detached d08e097

#1 feat(xtgen): generator for xcb-proto bindings

state
merged · d08e097 · fast-forward
branch
feat/xtgen → main
opened
bnema ·
updated
CommitSubjectAuthorDateSignatureStatus
d08e097feat(xtgen): decode replies as zero-copy views with list iteratorsbriceGPG Verified
017e663feat(xtgen): encode typed mask-ordered request value listsbriceGPG Verified
582be88feat(xtgen): encode request lists and derive exclusive lengthsbriceGPG Verified
8e6fe5cfeat(xtgen): encode fixed requests with captured wire goldensbriceGPG Verified
85a51ddfeat(xtgen): resolve wire types and emit typed layoutsbriceGPG Verified
2c9c8eafeat(xtgen): parse pinned XML into a strict source-located ASTbriceGPG Verified

Checks 4

102 files · +16959 -1
4/4
A bigreq/replies_fuzz_test.go +21 -0
A bigreq/replies_generated.go +21 -0
A bigreq/requests_generated.go +21 -0
A bigreq/sizes_test.go +11 -0
A bigreq/types_generated.go +2 -0
A buf.go +92 -0
A buf_test.go +69 -0
A cmd/xtgen/emit.go +252 -0
A cmd/xtgen/expr.go +43 -0
A cmd/xtgen/ir.go +39 -0
A cmd/xtgen/layout.go +103 -0
M cmd/xtgen/main.go +47 -1
A cmd/xtgen/naming.go +43 -0
A cmd/xtgen/parse.go +292 -0
A cmd/xtgen/parse_test.go +74 -0
A cmd/xtgen/replies.go +554 -0
A cmd/xtgen/replies_test.go +70 -0
A cmd/xtgen/requests.go +359 -0
A cmd/xtgen/resolve.go +356 -0
A cmd/xtgen/resolve_test.go +165 -0
A cmd/xtgen/templates/ext.tmpl +10 -0
A cmd/xtgen/templates/replies.tmpl +5 -0
A cmd/xtgen/templates/requests.tmpl +5 -0
A cmd/xtgen/templates/sizes.tmpl +7 -0
A cmd/xtgen/templates/types.tmpl +5 -0
A cmd/xtgen/values.go +136 -0
A cmd/xtgen/values_test.go +93 -0
A composite/replies_fuzz_test.go +39 -0
A composite/replies_generated.go +42 -0
A composite/requests_generated.go +176 -0
A composite/sizes_test.go +14 -0
A composite/types_generated.go +7 -0
A ext.go +27 -0
A ext_generated.go +19 -0
A ge/replies_fuzz_test.go +22 -0
A ge/replies_generated.go +24 -0
A ge/requests_generated.go +24 -0
A ge/sizes_test.go +11 -0
A ge/types_generated.go +2 -0
A generate.go +3 -0
A internal/xtest/README.md +40 -0
A internal/xtest/capture_test.go +405 -0
A internal/xtest/golden.go +22 -0
A lists_test.go +87 -0
A render/replies_fuzz_test.go +135 -0
A render/replies_generated.go +380 -0
A render/requests_generated.go +1276 -0
A render/sizes_test.go +68 -0
A render/types_generated.go +522 -0
A replies_test.go +304 -0
A requests_test.go +62 -0
@@ -0,0 +1,62 @@
1+package xturbo_test
2+
3+import (
4+ "bytes"
5+ "encoding/binary"
6+ "testing"
7+
8+ "bnema.dev/xturbo"
9+ "bnema.dev/xturbo/internal/xtest"
10+ "bnema.dev/xturbo/xfixes"
11+ "bnema.dev/xturbo/xproto"
12+)
13+
14+func TestRequestGoldens(t *testing.T) {
15+ for _, tc := range []struct {
16+ name string
17+ encode func(*xturbo.Buf, uint32) xturbo.Seq
18+ }{
19+ {"xproto/MapWindow", func(b *xturbo.Buf, id uint32) xturbo.Seq { return xproto.MapWindow(b, xproto.Window(id)) }},
20+ {"xproto/GetGeometry", func(b *xturbo.Buf, id uint32) xturbo.Seq { return xproto.GetGeometry(b, xproto.Drawable(id)) }},
21+ {"xfixes/QueryVersion", func(b *xturbo.Buf, _ uint32) xturbo.Seq { return xfixes.QueryVersion(b, 6, 0) }},
22+ } {
23+ t.Run(tc.name, func(t *testing.T) {
24+ want, err := xtest.LoadHex("testdata/golden/" + tc.name + ".req.hex")
25+ if err != nil {
26+ t.Fatal(err)
27+ }
28+ b := xturbo.NewBuf(0)
29+ var ext xturbo.ExtTable
30+ ext.Set(xturbo.ExtXFixes, want[0], 0, 0)
31+ b.Ext = &ext
32+ id := binary.LittleEndian.Uint32(want[4:])
33+ if tc.encode(b, id) != 1 || b.Err() != nil {
34+ t.Fatalf("seq/err: %v", b.Err())
35+ }
36+ if !bytes.Equal(b.Bytes(), want) {
37+ t.Fatalf("got %x want %x", b.Bytes(), want)
38+ }
39+ })
40+ }
41+}
42+func TestMissingExtension(t *testing.T) {
43+ for _, table := range []*xturbo.ExtTable{nil, {}} {
44+ b := xturbo.NewBuf(0)
45+ b.Ext = table
46+ if xfixes.QueryVersion(b, 6, 0) != 0 || b.Err() != xturbo.ErrExtMissing || b.Len() != 0 || xproto.MapWindow(b, 1) != 0 {
47+ t.Fatal("missing extension must fail sticky")
48+ }
49+ }
50+}
51+func TestAllocFixedRequests(t *testing.T) {
52+ b := xturbo.NewBuf(0)
53+ var ext xturbo.ExtTable
54+ ext.Set(xturbo.ExtXFixes, 138, 0, 0)
55+ b.Ext = &ext
56+ if n := testing.AllocsPerRun(1000, func() { b.Reset(); xproto.MapWindow(b, 1); xproto.GetGeometry(b, 1); xfixes.QueryVersion(b, 6, 0) }); n != 0 {
57+ t.Fatal(n)
58+ }
59+ if b.Err() != nil {
60+ t.Fatal(b.Err())
61+ }
62+}
@@ -0,0 +1,62 @@
1+package xturbo_test
2+
3+import (
4+ "bytes"
5+ "encoding/binary"
6+ "testing"
7+
8+ "bnema.dev/xturbo"
9+ "bnema.dev/xturbo/internal/xtest"
10+ "bnema.dev/xturbo/xfixes"
11+ "bnema.dev/xturbo/xproto"
12+)
13+
14+func TestRequestGoldens(t *testing.T) {
15+ for _, tc := range []struct {
16+ name string
17+ encode func(*xturbo.Buf, uint32) xturbo.Seq
18+ }{
19+ {"xproto/MapWindow", func(b *xturbo.Buf, id uint32) xturbo.Seq { return xproto.MapWindow(b, xproto.Window(id)) }},
20+ {"xproto/GetGeometry", func(b *xturbo.Buf, id uint32) xturbo.Seq { return xproto.GetGeometry(b, xproto.Drawable(id)) }},
21+ {"xfixes/QueryVersion", func(b *xturbo.Buf, _ uint32) xturbo.Seq { return xfixes.QueryVersion(b, 6, 0) }},
22+ } {
23+ t.Run(tc.name, func(t *testing.T) {
24+ want, err := xtest.LoadHex("testdata/golden/" + tc.name + ".req.hex")
25+ if err != nil {
26+ t.Fatal(err)
27+ }
28+ b := xturbo.NewBuf(0)
29+ var ext xturbo.ExtTable
30+ ext.Set(xturbo.ExtXFixes, want[0], 0, 0)
31+ b.Ext = &ext
32+ id := binary.LittleEndian.Uint32(want[4:])
33+ if tc.encode(b, id) != 1 || b.Err() != nil {
34+ t.Fatalf("seq/err: %v", b.Err())
35+ }
36+ if !bytes.Equal(b.Bytes(), want) {
37+ t.Fatalf("got %x want %x", b.Bytes(), want)
38+ }
39+ })
40+ }
41+}
42+func TestMissingExtension(t *testing.T) {
43+ for _, table := range []*xturbo.ExtTable{nil, {}} {
44+ b := xturbo.NewBuf(0)
45+ b.Ext = table
46+ if xfixes.QueryVersion(b, 6, 0) != 0 || b.Err() != xturbo.ErrExtMissing || b.Len() != 0 || xproto.MapWindow(b, 1) != 0 {
47+ t.Fatal("missing extension must fail sticky")
48+ }
49+ }
50+}
51+func TestAllocFixedRequests(t *testing.T) {
52+ b := xturbo.NewBuf(0)
53+ var ext xturbo.ExtTable
54+ ext.Set(xturbo.ExtXFixes, 138, 0, 0)
55+ b.Ext = &ext
56+ if n := testing.AllocsPerRun(1000, func() { b.Reset(); xproto.MapWindow(b, 1); xproto.GetGeometry(b, 1); xfixes.QueryVersion(b, 6, 0) }); n != 0 {
57+ t.Fatal(n)
58+ }
59+ if b.Err() != nil {
60+ t.Fatal(b.Err())
61+ }
62+}
A res/replies_fuzz_test.go +146 -0
@@ -0,0 +1,146 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package res
3+
4+import "testing"
5+import "bnema.dev/xturbo/internal/xtest"
6+
7+func FuzzParseQueryVersionReply(f *testing.F) {
8+ f.Add(make([]byte, 32))
9+ f.Fuzz(func(t *testing.T, raw []byte) {
10+ r, ok := ParseQueryVersionReply(raw)
11+ if !ok {
12+ if len(raw) >= 32 {
13+ t.Fatal("rejected a complete fixed-size reply")
14+ }
15+ return
16+ }
17+ if len(r.Raw()) != len(raw) {
18+ t.Fatal("Raw must return the parsed bytes")
19+ }
20+ _ = r.ServerMajor()
21+ _ = r.ServerMinor()
22+ })
23+}
24+
25+func FuzzParseQueryClientsReply(f *testing.F) {
26+ f.Add(make([]byte, 32))
27+ f.Fuzz(func(t *testing.T, raw []byte) {
28+ r, ok := ParseQueryClientsReply(raw)
29+ if !ok {
30+ return
31+ }
32+ if len(r.Raw()) != len(raw) {
33+ t.Fatal("Raw must return the parsed bytes")
34+ }
35+ _ = r.NumClients()
36+ {
37+ l0 := r.Clients()
38+ for i := 0; i < l0.Len(); i++ {
39+ _ = l0.At(i)
40+ }
41+ }
42+ })
43+}
44+
45+func FuzzParseQueryClientResourcesReply(f *testing.F) {
46+ f.Add(make([]byte, 32))
47+ f.Fuzz(func(t *testing.T, raw []byte) {
48+ r, ok := ParseQueryClientResourcesReply(raw)
49+ if !ok {
50+ return
51+ }
52+ if len(r.Raw()) != len(raw) {
53+ t.Fatal("Raw must return the parsed bytes")
54+ }
55+ _ = r.NumTypes()
56+ {
57+ l0 := r.Types()
58+ for i := 0; i < l0.Len(); i++ {
59+ _ = l0.At(i)
60+ }
61+ }
62+ })
63+}
64+
65+func FuzzParseQueryClientPixmapBytesReply(f *testing.F) {
66+ f.Add(make([]byte, 32))
67+ f.Fuzz(func(t *testing.T, raw []byte) {
68+ r, ok := ParseQueryClientPixmapBytesReply(raw)
69+ if !ok {
70+ if len(raw) >= 32 {
71+ t.Fatal("rejected a complete fixed-size reply")
72+ }
73+ return
74+ }
75+ if len(r.Raw()) != len(raw) {
76+ t.Fatal("Raw must return the parsed bytes")
77+ }
78+ _ = r.Bytes()
79+ _ = r.BytesOverflow()
80+ })
81+}
82+
83+func FuzzParseQueryClientIdsReply(f *testing.F) {
84+ f.Add(make([]byte, 32))
85+ if raw, err := xtest.LoadHex("../testdata/golden/res/QueryClientIds.reply.hex"); err != nil {
86+ f.Fatal(err)
87+ } else {
88+ f.Add(raw)
89+ }
90+ f.Fuzz(func(t *testing.T, raw []byte) {
91+ r, ok := ParseQueryClientIdsReply(raw)
92+ if !ok {
93+ return
94+ }
95+ if len(r.Raw()) != len(raw) {
96+ t.Fatal("Raw must return the parsed bytes")
97+ }
98+ _ = r.NumIds()
99+ {
100+ it0 := r.Ids()
101+ for it0.Next() {
102+ _ = it0.Value().Spec()
103+ _ = it0.Value().Length()
104+ {
105+ l1 := it0.Value().Value()
106+ for i := 0; i < l1.Len(); i++ {
107+ _ = l1.At(i)
108+ }
109+ }
110+ }
111+ if it0.Err() {
112+ t.Fatal("iterator error after successful Parse")
113+ }
114+ }
115+ })
116+}
117+
118+func FuzzParseQueryResourceBytesReply(f *testing.F) {
119+ f.Add(make([]byte, 32))
120+ f.Fuzz(func(t *testing.T, raw []byte) {
121+ r, ok := ParseQueryResourceBytesReply(raw)
122+ if !ok {
123+ return
124+ }
125+ if len(r.Raw()) != len(raw) {
126+ t.Fatal("Raw must return the parsed bytes")
127+ }
128+ _ = r.NumSizes()
129+ {
130+ it0 := r.Sizes()
131+ for it0.Next() {
132+ _ = it0.Value().Size_()
133+ _ = it0.Value().NumCrossReferences()
134+ {
135+ l1 := it0.Value().CrossReferences()
136+ for i := 0; i < l1.Len(); i++ {
137+ _ = l1.At(i)
138+ }
139+ }
140+ }
141+ if it0.Err() {
142+ t.Fatal("iterator error after successful Parse")
143+ }
144+ }
145+ })
146+}
@@ -0,0 +1,146 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package res
3+
4+import "testing"
5+import "bnema.dev/xturbo/internal/xtest"
6+
7+func FuzzParseQueryVersionReply(f *testing.F) {
8+ f.Add(make([]byte, 32))
9+ f.Fuzz(func(t *testing.T, raw []byte) {
10+ r, ok := ParseQueryVersionReply(raw)
11+ if !ok {
12+ if len(raw) >= 32 {
13+ t.Fatal("rejected a complete fixed-size reply")
14+ }
15+ return
16+ }
17+ if len(r.Raw()) != len(raw) {
18+ t.Fatal("Raw must return the parsed bytes")
19+ }
20+ _ = r.ServerMajor()
21+ _ = r.ServerMinor()
22+ })
23+}
24+
25+func FuzzParseQueryClientsReply(f *testing.F) {
26+ f.Add(make([]byte, 32))
27+ f.Fuzz(func(t *testing.T, raw []byte) {
28+ r, ok := ParseQueryClientsReply(raw)
29+ if !ok {
30+ return
31+ }
32+ if len(r.Raw()) != len(raw) {
33+ t.Fatal("Raw must return the parsed bytes")
34+ }
35+ _ = r.NumClients()
36+ {
37+ l0 := r.Clients()
38+ for i := 0; i < l0.Len(); i++ {
39+ _ = l0.At(i)
40+ }
41+ }
42+ })
43+}
44+
45+func FuzzParseQueryClientResourcesReply(f *testing.F) {
46+ f.Add(make([]byte, 32))
47+ f.Fuzz(func(t *testing.T, raw []byte) {
48+ r, ok := ParseQueryClientResourcesReply(raw)
49+ if !ok {
50+ return
51+ }
52+ if len(r.Raw()) != len(raw) {
53+ t.Fatal("Raw must return the parsed bytes")
54+ }
55+ _ = r.NumTypes()
56+ {
57+ l0 := r.Types()
58+ for i := 0; i < l0.Len(); i++ {
59+ _ = l0.At(i)
60+ }
61+ }
62+ })
63+}
64+
65+func FuzzParseQueryClientPixmapBytesReply(f *testing.F) {
66+ f.Add(make([]byte, 32))
67+ f.Fuzz(func(t *testing.T, raw []byte) {
68+ r, ok := ParseQueryClientPixmapBytesReply(raw)
69+ if !ok {
70+ if len(raw) >= 32 {
71+ t.Fatal("rejected a complete fixed-size reply")
72+ }
73+ return
74+ }
75+ if len(r.Raw()) != len(raw) {
76+ t.Fatal("Raw must return the parsed bytes")
77+ }
78+ _ = r.Bytes()
79+ _ = r.BytesOverflow()
80+ })
81+}
82+
83+func FuzzParseQueryClientIdsReply(f *testing.F) {
84+ f.Add(make([]byte, 32))
85+ if raw, err := xtest.LoadHex("../testdata/golden/res/QueryClientIds.reply.hex"); err != nil {
86+ f.Fatal(err)
87+ } else {
88+ f.Add(raw)
89+ }
90+ f.Fuzz(func(t *testing.T, raw []byte) {
91+ r, ok := ParseQueryClientIdsReply(raw)
92+ if !ok {
93+ return
94+ }
95+ if len(r.Raw()) != len(raw) {
96+ t.Fatal("Raw must return the parsed bytes")
97+ }
98+ _ = r.NumIds()
99+ {
100+ it0 := r.Ids()
101+ for it0.Next() {
102+ _ = it0.Value().Spec()
103+ _ = it0.Value().Length()
104+ {
105+ l1 := it0.Value().Value()
106+ for i := 0; i < l1.Len(); i++ {
107+ _ = l1.At(i)
108+ }
109+ }
110+ }
111+ if it0.Err() {
112+ t.Fatal("iterator error after successful Parse")
113+ }
114+ }
115+ })
116+}
117+
118+func FuzzParseQueryResourceBytesReply(f *testing.F) {
119+ f.Add(make([]byte, 32))
120+ f.Fuzz(func(t *testing.T, raw []byte) {
121+ r, ok := ParseQueryResourceBytesReply(raw)
122+ if !ok {
123+ return
124+ }
125+ if len(r.Raw()) != len(raw) {
126+ t.Fatal("Raw must return the parsed bytes")
127+ }
128+ _ = r.NumSizes()
129+ {
130+ it0 := r.Sizes()
131+ for it0.Next() {
132+ _ = it0.Value().Size_()
133+ _ = it0.Value().NumCrossReferences()
134+ {
135+ l1 := it0.Value().CrossReferences()
136+ for i := 0; i < l1.Len(); i++ {
137+ _ = l1.At(i)
138+ }
139+ }
140+ }
141+ if it0.Err() {
142+ t.Fatal("iterator error after successful Parse")
143+ }
144+ }
145+ })
146+}
A res/replies_generated.go +348 -0
@@ -0,0 +1,348 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package res
3+
4+import "encoding/binary"
5+
6+// QueryVersionReply is a zero-copy view over a QueryVersion reply; offsets count from reply byte 0.
7+// It borrows the reply bytes: valid only until the Handler callback returns, because the read ring is reused. Copy what you keep.
8+type QueryVersionReply struct{ raw []byte }
9+
10+// ParseQueryVersionReply validates raw (the whole reply, 32+4*length bytes) once; getters do not re-check.
11+func ParseQueryVersionReply(raw []byte) (QueryVersionReply, bool) {
12+ if len(raw) < 32 {
13+ return QueryVersionReply{}, false
14+ }
15+ r := QueryVersionReply{raw: raw}
16+ return r, true
17+}
18+func (r QueryVersionReply) Raw() []byte { return r.raw }
19+func (r QueryVersionReply) ServerMajor() uint16 { return uint16(binary.LittleEndian.Uint16(r.raw[8:])) }
20+func (r QueryVersionReply) ServerMinor() uint16 {
21+ return uint16(binary.LittleEndian.Uint16(r.raw[10:]))
22+}
23+
24+// QueryClientsReply is a zero-copy view over a QueryClients reply; offsets count from reply byte 0.
25+// It borrows the reply bytes: valid only until the Handler callback returns, because the read ring is reused. Copy what you keep.
26+type QueryClientsReply struct{ raw []byte }
27+
28+// ParseQueryClientsReply validates raw (the whole reply, 32+4*length bytes) once; getters do not re-check.
29+func ParseQueryClientsReply(raw []byte) (QueryClientsReply, bool) {
30+ if len(raw) < 32 {
31+ return QueryClientsReply{}, false
32+ }
33+ r := QueryClientsReply{raw: raw}
34+ off := 32
35+ {
36+ n := int(r.NumClients())
37+ if n < 0 || n > len(r.raw) {
38+ return QueryClientsReply{}, false
39+ }
40+ off += n * 8
41+ }
42+ if off > len(r.raw) {
43+ return QueryClientsReply{}, false
44+ }
45+ if off > len(r.raw) {
46+ return QueryClientsReply{}, false
47+ }
48+ return r, true
49+}
50+func (r QueryClientsReply) Raw() []byte { return r.raw }
51+func (r QueryClientsReply) NumClients() uint32 { return uint32(binary.LittleEndian.Uint32(r.raw[8:])) }
52+func (r QueryClientsReply) Clients() ClientList {
53+ off := 32
54+ end := off + (int(r.NumClients()))*8
55+ return ClientList{b: r.raw[off:end:end]}
56+}
57+
58+// QueryClientResourcesReply is a zero-copy view over a QueryClientResources reply; offsets count from reply byte 0.
59+// It borrows the reply bytes: valid only until the Handler callback returns, because the read ring is reused. Copy what you keep.
60+type QueryClientResourcesReply struct{ raw []byte }
61+
62+// ParseQueryClientResourcesReply validates raw (the whole reply, 32+4*length bytes) once; getters do not re-check.
63+func ParseQueryClientResourcesReply(raw []byte) (QueryClientResourcesReply, bool) {
64+ if len(raw) < 32 {
65+ return QueryClientResourcesReply{}, false
66+ }
67+ r := QueryClientResourcesReply{raw: raw}
68+ off := 32
69+ {
70+ n := int(r.NumTypes())
71+ if n < 0 || n > len(r.raw) {
72+ return QueryClientResourcesReply{}, false
73+ }
74+ off += n * 8
75+ }
76+ if off > len(r.raw) {
77+ return QueryClientResourcesReply{}, false
78+ }
79+ if off > len(r.raw) {
80+ return QueryClientResourcesReply{}, false
81+ }
82+ return r, true
83+}
84+func (r QueryClientResourcesReply) Raw() []byte { return r.raw }
85+func (r QueryClientResourcesReply) NumTypes() uint32 {
86+ return uint32(binary.LittleEndian.Uint32(r.raw[8:]))
87+}
88+func (r QueryClientResourcesReply) Types() TypeList {
89+ off := 32
90+ end := off + (int(r.NumTypes()))*8
91+ return TypeList{b: r.raw[off:end:end]}
92+}
93+
94+// QueryClientPixmapBytesReply is a zero-copy view over a QueryClientPixmapBytes reply; offsets count from reply byte 0.
95+// It borrows the reply bytes: valid only until the Handler callback returns, because the read ring is reused. Copy what you keep.
96+type QueryClientPixmapBytesReply struct{ raw []byte }
97+
98+// ParseQueryClientPixmapBytesReply validates raw (the whole reply, 32+4*length bytes) once; getters do not re-check.
99+func ParseQueryClientPixmapBytesReply(raw []byte) (QueryClientPixmapBytesReply, bool) {
100+ if len(raw) < 32 {
101+ return QueryClientPixmapBytesReply{}, false
102+ }
103+ r := QueryClientPixmapBytesReply{raw: raw}
104+ return r, true
105+}
106+func (r QueryClientPixmapBytesReply) Raw() []byte { return r.raw }
107+func (r QueryClientPixmapBytesReply) Bytes() uint32 {
108+ return uint32(binary.LittleEndian.Uint32(r.raw[8:]))
109+}
110+func (r QueryClientPixmapBytesReply) BytesOverflow() uint32 {
111+ return uint32(binary.LittleEndian.Uint32(r.raw[12:]))
112+}
113+
114+// QueryClientIdsReply is a zero-copy view over a QueryClientIds reply; offsets count from reply byte 0.
115+// It borrows the reply bytes: valid only until the Handler callback returns, because the read ring is reused. Copy what you keep.
116+type QueryClientIdsReply struct{ raw []byte }
117+
118+// ParseQueryClientIdsReply validates raw (the whole reply, 32+4*length bytes) once; getters do not re-check.
119+func ParseQueryClientIdsReply(raw []byte) (QueryClientIdsReply, bool) {
120+ if len(raw) < 32 {
121+ return QueryClientIdsReply{}, false
122+ }
123+ r := QueryClientIdsReply{raw: raw}
124+ off := 32
125+ {
126+ n := int(r.NumIds())
127+ if off > len(r.raw) || n < 0 || n > len(r.raw) {
128+ return QueryClientIdsReply{}, false
129+ }
130+ it := NewClientIdValueIter(r.raw[off:], n)
131+ for it.Next() {
132+ off += it.Value().Size()
133+ }
134+ if it.Err() {
135+ return QueryClientIdsReply{}, false
136+ }
137+ }
138+ if off > len(r.raw) {
139+ return QueryClientIdsReply{}, false
140+ }
141+ return r, true
142+}
143+func (r QueryClientIdsReply) Raw() []byte { return r.raw }
144+func (r QueryClientIdsReply) NumIds() uint32 { return uint32(binary.LittleEndian.Uint32(r.raw[8:])) }
145+func (r QueryClientIdsReply) Ids() ClientIdValueIter {
146+ off := 32
147+ return NewClientIdValueIter(r.raw[off:], int(r.NumIds()))
148+}
149+
150+// QueryResourceBytesReply is a zero-copy view over a QueryResourceBytes reply; offsets count from reply byte 0.
151+// It borrows the reply bytes: valid only until the Handler callback returns, because the read ring is reused. Copy what you keep.
152+type QueryResourceBytesReply struct{ raw []byte }
153+
154+// ParseQueryResourceBytesReply validates raw (the whole reply, 32+4*length bytes) once; getters do not re-check.
155+func ParseQueryResourceBytesReply(raw []byte) (QueryResourceBytesReply, bool) {
156+ if len(raw) < 32 {
157+ return QueryResourceBytesReply{}, false
158+ }
159+ r := QueryResourceBytesReply{raw: raw}
160+ off := 32
161+ {
162+ n := int(r.NumSizes())
163+ if off > len(r.raw) || n < 0 || n > len(r.raw) {
164+ return QueryResourceBytesReply{}, false
165+ }
166+ it := NewResourceSizeValueIter(r.raw[off:], n)
167+ for it.Next() {
168+ off += it.Value().Size()
169+ }
170+ if it.Err() {
171+ return QueryResourceBytesReply{}, false
172+ }
173+ }
174+ if off > len(r.raw) {
175+ return QueryResourceBytesReply{}, false
176+ }
177+ return r, true
178+}
179+func (r QueryResourceBytesReply) Raw() []byte { return r.raw }
180+func (r QueryResourceBytesReply) NumSizes() uint32 {
181+ return uint32(binary.LittleEndian.Uint32(r.raw[8:]))
182+}
183+func (r QueryResourceBytesReply) Sizes() ResourceSizeValueIter {
184+ off := 32
185+ return NewResourceSizeValueIter(r.raw[off:], int(r.NumSizes()))
186+}
187+
188+// ClientIdValueView is a zero-copy view over one wire-encoded ClientIdValue, yielded by ClientIdValueIter.
189+// It shares the lifetime of the bytes it was taken from (for replies: until the Handler callback returns). Copy what you keep.
190+type ClientIdValueView struct{ raw []byte }
191+
192+func (v ClientIdValueView) Raw() []byte { return v.raw }
193+
194+// Size is the element's wire size, including trailing alignment.
195+func (v ClientIdValueView) Size() int { return len(v.raw) }
196+func sizeClientIdValue(p []byte) int {
197+ if len(p) < 12 {
198+ return -1
199+ }
200+ v := ClientIdValueView{raw: p}
201+ _ = v
202+ off := 12
203+ {
204+ n := (int(v.Length()) / 4)
205+ if n < 0 || n > len(v.raw) {
206+ return -1
207+ }
208+ off += n * 4
209+ }
210+ if off > len(v.raw) {
211+ return -1
212+ }
213+ if off > len(v.raw) {
214+ return -1
215+ }
216+ return off
217+}
218+func (v ClientIdValueView) Spec() ClientIdSpec { return GetClientIdSpec(v.raw[0:]) }
219+func (v ClientIdValueView) Length() uint32 { return uint32(binary.LittleEndian.Uint32(v.raw[8:])) }
220+func (v ClientIdValueView) Value() Uint32List {
221+ off := 12
222+ end := off + (int(v.Length())/4)*4
223+ return Uint32List{b: v.raw[off:end:end]}
224+}
225+
226+// ClientIdValueIter walks n consecutive ClientIdValue elements; Err reports a malformed length.
227+// It shares the lifetime of the bytes it walks.
228+type ClientIdValueIter struct {
229+ b []byte
230+ n int
231+ v ClientIdValueView
232+ err bool
233+}
234+
235+// NewClientIdValueIter iterates n elements encoded at the start of b.
236+func NewClientIdValueIter(b []byte, n int) ClientIdValueIter { return ClientIdValueIter{b: b, n: n} }
237+func (it *ClientIdValueIter) Next() bool {
238+ if it.n <= 0 || it.err {
239+ return false
240+ }
241+ s := sizeClientIdValue(it.b)
242+ if s < 0 {
243+ it.err = true
244+ it.n = 0
245+ return false
246+ }
247+ it.v = ClientIdValueView{raw: it.b[:s:s]}
248+ it.b = it.b[s:]
249+ it.n--
250+ return true
251+}
252+func (it *ClientIdValueIter) Value() ClientIdValueView { return it.v }
253+func (it *ClientIdValueIter) Err() bool { return it.err }
254+
255+// ResourceSizeValueView is a zero-copy view over one wire-encoded ResourceSizeValue, yielded by ResourceSizeValueIter.
256+// It shares the lifetime of the bytes it was taken from (for replies: until the Handler callback returns). Copy what you keep.
257+type ResourceSizeValueView struct{ raw []byte }
258+
259+func (v ResourceSizeValueView) Raw() []byte { return v.raw }
260+
261+// Size is the element's wire size, including trailing alignment.
262+func (v ResourceSizeValueView) Size() int { return len(v.raw) }
263+func sizeResourceSizeValue(p []byte) int {
264+ if len(p) < 24 {
265+ return -1
266+ }
267+ v := ResourceSizeValueView{raw: p}
268+ _ = v
269+ off := 24
270+ {
271+ n := int(v.NumCrossReferences())
272+ if n < 0 || n > len(v.raw) {
273+ return -1
274+ }
275+ off += n * 20
276+ }
277+ if off > len(v.raw) {
278+ return -1
279+ }
280+ if off > len(v.raw) {
281+ return -1
282+ }
283+ return off
284+}
285+func (v ResourceSizeValueView) Size_() ResourceSizeSpec { return GetResourceSizeSpec(v.raw[0:]) }
286+func (v ResourceSizeValueView) NumCrossReferences() uint32 {
287+ return uint32(binary.LittleEndian.Uint32(v.raw[20:]))
288+}
289+func (v ResourceSizeValueView) CrossReferences() ResourceSizeSpecList {
290+ off := 24
291+ end := off + (int(v.NumCrossReferences()))*20
292+ return ResourceSizeSpecList{b: v.raw[off:end:end]}
293+}
294+
295+// ResourceSizeValueIter walks n consecutive ResourceSizeValue elements; Err reports a malformed length.
296+// It shares the lifetime of the bytes it walks.
297+type ResourceSizeValueIter struct {
298+ b []byte
299+ n int
300+ v ResourceSizeValueView
301+ err bool
302+}
303+
304+// NewResourceSizeValueIter iterates n elements encoded at the start of b.
305+func NewResourceSizeValueIter(b []byte, n int) ResourceSizeValueIter {
306+ return ResourceSizeValueIter{b: b, n: n}
307+}
308+func (it *ResourceSizeValueIter) Next() bool {
309+ if it.n <= 0 || it.err {
310+ return false
311+ }
312+ s := sizeResourceSizeValue(it.b)
313+ if s < 0 {
314+ it.err = true
315+ it.n = 0
316+ return false
317+ }
318+ it.v = ResourceSizeValueView{raw: it.b[:s:s]}
319+ it.b = it.b[s:]
320+ it.n--
321+ return true
322+}
323+func (it *ResourceSizeValueIter) Value() ResourceSizeValueView { return it.v }
324+func (it *ResourceSizeValueIter) Err() bool { return it.err }
325+
326+// ClientList is a borrowed view over a wire list of Client. It shares the lifetime of the bytes it was taken from; copy what you keep.
327+type ClientList struct{ b []byte }
328+
329+func (l ClientList) Len() int { return len(l.b) / 8 }
330+func (l ClientList) At(i int) Client { return GetClient(l.b[i*8:]) }
331+
332+// ResourceSizeSpecList is a borrowed view over a wire list of ResourceSizeSpec. It shares the lifetime of the bytes it was taken from; copy what you keep.
333+type ResourceSizeSpecList struct{ b []byte }
334+
335+func (l ResourceSizeSpecList) Len() int { return len(l.b) / 20 }
336+func (l ResourceSizeSpecList) At(i int) ResourceSizeSpec { return GetResourceSizeSpec(l.b[i*20:]) }
337+
338+// TypeList is a borrowed view over a wire list of Type. It shares the lifetime of the bytes it was taken from; copy what you keep.
339+type TypeList struct{ b []byte }
340+
341+func (l TypeList) Len() int { return len(l.b) / 8 }
342+func (l TypeList) At(i int) Type { return GetType(l.b[i*8:]) }
343+
344+// Uint32List is a borrowed view over a wire list of uint32. It shares the lifetime of the bytes it was taken from; copy what you keep.
345+type Uint32List struct{ b []byte }
346+
347+func (l Uint32List) Len() int { return len(l.b) / 4 }
348+func (l Uint32List) At(i int) uint32 { return uint32(binary.LittleEndian.Uint32(l.b[i*4:])) }
@@ -0,0 +1,348 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package res
3+
4+import "encoding/binary"
5+
6+// QueryVersionReply is a zero-copy view over a QueryVersion reply; offsets count from reply byte 0.
7+// It borrows the reply bytes: valid only until the Handler callback returns, because the read ring is reused. Copy what you keep.
8+type QueryVersionReply struct{ raw []byte }
9+
10+// ParseQueryVersionReply validates raw (the whole reply, 32+4*length bytes) once; getters do not re-check.
11+func ParseQueryVersionReply(raw []byte) (QueryVersionReply, bool) {
12+ if len(raw) < 32 {
13+ return QueryVersionReply{}, false
14+ }
15+ r := QueryVersionReply{raw: raw}
16+ return r, true
17+}
18+func (r QueryVersionReply) Raw() []byte { return r.raw }
19+func (r QueryVersionReply) ServerMajor() uint16 { return uint16(binary.LittleEndian.Uint16(r.raw[8:])) }
20+func (r QueryVersionReply) ServerMinor() uint16 {
21+ return uint16(binary.LittleEndian.Uint16(r.raw[10:]))
22+}
23+
24+// QueryClientsReply is a zero-copy view over a QueryClients reply; offsets count from reply byte 0.
25+// It borrows the reply bytes: valid only until the Handler callback returns, because the read ring is reused. Copy what you keep.
26+type QueryClientsReply struct{ raw []byte }
27+
28+// ParseQueryClientsReply validates raw (the whole reply, 32+4*length bytes) once; getters do not re-check.
29+func ParseQueryClientsReply(raw []byte) (QueryClientsReply, bool) {
30+ if len(raw) < 32 {
31+ return QueryClientsReply{}, false
32+ }
33+ r := QueryClientsReply{raw: raw}
34+ off := 32
35+ {
36+ n := int(r.NumClients())
37+ if n < 0 || n > len(r.raw) {
38+ return QueryClientsReply{}, false
39+ }
40+ off += n * 8
41+ }
42+ if off > len(r.raw) {
43+ return QueryClientsReply{}, false
44+ }
45+ if off > len(r.raw) {
46+ return QueryClientsReply{}, false
47+ }
48+ return r, true
49+}
50+func (r QueryClientsReply) Raw() []byte { return r.raw }
51+func (r QueryClientsReply) NumClients() uint32 { return uint32(binary.LittleEndian.Uint32(r.raw[8:])) }
52+func (r QueryClientsReply) Clients() ClientList {
53+ off := 32
54+ end := off + (int(r.NumClients()))*8
55+ return ClientList{b: r.raw[off:end:end]}
56+}
57+
58+// QueryClientResourcesReply is a zero-copy view over a QueryClientResources reply; offsets count from reply byte 0.
59+// It borrows the reply bytes: valid only until the Handler callback returns, because the read ring is reused. Copy what you keep.
60+type QueryClientResourcesReply struct{ raw []byte }
61+
62+// ParseQueryClientResourcesReply validates raw (the whole reply, 32+4*length bytes) once; getters do not re-check.
63+func ParseQueryClientResourcesReply(raw []byte) (QueryClientResourcesReply, bool) {
64+ if len(raw) < 32 {
65+ return QueryClientResourcesReply{}, false
66+ }
67+ r := QueryClientResourcesReply{raw: raw}
68+ off := 32
69+ {
70+ n := int(r.NumTypes())
71+ if n < 0 || n > len(r.raw) {
72+ return QueryClientResourcesReply{}, false
73+ }
74+ off += n * 8
75+ }
76+ if off > len(r.raw) {
77+ return QueryClientResourcesReply{}, false
78+ }
79+ if off > len(r.raw) {
80+ return QueryClientResourcesReply{}, false
81+ }
82+ return r, true
83+}
84+func (r QueryClientResourcesReply) Raw() []byte { return r.raw }
85+func (r QueryClientResourcesReply) NumTypes() uint32 {
86+ return uint32(binary.LittleEndian.Uint32(r.raw[8:]))
87+}
88+func (r QueryClientResourcesReply) Types() TypeList {
89+ off := 32
90+ end := off + (int(r.NumTypes()))*8
91+ return TypeList{b: r.raw[off:end:end]}
92+}
93+
94+// QueryClientPixmapBytesReply is a zero-copy view over a QueryClientPixmapBytes reply; offsets count from reply byte 0.
95+// It borrows the reply bytes: valid only until the Handler callback returns, because the read ring is reused. Copy what you keep.
96+type QueryClientPixmapBytesReply struct{ raw []byte }
97+
98+// ParseQueryClientPixmapBytesReply validates raw (the whole reply, 32+4*length bytes) once; getters do not re-check.
99+func ParseQueryClientPixmapBytesReply(raw []byte) (QueryClientPixmapBytesReply, bool) {
100+ if len(raw) < 32 {
101+ return QueryClientPixmapBytesReply{}, false
102+ }
103+ r := QueryClientPixmapBytesReply{raw: raw}
104+ return r, true
105+}
106+func (r QueryClientPixmapBytesReply) Raw() []byte { return r.raw }
107+func (r QueryClientPixmapBytesReply) Bytes() uint32 {
108+ return uint32(binary.LittleEndian.Uint32(r.raw[8:]))
109+}
110+func (r QueryClientPixmapBytesReply) BytesOverflow() uint32 {
111+ return uint32(binary.LittleEndian.Uint32(r.raw[12:]))
112+}
113+
114+// QueryClientIdsReply is a zero-copy view over a QueryClientIds reply; offsets count from reply byte 0.
115+// It borrows the reply bytes: valid only until the Handler callback returns, because the read ring is reused. Copy what you keep.
116+type QueryClientIdsReply struct{ raw []byte }
117+
118+// ParseQueryClientIdsReply validates raw (the whole reply, 32+4*length bytes) once; getters do not re-check.
119+func ParseQueryClientIdsReply(raw []byte) (QueryClientIdsReply, bool) {
120+ if len(raw) < 32 {
121+ return QueryClientIdsReply{}, false
122+ }
123+ r := QueryClientIdsReply{raw: raw}
124+ off := 32
125+ {
126+ n := int(r.NumIds())
127+ if off > len(r.raw) || n < 0 || n > len(r.raw) {
128+ return QueryClientIdsReply{}, false
129+ }
130+ it := NewClientIdValueIter(r.raw[off:], n)
131+ for it.Next() {
132+ off += it.Value().Size()
133+ }
134+ if it.Err() {
135+ return QueryClientIdsReply{}, false
136+ }
137+ }
138+ if off > len(r.raw) {
139+ return QueryClientIdsReply{}, false
140+ }
141+ return r, true
142+}
143+func (r QueryClientIdsReply) Raw() []byte { return r.raw }
144+func (r QueryClientIdsReply) NumIds() uint32 { return uint32(binary.LittleEndian.Uint32(r.raw[8:])) }
145+func (r QueryClientIdsReply) Ids() ClientIdValueIter {
146+ off := 32
147+ return NewClientIdValueIter(r.raw[off:], int(r.NumIds()))
148+}
149+
150+// QueryResourceBytesReply is a zero-copy view over a QueryResourceBytes reply; offsets count from reply byte 0.
151+// It borrows the reply bytes: valid only until the Handler callback returns, because the read ring is reused. Copy what you keep.
152+type QueryResourceBytesReply struct{ raw []byte }
153+
154+// ParseQueryResourceBytesReply validates raw (the whole reply, 32+4*length bytes) once; getters do not re-check.
155+func ParseQueryResourceBytesReply(raw []byte) (QueryResourceBytesReply, bool) {
156+ if len(raw) < 32 {
157+ return QueryResourceBytesReply{}, false
158+ }
159+ r := QueryResourceBytesReply{raw: raw}
160+ off := 32
161+ {
162+ n := int(r.NumSizes())
163+ if off > len(r.raw) || n < 0 || n > len(r.raw) {
164+ return QueryResourceBytesReply{}, false
165+ }
166+ it := NewResourceSizeValueIter(r.raw[off:], n)
167+ for it.Next() {
168+ off += it.Value().Size()
169+ }
170+ if it.Err() {
171+ return QueryResourceBytesReply{}, false
172+ }
173+ }
174+ if off > len(r.raw) {
175+ return QueryResourceBytesReply{}, false
176+ }
177+ return r, true
178+}
179+func (r QueryResourceBytesReply) Raw() []byte { return r.raw }
180+func (r QueryResourceBytesReply) NumSizes() uint32 {
181+ return uint32(binary.LittleEndian.Uint32(r.raw[8:]))
182+}
183+func (r QueryResourceBytesReply) Sizes() ResourceSizeValueIter {
184+ off := 32
185+ return NewResourceSizeValueIter(r.raw[off:], int(r.NumSizes()))
186+}
187+
188+// ClientIdValueView is a zero-copy view over one wire-encoded ClientIdValue, yielded by ClientIdValueIter.
189+// It shares the lifetime of the bytes it was taken from (for replies: until the Handler callback returns). Copy what you keep.
190+type ClientIdValueView struct{ raw []byte }
191+
192+func (v ClientIdValueView) Raw() []byte { return v.raw }
193+
194+// Size is the element's wire size, including trailing alignment.
195+func (v ClientIdValueView) Size() int { return len(v.raw) }
196+func sizeClientIdValue(p []byte) int {
197+ if len(p) < 12 {
198+ return -1
199+ }
200+ v := ClientIdValueView{raw: p}
201+ _ = v
202+ off := 12
203+ {
204+ n := (int(v.Length()) / 4)
205+ if n < 0 || n > len(v.raw) {
206+ return -1
207+ }
208+ off += n * 4
209+ }
210+ if off > len(v.raw) {
211+ return -1
212+ }
213+ if off > len(v.raw) {
214+ return -1
215+ }
216+ return off
217+}
218+func (v ClientIdValueView) Spec() ClientIdSpec { return GetClientIdSpec(v.raw[0:]) }
219+func (v ClientIdValueView) Length() uint32 { return uint32(binary.LittleEndian.Uint32(v.raw[8:])) }
220+func (v ClientIdValueView) Value() Uint32List {
221+ off := 12
222+ end := off + (int(v.Length())/4)*4
223+ return Uint32List{b: v.raw[off:end:end]}
224+}
225+
226+// ClientIdValueIter walks n consecutive ClientIdValue elements; Err reports a malformed length.
227+// It shares the lifetime of the bytes it walks.
228+type ClientIdValueIter struct {
229+ b []byte
230+ n int
231+ v ClientIdValueView
232+ err bool
233+}
234+
235+// NewClientIdValueIter iterates n elements encoded at the start of b.
236+func NewClientIdValueIter(b []byte, n int) ClientIdValueIter { return ClientIdValueIter{b: b, n: n} }
237+func (it *ClientIdValueIter) Next() bool {
238+ if it.n <= 0 || it.err {
239+ return false
240+ }
241+ s := sizeClientIdValue(it.b)
242+ if s < 0 {
243+ it.err = true
244+ it.n = 0
245+ return false
246+ }
247+ it.v = ClientIdValueView{raw: it.b[:s:s]}
248+ it.b = it.b[s:]
249+ it.n--
250+ return true
251+}
252+func (it *ClientIdValueIter) Value() ClientIdValueView { return it.v }
253+func (it *ClientIdValueIter) Err() bool { return it.err }
254+
255+// ResourceSizeValueView is a zero-copy view over one wire-encoded ResourceSizeValue, yielded by ResourceSizeValueIter.
256+// It shares the lifetime of the bytes it was taken from (for replies: until the Handler callback returns). Copy what you keep.
257+type ResourceSizeValueView struct{ raw []byte }
258+
259+func (v ResourceSizeValueView) Raw() []byte { return v.raw }
260+
261+// Size is the element's wire size, including trailing alignment.
262+func (v ResourceSizeValueView) Size() int { return len(v.raw) }
263+func sizeResourceSizeValue(p []byte) int {
264+ if len(p) < 24 {
265+ return -1
266+ }
267+ v := ResourceSizeValueView{raw: p}
268+ _ = v
269+ off := 24
270+ {
271+ n := int(v.NumCrossReferences())
272+ if n < 0 || n > len(v.raw) {
273+ return -1
274+ }
275+ off += n * 20
276+ }
277+ if off > len(v.raw) {
278+ return -1
279+ }
280+ if off > len(v.raw) {
281+ return -1
282+ }
283+ return off
284+}
285+func (v ResourceSizeValueView) Size_() ResourceSizeSpec { return GetResourceSizeSpec(v.raw[0:]) }
286+func (v ResourceSizeValueView) NumCrossReferences() uint32 {
287+ return uint32(binary.LittleEndian.Uint32(v.raw[20:]))
288+}
289+func (v ResourceSizeValueView) CrossReferences() ResourceSizeSpecList {
290+ off := 24
291+ end := off + (int(v.NumCrossReferences()))*20
292+ return ResourceSizeSpecList{b: v.raw[off:end:end]}
293+}
294+
295+// ResourceSizeValueIter walks n consecutive ResourceSizeValue elements; Err reports a malformed length.
296+// It shares the lifetime of the bytes it walks.
297+type ResourceSizeValueIter struct {
298+ b []byte
299+ n int
300+ v ResourceSizeValueView
301+ err bool
302+}
303+
304+// NewResourceSizeValueIter iterates n elements encoded at the start of b.
305+func NewResourceSizeValueIter(b []byte, n int) ResourceSizeValueIter {
306+ return ResourceSizeValueIter{b: b, n: n}
307+}
308+func (it *ResourceSizeValueIter) Next() bool {
309+ if it.n <= 0 || it.err {
310+ return false
311+ }
312+ s := sizeResourceSizeValue(it.b)
313+ if s < 0 {
314+ it.err = true
315+ it.n = 0
316+ return false
317+ }
318+ it.v = ResourceSizeValueView{raw: it.b[:s:s]}
319+ it.b = it.b[s:]
320+ it.n--
321+ return true
322+}
323+func (it *ResourceSizeValueIter) Value() ResourceSizeValueView { return it.v }
324+func (it *ResourceSizeValueIter) Err() bool { return it.err }
325+
326+// ClientList is a borrowed view over a wire list of Client. It shares the lifetime of the bytes it was taken from; copy what you keep.
327+type ClientList struct{ b []byte }
328+
329+func (l ClientList) Len() int { return len(l.b) / 8 }
330+func (l ClientList) At(i int) Client { return GetClient(l.b[i*8:]) }
331+
332+// ResourceSizeSpecList is a borrowed view over a wire list of ResourceSizeSpec. It shares the lifetime of the bytes it was taken from; copy what you keep.
333+type ResourceSizeSpecList struct{ b []byte }
334+
335+func (l ResourceSizeSpecList) Len() int { return len(l.b) / 20 }
336+func (l ResourceSizeSpecList) At(i int) ResourceSizeSpec { return GetResourceSizeSpec(l.b[i*20:]) }
337+
338+// TypeList is a borrowed view over a wire list of Type. It shares the lifetime of the bytes it was taken from; copy what you keep.
339+type TypeList struct{ b []byte }
340+
341+func (l TypeList) Len() int { return len(l.b) / 8 }
342+func (l TypeList) At(i int) Type { return GetType(l.b[i*8:]) }
343+
344+// Uint32List is a borrowed view over a wire list of uint32. It shares the lifetime of the bytes it was taken from; copy what you keep.
345+type Uint32List struct{ b []byte }
346+
347+func (l Uint32List) Len() int { return len(l.b) / 4 }
348+func (l Uint32List) At(i int) uint32 { return uint32(binary.LittleEndian.Uint32(l.b[i*4:])) }
A res/requests_generated.go +144 -0
@@ -0,0 +1,144 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package res
3+
4+import "encoding/binary"
5+import "bnema.dev/xturbo"
6+
7+func QueryVersion(b *xturbo.Buf, clientMajor uint8, clientMinor uint8) xturbo.Seq {
8+ if b.Ext == nil {
9+ b.Fail(xturbo.ErrExtMissing)
10+ return 0
11+ }
12+ major := b.Ext.Major(xturbo.ExtRes)
13+ if major == 0 {
14+ b.Fail(xturbo.ErrExtMissing)
15+ return 0
16+ }
17+ p, seq := b.Request(major, 0, 4)
18+ if p == nil {
19+ return 0
20+ }
21+ p[0:][0] = byte(clientMajor)
22+ p[1:][0] = byte(clientMinor)
23+ return seq
24+}
25+
26+func QueryClients(b *xturbo.Buf) xturbo.Seq {
27+ if b.Ext == nil {
28+ b.Fail(xturbo.ErrExtMissing)
29+ return 0
30+ }
31+ major := b.Ext.Major(xturbo.ExtRes)
32+ if major == 0 {
33+ b.Fail(xturbo.ErrExtMissing)
34+ return 0
35+ }
36+ p, seq := b.Request(major, 1, 0)
37+ if p == nil {
38+ return 0
39+ }
40+ return seq
41+}
42+
43+func QueryClientResources(b *xturbo.Buf, xid uint32) xturbo.Seq {
44+ if b.Ext == nil {
45+ b.Fail(xturbo.ErrExtMissing)
46+ return 0
47+ }
48+ major := b.Ext.Major(xturbo.ExtRes)
49+ if major == 0 {
50+ b.Fail(xturbo.ErrExtMissing)
51+ return 0
52+ }
53+ p, seq := b.Request(major, 2, 4)
54+ if p == nil {
55+ return 0
56+ }
57+ binary.LittleEndian.PutUint32(p[0:], uint32(xid))
58+ return seq
59+}
60+
61+func QueryClientPixmapBytes(b *xturbo.Buf, xid uint32) xturbo.Seq {
62+ if b.Ext == nil {
63+ b.Fail(xturbo.ErrExtMissing)
64+ return 0
65+ }
66+ major := b.Ext.Major(xturbo.ExtRes)
67+ if major == 0 {
68+ b.Fail(xturbo.ErrExtMissing)
69+ return 0
70+ }
71+ p, seq := b.Request(major, 3, 4)
72+ if p == nil {
73+ return 0
74+ }
75+ binary.LittleEndian.PutUint32(p[0:], uint32(xid))
76+ return seq
77+}
78+
79+func QueryClientIds(b *xturbo.Buf, specs []ClientIdSpec) xturbo.Seq {
80+ if uint64(len(specs)) > 4294967295 {
81+ b.Fail(xturbo.ErrBadLength)
82+ return 0
83+ }
84+ size := 0
85+ size += 4
86+ size += len(specs) * 8
87+ size = (size + 3) &^ 3
88+ if b.Ext == nil {
89+ b.Fail(xturbo.ErrExtMissing)
90+ return 0
91+ }
92+ major := b.Ext.Major(xturbo.ExtRes)
93+ if major == 0 {
94+ b.Fail(xturbo.ErrExtMissing)
95+ return 0
96+ }
97+ p, seq := b.Request(major, 4, size)
98+ if p == nil {
99+ return 0
100+ }
101+ off := 0
102+ binary.LittleEndian.PutUint32(p[off:], uint32(len(specs)))
103+ off += 4
104+ for i := range specs {
105+ specs[i].Put(p[off:])
106+ off += 8
107+ }
108+ return seq
109+}
110+
111+func QueryResourceBytes(b *xturbo.Buf, client uint32, specs []ResourceIdSpec) xturbo.Seq {
112+ if uint64(len(specs)) > 4294967295 {
113+ b.Fail(xturbo.ErrBadLength)
114+ return 0
115+ }
116+ size := 0
117+ size += 4
118+ size += 4
119+ size += len(specs) * 8
120+ size = (size + 3) &^ 3
121+ if b.Ext == nil {
122+ b.Fail(xturbo.ErrExtMissing)
123+ return 0
124+ }
125+ major := b.Ext.Major(xturbo.ExtRes)
126+ if major == 0 {
127+ b.Fail(xturbo.ErrExtMissing)
128+ return 0
129+ }
130+ p, seq := b.Request(major, 5, size)
131+ if p == nil {
132+ return 0
133+ }
134+ off := 0
135+ binary.LittleEndian.PutUint32(p[off:], uint32(client))
136+ off += 4
137+ binary.LittleEndian.PutUint32(p[off:], uint32(len(specs)))
138+ off += 4
139+ for i := range specs {
140+ specs[i].Put(p[off:])
141+ off += 8
142+ }
143+ return seq
144+}
@@ -0,0 +1,144 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package res
3+
4+import "encoding/binary"
5+import "bnema.dev/xturbo"
6+
7+func QueryVersion(b *xturbo.Buf, clientMajor uint8, clientMinor uint8) xturbo.Seq {
8+ if b.Ext == nil {
9+ b.Fail(xturbo.ErrExtMissing)
10+ return 0
11+ }
12+ major := b.Ext.Major(xturbo.ExtRes)
13+ if major == 0 {
14+ b.Fail(xturbo.ErrExtMissing)
15+ return 0
16+ }
17+ p, seq := b.Request(major, 0, 4)
18+ if p == nil {
19+ return 0
20+ }
21+ p[0:][0] = byte(clientMajor)
22+ p[1:][0] = byte(clientMinor)
23+ return seq
24+}
25+
26+func QueryClients(b *xturbo.Buf) xturbo.Seq {
27+ if b.Ext == nil {
28+ b.Fail(xturbo.ErrExtMissing)
29+ return 0
30+ }
31+ major := b.Ext.Major(xturbo.ExtRes)
32+ if major == 0 {
33+ b.Fail(xturbo.ErrExtMissing)
34+ return 0
35+ }
36+ p, seq := b.Request(major, 1, 0)
37+ if p == nil {
38+ return 0
39+ }
40+ return seq
41+}
42+
43+func QueryClientResources(b *xturbo.Buf, xid uint32) xturbo.Seq {
44+ if b.Ext == nil {
45+ b.Fail(xturbo.ErrExtMissing)
46+ return 0
47+ }
48+ major := b.Ext.Major(xturbo.ExtRes)
49+ if major == 0 {
50+ b.Fail(xturbo.ErrExtMissing)
51+ return 0
52+ }
53+ p, seq := b.Request(major, 2, 4)
54+ if p == nil {
55+ return 0
56+ }
57+ binary.LittleEndian.PutUint32(p[0:], uint32(xid))
58+ return seq
59+}
60+
61+func QueryClientPixmapBytes(b *xturbo.Buf, xid uint32) xturbo.Seq {
62+ if b.Ext == nil {
63+ b.Fail(xturbo.ErrExtMissing)
64+ return 0
65+ }
66+ major := b.Ext.Major(xturbo.ExtRes)
67+ if major == 0 {
68+ b.Fail(xturbo.ErrExtMissing)
69+ return 0
70+ }
71+ p, seq := b.Request(major, 3, 4)
72+ if p == nil {
73+ return 0
74+ }
75+ binary.LittleEndian.PutUint32(p[0:], uint32(xid))
76+ return seq
77+}
78+
79+func QueryClientIds(b *xturbo.Buf, specs []ClientIdSpec) xturbo.Seq {
80+ if uint64(len(specs)) > 4294967295 {
81+ b.Fail(xturbo.ErrBadLength)
82+ return 0
83+ }
84+ size := 0
85+ size += 4
86+ size += len(specs) * 8
87+ size = (size + 3) &^ 3
88+ if b.Ext == nil {
89+ b.Fail(xturbo.ErrExtMissing)
90+ return 0
91+ }
92+ major := b.Ext.Major(xturbo.ExtRes)
93+ if major == 0 {
94+ b.Fail(xturbo.ErrExtMissing)
95+ return 0
96+ }
97+ p, seq := b.Request(major, 4, size)
98+ if p == nil {
99+ return 0
100+ }
101+ off := 0
102+ binary.LittleEndian.PutUint32(p[off:], uint32(len(specs)))
103+ off += 4
104+ for i := range specs {
105+ specs[i].Put(p[off:])
106+ off += 8
107+ }
108+ return seq
109+}
110+
111+func QueryResourceBytes(b *xturbo.Buf, client uint32, specs []ResourceIdSpec) xturbo.Seq {
112+ if uint64(len(specs)) > 4294967295 {
113+ b.Fail(xturbo.ErrBadLength)
114+ return 0
115+ }
116+ size := 0
117+ size += 4
118+ size += 4
119+ size += len(specs) * 8
120+ size = (size + 3) &^ 3
121+ if b.Ext == nil {
122+ b.Fail(xturbo.ErrExtMissing)
123+ return 0
124+ }
125+ major := b.Ext.Major(xturbo.ExtRes)
126+ if major == 0 {
127+ b.Fail(xturbo.ErrExtMissing)
128+ return 0
129+ }
130+ p, seq := b.Request(major, 5, size)
131+ if p == nil {
132+ return 0
133+ }
134+ off := 0
135+ binary.LittleEndian.PutUint32(p[off:], uint32(client))
136+ off += 4
137+ binary.LittleEndian.PutUint32(p[off:], uint32(len(specs)))
138+ off += 4
139+ for i := range specs {
140+ specs[i].Put(p[off:])
141+ off += 8
142+ }
143+ return seq
144+}
A res/sizes_test.go +47 -0
@@ -0,0 +1,47 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package res
3+
4+import "testing"
5+
6+func TestWireSizes(t *testing.T) {
7+ if ClientSize != 8 {
8+ t.Errorf("Client fixed prefix = %d", ClientSize)
9+ }
10+ if TypeSize != 8 {
11+ t.Errorf("Type fixed prefix = %d", TypeSize)
12+ }
13+ if ClientIdSpecSize != 8 {
14+ t.Errorf("ClientIdSpec fixed prefix = %d", ClientIdSpecSize)
15+ }
16+ if ClientIdValueSize != 12 {
17+ t.Errorf("ClientIdValue fixed prefix = %d", ClientIdValueSize)
18+ }
19+ if ResourceIdSpecSize != 8 {
20+ t.Errorf("ResourceIdSpec fixed prefix = %d", ResourceIdSpecSize)
21+ }
22+ if ResourceSizeSpecSize != 20 {
23+ t.Errorf("ResourceSizeSpec fixed prefix = %d", ResourceSizeSpecSize)
24+ }
25+ if ResourceSizeValueSize != 24 {
26+ t.Errorf("ResourceSizeValue fixed prefix = %d", ResourceSizeValueSize)
27+ }
28+ if got := 32; got != 32 {
29+ t.Errorf("reply QueryVersion fixed size = %d", got)
30+ }
31+ if got := 32; got != 32 {
32+ t.Errorf("reply QueryClients fixed size = %d", got)
33+ }
34+ if got := 32; got != 32 {
35+ t.Errorf("reply QueryClientResources fixed size = %d", got)
36+ }
37+ if got := 32; got != 32 {
38+ t.Errorf("reply QueryClientPixmapBytes fixed size = %d", got)
39+ }
40+ if got := 32; got != 32 {
41+ t.Errorf("reply QueryClientIds fixed size = %d", got)
42+ }
43+ if got := 32; got != 32 {
44+ t.Errorf("reply QueryResourceBytes fixed size = %d", got)
45+ }
46+
47+}
@@ -0,0 +1,47 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package res
3+
4+import "testing"
5+
6+func TestWireSizes(t *testing.T) {
7+ if ClientSize != 8 {
8+ t.Errorf("Client fixed prefix = %d", ClientSize)
9+ }
10+ if TypeSize != 8 {
11+ t.Errorf("Type fixed prefix = %d", TypeSize)
12+ }
13+ if ClientIdSpecSize != 8 {
14+ t.Errorf("ClientIdSpec fixed prefix = %d", ClientIdSpecSize)
15+ }
16+ if ClientIdValueSize != 12 {
17+ t.Errorf("ClientIdValue fixed prefix = %d", ClientIdValueSize)
18+ }
19+ if ResourceIdSpecSize != 8 {
20+ t.Errorf("ResourceIdSpec fixed prefix = %d", ResourceIdSpecSize)
21+ }
22+ if ResourceSizeSpecSize != 20 {
23+ t.Errorf("ResourceSizeSpec fixed prefix = %d", ResourceSizeSpecSize)
24+ }
25+ if ResourceSizeValueSize != 24 {
26+ t.Errorf("ResourceSizeValue fixed prefix = %d", ResourceSizeValueSize)
27+ }
28+ if got := 32; got != 32 {
29+ t.Errorf("reply QueryVersion fixed size = %d", got)
30+ }
31+ if got := 32; got != 32 {
32+ t.Errorf("reply QueryClients fixed size = %d", got)
33+ }
34+ if got := 32; got != 32 {
35+ t.Errorf("reply QueryClientResources fixed size = %d", got)
36+ }
37+ if got := 32; got != 32 {
38+ t.Errorf("reply QueryClientPixmapBytes fixed size = %d", got)
39+ }
40+ if got := 32; got != 32 {
41+ t.Errorf("reply QueryClientIds fixed size = %d", got)
42+ }
43+ if got := 32; got != 32 {
44+ t.Errorf("reply QueryResourceBytes fixed size = %d", got)
45+ }
46+
47+}
A res/types_generated.go +159 -0
@@ -0,0 +1,159 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package res
3+
4+import "bnema.dev/xturbo/xproto"
5+import "encoding/binary"
6+
7+type Client struct {
8+ ResourceBase uint32
9+ ResourceMask uint32
10+}
11+
12+const ClientSize = 8
13+
14+func (v Client) Put(p []byte) {
15+ clear(p[:8])
16+ binary.LittleEndian.PutUint32(p[0:], uint32(v.ResourceBase))
17+ binary.LittleEndian.PutUint32(p[4:], uint32(v.ResourceMask))
18+}
19+func GetClient(p []byte) (v Client) {
20+ _ = p[7]
21+ v.ResourceBase = uint32(binary.LittleEndian.Uint32(p[0:]))
22+ v.ResourceMask = uint32(binary.LittleEndian.Uint32(p[4:]))
23+ return
24+}
25+
26+type Type struct {
27+ ResourceType xproto.Atom
28+ Count uint32
29+}
30+
31+const TypeSize = 8
32+
33+func (v Type) Put(p []byte) {
34+ clear(p[:8])
35+ binary.LittleEndian.PutUint32(p[0:], uint32(v.ResourceType))
36+ binary.LittleEndian.PutUint32(p[4:], uint32(v.Count))
37+}
38+func GetType(p []byte) (v Type) {
39+ _ = p[7]
40+ v.ResourceType = xproto.Atom(binary.LittleEndian.Uint32(p[0:]))
41+ v.Count = uint32(binary.LittleEndian.Uint32(p[4:]))
42+ return
43+}
44+
45+type ClientIdSpec struct {
46+ Client uint32
47+ Mask ClientIdMask
48+}
49+
50+const ClientIdSpecSize = 8
51+
52+func (v ClientIdSpec) Put(p []byte) {
53+ clear(p[:8])
54+ binary.LittleEndian.PutUint32(p[0:], uint32(v.Client))
55+ binary.LittleEndian.PutUint32(p[4:], uint32(v.Mask))
56+}
57+func GetClientIdSpec(p []byte) (v ClientIdSpec) {
58+ _ = p[7]
59+ v.Client = uint32(binary.LittleEndian.Uint32(p[0:]))
60+ v.Mask = ClientIdMask(binary.LittleEndian.Uint32(p[4:]))
61+ return
62+}
63+
64+type ClientIdValue struct {
65+ Spec ClientIdSpec
66+ Length uint32
67+ Value []uint32
68+}
69+
70+const ClientIdValueSize = 12
71+
72+func (v ClientIdValue) Size() int { off := 0; off += 8; off += 4; off += len(v.Value) * 4; return off }
73+func (v ClientIdValue) Put(p []byte) {
74+ off := 0
75+ v.Spec.Put(p[off:])
76+ off += 8
77+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Length))
78+ off += 4
79+ for i := range v.Value {
80+ binary.LittleEndian.PutUint32(p[off+i*4:], uint32(v.Value[i]))
81+ }
82+ off += len(v.Value) * 4
83+}
84+
85+type ResourceIdSpec struct {
86+ Resource uint32
87+ Type uint32
88+}
89+
90+const ResourceIdSpecSize = 8
91+
92+func (v ResourceIdSpec) Put(p []byte) {
93+ clear(p[:8])
94+ binary.LittleEndian.PutUint32(p[0:], uint32(v.Resource))
95+ binary.LittleEndian.PutUint32(p[4:], uint32(v.Type))
96+}
97+func GetResourceIdSpec(p []byte) (v ResourceIdSpec) {
98+ _ = p[7]
99+ v.Resource = uint32(binary.LittleEndian.Uint32(p[0:]))
100+ v.Type = uint32(binary.LittleEndian.Uint32(p[4:]))
101+ return
102+}
103+
104+type ResourceSizeSpec struct {
105+ Spec ResourceIdSpec
106+ Bytes uint32
107+ RefCount uint32
108+ UseCount uint32
109+}
110+
111+const ResourceSizeSpecSize = 20
112+
113+func (v ResourceSizeSpec) Put(p []byte) {
114+ clear(p[:20])
115+ v.Spec.Put(p[0:])
116+ binary.LittleEndian.PutUint32(p[8:], uint32(v.Bytes))
117+ binary.LittleEndian.PutUint32(p[12:], uint32(v.RefCount))
118+ binary.LittleEndian.PutUint32(p[16:], uint32(v.UseCount))
119+}
120+func GetResourceSizeSpec(p []byte) (v ResourceSizeSpec) {
121+ _ = p[19]
122+ v.Spec = GetResourceIdSpec(p[0:])
123+ v.Bytes = uint32(binary.LittleEndian.Uint32(p[8:]))
124+ v.RefCount = uint32(binary.LittleEndian.Uint32(p[12:]))
125+ v.UseCount = uint32(binary.LittleEndian.Uint32(p[16:]))
126+ return
127+}
128+
129+type ResourceSizeValue struct {
130+ Size_ ResourceSizeSpec
131+ NumCrossReferences uint32
132+ CrossReferences []ResourceSizeSpec
133+}
134+
135+const ResourceSizeValueSize = 24
136+
137+func (v ResourceSizeValue) Size() int {
138+ off := 0
139+ off += 20
140+ off += 4
141+ off += len(v.CrossReferences) * 20
142+ return off
143+}
144+func (v ResourceSizeValue) Put(p []byte) {
145+ off := 0
146+ v.Size_.Put(p[off:])
147+ off += 20
148+ binary.LittleEndian.PutUint32(p[off:], uint32(v.NumCrossReferences))
149+ off += 4
150+ for i := range v.CrossReferences {
151+ v.CrossReferences[i].Put(p[off+i*20:])
152+ }
153+ off += len(v.CrossReferences) * 20
154+}
155+
156+type ClientIdMask uint32
157+
158+const ClientIdMaskClientXID ClientIdMask = 1
159+const ClientIdMaskLocalClientPID ClientIdMask = 2
@@ -0,0 +1,159 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package res
3+
4+import "bnema.dev/xturbo/xproto"
5+import "encoding/binary"
6+
7+type Client struct {
8+ ResourceBase uint32
9+ ResourceMask uint32
10+}
11+
12+const ClientSize = 8
13+
14+func (v Client) Put(p []byte) {
15+ clear(p[:8])
16+ binary.LittleEndian.PutUint32(p[0:], uint32(v.ResourceBase))
17+ binary.LittleEndian.PutUint32(p[4:], uint32(v.ResourceMask))
18+}
19+func GetClient(p []byte) (v Client) {
20+ _ = p[7]
21+ v.ResourceBase = uint32(binary.LittleEndian.Uint32(p[0:]))
22+ v.ResourceMask = uint32(binary.LittleEndian.Uint32(p[4:]))
23+ return
24+}
25+
26+type Type struct {
27+ ResourceType xproto.Atom
28+ Count uint32
29+}
30+
31+const TypeSize = 8
32+
33+func (v Type) Put(p []byte) {
34+ clear(p[:8])
35+ binary.LittleEndian.PutUint32(p[0:], uint32(v.ResourceType))
36+ binary.LittleEndian.PutUint32(p[4:], uint32(v.Count))
37+}
38+func GetType(p []byte) (v Type) {
39+ _ = p[7]
40+ v.ResourceType = xproto.Atom(binary.LittleEndian.Uint32(p[0:]))
41+ v.Count = uint32(binary.LittleEndian.Uint32(p[4:]))
42+ return
43+}
44+
45+type ClientIdSpec struct {
46+ Client uint32
47+ Mask ClientIdMask
48+}
49+
50+const ClientIdSpecSize = 8
51+
52+func (v ClientIdSpec) Put(p []byte) {
53+ clear(p[:8])
54+ binary.LittleEndian.PutUint32(p[0:], uint32(v.Client))
55+ binary.LittleEndian.PutUint32(p[4:], uint32(v.Mask))
56+}
57+func GetClientIdSpec(p []byte) (v ClientIdSpec) {
58+ _ = p[7]
59+ v.Client = uint32(binary.LittleEndian.Uint32(p[0:]))
60+ v.Mask = ClientIdMask(binary.LittleEndian.Uint32(p[4:]))
61+ return
62+}
63+
64+type ClientIdValue struct {
65+ Spec ClientIdSpec
66+ Length uint32
67+ Value []uint32
68+}
69+
70+const ClientIdValueSize = 12
71+
72+func (v ClientIdValue) Size() int { off := 0; off += 8; off += 4; off += len(v.Value) * 4; return off }
73+func (v ClientIdValue) Put(p []byte) {
74+ off := 0
75+ v.Spec.Put(p[off:])
76+ off += 8
77+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Length))
78+ off += 4
79+ for i := range v.Value {
80+ binary.LittleEndian.PutUint32(p[off+i*4:], uint32(v.Value[i]))
81+ }
82+ off += len(v.Value) * 4
83+}
84+
85+type ResourceIdSpec struct {
86+ Resource uint32
87+ Type uint32
88+}
89+
90+const ResourceIdSpecSize = 8
91+
92+func (v ResourceIdSpec) Put(p []byte) {
93+ clear(p[:8])
94+ binary.LittleEndian.PutUint32(p[0:], uint32(v.Resource))
95+ binary.LittleEndian.PutUint32(p[4:], uint32(v.Type))
96+}
97+func GetResourceIdSpec(p []byte) (v ResourceIdSpec) {
98+ _ = p[7]
99+ v.Resource = uint32(binary.LittleEndian.Uint32(p[0:]))
100+ v.Type = uint32(binary.LittleEndian.Uint32(p[4:]))
101+ return
102+}
103+
104+type ResourceSizeSpec struct {
105+ Spec ResourceIdSpec
106+ Bytes uint32
107+ RefCount uint32
108+ UseCount uint32
109+}
110+
111+const ResourceSizeSpecSize = 20
112+
113+func (v ResourceSizeSpec) Put(p []byte) {
114+ clear(p[:20])
115+ v.Spec.Put(p[0:])
116+ binary.LittleEndian.PutUint32(p[8:], uint32(v.Bytes))
117+ binary.LittleEndian.PutUint32(p[12:], uint32(v.RefCount))
118+ binary.LittleEndian.PutUint32(p[16:], uint32(v.UseCount))
119+}
120+func GetResourceSizeSpec(p []byte) (v ResourceSizeSpec) {
121+ _ = p[19]
122+ v.Spec = GetResourceIdSpec(p[0:])
123+ v.Bytes = uint32(binary.LittleEndian.Uint32(p[8:]))
124+ v.RefCount = uint32(binary.LittleEndian.Uint32(p[12:]))
125+ v.UseCount = uint32(binary.LittleEndian.Uint32(p[16:]))
126+ return
127+}
128+
129+type ResourceSizeValue struct {
130+ Size_ ResourceSizeSpec
131+ NumCrossReferences uint32
132+ CrossReferences []ResourceSizeSpec
133+}
134+
135+const ResourceSizeValueSize = 24
136+
137+func (v ResourceSizeValue) Size() int {
138+ off := 0
139+ off += 20
140+ off += 4
141+ off += len(v.CrossReferences) * 20
142+ return off
143+}
144+func (v ResourceSizeValue) Put(p []byte) {
145+ off := 0
146+ v.Size_.Put(p[off:])
147+ off += 20
148+ binary.LittleEndian.PutUint32(p[off:], uint32(v.NumCrossReferences))
149+ off += 4
150+ for i := range v.CrossReferences {
151+ v.CrossReferences[i].Put(p[off+i*20:])
152+ }
153+ off += len(v.CrossReferences) * 20
154+}
155+
156+type ClientIdMask uint32
157+
158+const ClientIdMaskClientXID ClientIdMask = 1
159+const ClientIdMaskLocalClientPID ClientIdMask = 2
A shape/replies_fuzz_test.go +86 -0
@@ -0,0 +1,86 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package shape
3+
4+import "testing"
5+
6+func FuzzParseQueryVersionReply(f *testing.F) {
7+ f.Add(make([]byte, 32))
8+ f.Fuzz(func(t *testing.T, raw []byte) {
9+ r, ok := ParseQueryVersionReply(raw)
10+ if !ok {
11+ if len(raw) >= 32 {
12+ t.Fatal("rejected a complete fixed-size reply")
13+ }
14+ return
15+ }
16+ if len(r.Raw()) != len(raw) {
17+ t.Fatal("Raw must return the parsed bytes")
18+ }
19+ _ = r.MajorVersion()
20+ _ = r.MinorVersion()
21+ })
22+}
23+
24+func FuzzParseQueryExtentsReply(f *testing.F) {
25+ f.Add(make([]byte, 32))
26+ f.Fuzz(func(t *testing.T, raw []byte) {
27+ r, ok := ParseQueryExtentsReply(raw)
28+ if !ok {
29+ if len(raw) >= 32 {
30+ t.Fatal("rejected a complete fixed-size reply")
31+ }
32+ return
33+ }
34+ if len(r.Raw()) != len(raw) {
35+ t.Fatal("Raw must return the parsed bytes")
36+ }
37+ _ = r.BoundingShaped()
38+ _ = r.ClipShaped()
39+ _ = r.BoundingShapeExtentsX()
40+ _ = r.BoundingShapeExtentsY()
41+ _ = r.BoundingShapeExtentsWidth()
42+ _ = r.BoundingShapeExtentsHeight()
43+ _ = r.ClipShapeExtentsX()
44+ _ = r.ClipShapeExtentsY()
45+ _ = r.ClipShapeExtentsWidth()
46+ _ = r.ClipShapeExtentsHeight()
47+ })
48+}
49+
50+func FuzzParseInputSelectedReply(f *testing.F) {
51+ f.Add(make([]byte, 32))
52+ f.Fuzz(func(t *testing.T, raw []byte) {
53+ r, ok := ParseInputSelectedReply(raw)
54+ if !ok {
55+ if len(raw) >= 32 {
56+ t.Fatal("rejected a complete fixed-size reply")
57+ }
58+ return
59+ }
60+ if len(r.Raw()) != len(raw) {
61+ t.Fatal("Raw must return the parsed bytes")
62+ }
63+ _ = r.Enabled()
64+ })
65+}
66+
67+func FuzzParseGetRectanglesReply(f *testing.F) {
68+ f.Add(make([]byte, 32))
69+ f.Fuzz(func(t *testing.T, raw []byte) {
70+ r, ok := ParseGetRectanglesReply(raw)
71+ if !ok {
72+ return
73+ }
74+ if len(r.Raw()) != len(raw) {
75+ t.Fatal("Raw must return the parsed bytes")
76+ }
77+ _ = r.Ordering()
78+ _ = r.RectanglesLen()
79+ {
80+ l0 := r.Rectangles()
81+ for i := 0; i < l0.Len(); i++ {
82+ _ = l0.At(i)
83+ }
84+ }
85+ })
86+}
@@ -0,0 +1,86 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package shape
3+
4+import "testing"
5+
6+func FuzzParseQueryVersionReply(f *testing.F) {
7+ f.Add(make([]byte, 32))
8+ f.Fuzz(func(t *testing.T, raw []byte) {
9+ r, ok := ParseQueryVersionReply(raw)
10+ if !ok {
11+ if len(raw) >= 32 {
12+ t.Fatal("rejected a complete fixed-size reply")
13+ }
14+ return
15+ }
16+ if len(r.Raw()) != len(raw) {
17+ t.Fatal("Raw must return the parsed bytes")
18+ }
19+ _ = r.MajorVersion()
20+ _ = r.MinorVersion()
21+ })
22+}
23+
24+func FuzzParseQueryExtentsReply(f *testing.F) {
25+ f.Add(make([]byte, 32))
26+ f.Fuzz(func(t *testing.T, raw []byte) {
27+ r, ok := ParseQueryExtentsReply(raw)
28+ if !ok {
29+ if len(raw) >= 32 {
30+ t.Fatal("rejected a complete fixed-size reply")
31+ }
32+ return
33+ }
34+ if len(r.Raw()) != len(raw) {
35+ t.Fatal("Raw must return the parsed bytes")
36+ }
37+ _ = r.BoundingShaped()
38+ _ = r.ClipShaped()
39+ _ = r.BoundingShapeExtentsX()
40+ _ = r.BoundingShapeExtentsY()
41+ _ = r.BoundingShapeExtentsWidth()
42+ _ = r.BoundingShapeExtentsHeight()
43+ _ = r.ClipShapeExtentsX()
44+ _ = r.ClipShapeExtentsY()
45+ _ = r.ClipShapeExtentsWidth()
46+ _ = r.ClipShapeExtentsHeight()
47+ })
48+}
49+
50+func FuzzParseInputSelectedReply(f *testing.F) {
51+ f.Add(make([]byte, 32))
52+ f.Fuzz(func(t *testing.T, raw []byte) {
53+ r, ok := ParseInputSelectedReply(raw)
54+ if !ok {
55+ if len(raw) >= 32 {
56+ t.Fatal("rejected a complete fixed-size reply")
57+ }
58+ return
59+ }
60+ if len(r.Raw()) != len(raw) {
61+ t.Fatal("Raw must return the parsed bytes")
62+ }
63+ _ = r.Enabled()
64+ })
65+}
66+
67+func FuzzParseGetRectanglesReply(f *testing.F) {
68+ f.Add(make([]byte, 32))
69+ f.Fuzz(func(t *testing.T, raw []byte) {
70+ r, ok := ParseGetRectanglesReply(raw)
71+ if !ok {
72+ return
73+ }
74+ if len(r.Raw()) != len(raw) {
75+ t.Fatal("Raw must return the parsed bytes")
76+ }
77+ _ = r.Ordering()
78+ _ = r.RectanglesLen()
79+ {
80+ l0 := r.Rectangles()
81+ for i := 0; i < l0.Len(); i++ {
82+ _ = l0.At(i)
83+ }
84+ }
85+ })
86+}
A shape/replies_generated.go +123 -0
@@ -0,0 +1,123 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package shape
3+
4+import "bnema.dev/xturbo/xproto"
5+import "encoding/binary"
6+
7+// QueryVersionReply is a zero-copy view over a QueryVersion reply; offsets count from reply byte 0.
8+// It borrows the reply bytes: valid only until the Handler callback returns, because the read ring is reused. Copy what you keep.
9+type QueryVersionReply struct{ raw []byte }
10+
11+// ParseQueryVersionReply validates raw (the whole reply, 32+4*length bytes) once; getters do not re-check.
12+func ParseQueryVersionReply(raw []byte) (QueryVersionReply, bool) {
13+ if len(raw) < 32 {
14+ return QueryVersionReply{}, false
15+ }
16+ r := QueryVersionReply{raw: raw}
17+ return r, true
18+}
19+func (r QueryVersionReply) Raw() []byte { return r.raw }
20+func (r QueryVersionReply) MajorVersion() uint16 {
21+ return uint16(binary.LittleEndian.Uint16(r.raw[8:]))
22+}
23+func (r QueryVersionReply) MinorVersion() uint16 {
24+ return uint16(binary.LittleEndian.Uint16(r.raw[10:]))
25+}
26+
27+// QueryExtentsReply is a zero-copy view over a QueryExtents reply; offsets count from reply byte 0.
28+// It borrows the reply bytes: valid only until the Handler callback returns, because the read ring is reused. Copy what you keep.
29+type QueryExtentsReply struct{ raw []byte }
30+
31+// ParseQueryExtentsReply validates raw (the whole reply, 32+4*length bytes) once; getters do not re-check.
32+func ParseQueryExtentsReply(raw []byte) (QueryExtentsReply, bool) {
33+ if len(raw) < 32 {
34+ return QueryExtentsReply{}, false
35+ }
36+ r := QueryExtentsReply{raw: raw}
37+ return r, true
38+}
39+func (r QueryExtentsReply) Raw() []byte { return r.raw }
40+func (r QueryExtentsReply) BoundingShaped() bool { return (r.raw[8:][0] != 0) }
41+func (r QueryExtentsReply) ClipShaped() bool { return (r.raw[9:][0] != 0) }
42+func (r QueryExtentsReply) BoundingShapeExtentsX() int16 {
43+ return int16(binary.LittleEndian.Uint16(r.raw[12:]))
44+}
45+func (r QueryExtentsReply) BoundingShapeExtentsY() int16 {
46+ return int16(binary.LittleEndian.Uint16(r.raw[14:]))
47+}
48+func (r QueryExtentsReply) BoundingShapeExtentsWidth() uint16 {
49+ return uint16(binary.LittleEndian.Uint16(r.raw[16:]))
50+}
51+func (r QueryExtentsReply) BoundingShapeExtentsHeight() uint16 {
52+ return uint16(binary.LittleEndian.Uint16(r.raw[18:]))
53+}
54+func (r QueryExtentsReply) ClipShapeExtentsX() int16 {
55+ return int16(binary.LittleEndian.Uint16(r.raw[20:]))
56+}
57+func (r QueryExtentsReply) ClipShapeExtentsY() int16 {
58+ return int16(binary.LittleEndian.Uint16(r.raw[22:]))
59+}
60+func (r QueryExtentsReply) ClipShapeExtentsWidth() uint16 {
61+ return uint16(binary.LittleEndian.Uint16(r.raw[24:]))
62+}
63+func (r QueryExtentsReply) ClipShapeExtentsHeight() uint16 {
64+ return uint16(binary.LittleEndian.Uint16(r.raw[26:]))
65+}
66+
67+// InputSelectedReply is a zero-copy view over a InputSelected reply; offsets count from reply byte 0.
68+// It borrows the reply bytes: valid only until the Handler callback returns, because the read ring is reused. Copy what you keep.
69+type InputSelectedReply struct{ raw []byte }
70+
71+// ParseInputSelectedReply validates raw (the whole reply, 32+4*length bytes) once; getters do not re-check.
72+func ParseInputSelectedReply(raw []byte) (InputSelectedReply, bool) {
73+ if len(raw) < 32 {
74+ return InputSelectedReply{}, false
75+ }
76+ r := InputSelectedReply{raw: raw}
77+ return r, true
78+}
79+func (r InputSelectedReply) Raw() []byte { return r.raw }
80+func (r InputSelectedReply) Enabled() bool { return (r.raw[1:][0] != 0) }
81+
82+// GetRectanglesReply is a zero-copy view over a GetRectangles reply; offsets count from reply byte 0.
83+// It borrows the reply bytes: valid only until the Handler callback returns, because the read ring is reused. Copy what you keep.
84+type GetRectanglesReply struct{ raw []byte }
85+
86+// ParseGetRectanglesReply validates raw (the whole reply, 32+4*length bytes) once; getters do not re-check.
87+func ParseGetRectanglesReply(raw []byte) (GetRectanglesReply, bool) {
88+ if len(raw) < 32 {
89+ return GetRectanglesReply{}, false
90+ }
91+ r := GetRectanglesReply{raw: raw}
92+ off := 32
93+ {
94+ n := int(r.RectanglesLen())
95+ if n < 0 || n > len(r.raw) {
96+ return GetRectanglesReply{}, false
97+ }
98+ off += n * 8
99+ }
100+ if off > len(r.raw) {
101+ return GetRectanglesReply{}, false
102+ }
103+ if off > len(r.raw) {
104+ return GetRectanglesReply{}, false
105+ }
106+ return r, true
107+}
108+func (r GetRectanglesReply) Raw() []byte { return r.raw }
109+func (r GetRectanglesReply) Ordering() xproto.ClipOrdering { return xproto.ClipOrdering(r.raw[1:][0]) }
110+func (r GetRectanglesReply) RectanglesLen() uint32 {
111+ return uint32(binary.LittleEndian.Uint32(r.raw[8:]))
112+}
113+func (r GetRectanglesReply) Rectangles() RectangleList {
114+ off := 32
115+ end := off + (int(r.RectanglesLen()))*8
116+ return RectangleList{b: r.raw[off:end:end]}
117+}
118+
119+// RectangleList is a borrowed view over a wire list of xproto.Rectangle. It shares the lifetime of the bytes it was taken from; copy what you keep.
120+type RectangleList struct{ b []byte }
121+
122+func (l RectangleList) Len() int { return len(l.b) / 8 }
123+func (l RectangleList) At(i int) xproto.Rectangle { return xproto.GetRectangle(l.b[i*8:]) }
@@ -0,0 +1,123 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package shape
3+
4+import "bnema.dev/xturbo/xproto"
5+import "encoding/binary"
6+
7+// QueryVersionReply is a zero-copy view over a QueryVersion reply; offsets count from reply byte 0.
8+// It borrows the reply bytes: valid only until the Handler callback returns, because the read ring is reused. Copy what you keep.
9+type QueryVersionReply struct{ raw []byte }
10+
11+// ParseQueryVersionReply validates raw (the whole reply, 32+4*length bytes) once; getters do not re-check.
12+func ParseQueryVersionReply(raw []byte) (QueryVersionReply, bool) {
13+ if len(raw) < 32 {
14+ return QueryVersionReply{}, false
15+ }
16+ r := QueryVersionReply{raw: raw}
17+ return r, true
18+}
19+func (r QueryVersionReply) Raw() []byte { return r.raw }
20+func (r QueryVersionReply) MajorVersion() uint16 {
21+ return uint16(binary.LittleEndian.Uint16(r.raw[8:]))
22+}
23+func (r QueryVersionReply) MinorVersion() uint16 {
24+ return uint16(binary.LittleEndian.Uint16(r.raw[10:]))
25+}
26+
27+// QueryExtentsReply is a zero-copy view over a QueryExtents reply; offsets count from reply byte 0.
28+// It borrows the reply bytes: valid only until the Handler callback returns, because the read ring is reused. Copy what you keep.
29+type QueryExtentsReply struct{ raw []byte }
30+
31+// ParseQueryExtentsReply validates raw (the whole reply, 32+4*length bytes) once; getters do not re-check.
32+func ParseQueryExtentsReply(raw []byte) (QueryExtentsReply, bool) {
33+ if len(raw) < 32 {
34+ return QueryExtentsReply{}, false
35+ }
36+ r := QueryExtentsReply{raw: raw}
37+ return r, true
38+}
39+func (r QueryExtentsReply) Raw() []byte { return r.raw }
40+func (r QueryExtentsReply) BoundingShaped() bool { return (r.raw[8:][0] != 0) }
41+func (r QueryExtentsReply) ClipShaped() bool { return (r.raw[9:][0] != 0) }
42+func (r QueryExtentsReply) BoundingShapeExtentsX() int16 {
43+ return int16(binary.LittleEndian.Uint16(r.raw[12:]))
44+}
45+func (r QueryExtentsReply) BoundingShapeExtentsY() int16 {
46+ return int16(binary.LittleEndian.Uint16(r.raw[14:]))
47+}
48+func (r QueryExtentsReply) BoundingShapeExtentsWidth() uint16 {
49+ return uint16(binary.LittleEndian.Uint16(r.raw[16:]))
50+}
51+func (r QueryExtentsReply) BoundingShapeExtentsHeight() uint16 {
52+ return uint16(binary.LittleEndian.Uint16(r.raw[18:]))
53+}
54+func (r QueryExtentsReply) ClipShapeExtentsX() int16 {
55+ return int16(binary.LittleEndian.Uint16(r.raw[20:]))
56+}
57+func (r QueryExtentsReply) ClipShapeExtentsY() int16 {
58+ return int16(binary.LittleEndian.Uint16(r.raw[22:]))
59+}
60+func (r QueryExtentsReply) ClipShapeExtentsWidth() uint16 {
61+ return uint16(binary.LittleEndian.Uint16(r.raw[24:]))
62+}
63+func (r QueryExtentsReply) ClipShapeExtentsHeight() uint16 {
64+ return uint16(binary.LittleEndian.Uint16(r.raw[26:]))
65+}
66+
67+// InputSelectedReply is a zero-copy view over a InputSelected reply; offsets count from reply byte 0.
68+// It borrows the reply bytes: valid only until the Handler callback returns, because the read ring is reused. Copy what you keep.
69+type InputSelectedReply struct{ raw []byte }
70+
71+// ParseInputSelectedReply validates raw (the whole reply, 32+4*length bytes) once; getters do not re-check.
72+func ParseInputSelectedReply(raw []byte) (InputSelectedReply, bool) {
73+ if len(raw) < 32 {
74+ return InputSelectedReply{}, false
75+ }
76+ r := InputSelectedReply{raw: raw}
77+ return r, true
78+}
79+func (r InputSelectedReply) Raw() []byte { return r.raw }
80+func (r InputSelectedReply) Enabled() bool { return (r.raw[1:][0] != 0) }
81+
82+// GetRectanglesReply is a zero-copy view over a GetRectangles reply; offsets count from reply byte 0.
83+// It borrows the reply bytes: valid only until the Handler callback returns, because the read ring is reused. Copy what you keep.
84+type GetRectanglesReply struct{ raw []byte }
85+
86+// ParseGetRectanglesReply validates raw (the whole reply, 32+4*length bytes) once; getters do not re-check.
87+func ParseGetRectanglesReply(raw []byte) (GetRectanglesReply, bool) {
88+ if len(raw) < 32 {
89+ return GetRectanglesReply{}, false
90+ }
91+ r := GetRectanglesReply{raw: raw}
92+ off := 32
93+ {
94+ n := int(r.RectanglesLen())
95+ if n < 0 || n > len(r.raw) {
96+ return GetRectanglesReply{}, false
97+ }
98+ off += n * 8
99+ }
100+ if off > len(r.raw) {
101+ return GetRectanglesReply{}, false
102+ }
103+ if off > len(r.raw) {
104+ return GetRectanglesReply{}, false
105+ }
106+ return r, true
107+}
108+func (r GetRectanglesReply) Raw() []byte { return r.raw }
109+func (r GetRectanglesReply) Ordering() xproto.ClipOrdering { return xproto.ClipOrdering(r.raw[1:][0]) }
110+func (r GetRectanglesReply) RectanglesLen() uint32 {
111+ return uint32(binary.LittleEndian.Uint32(r.raw[8:]))
112+}
113+func (r GetRectanglesReply) Rectangles() RectangleList {
114+ off := 32
115+ end := off + (int(r.RectanglesLen()))*8
116+ return RectangleList{b: r.raw[off:end:end]}
117+}
118+
119+// RectangleList is a borrowed view over a wire list of xproto.Rectangle. It shares the lifetime of the bytes it was taken from; copy what you keep.
120+type RectangleList struct{ b []byte }
121+
122+func (l RectangleList) Len() int { return len(l.b) / 8 }
123+func (l RectangleList) At(i int) xproto.Rectangle { return xproto.GetRectangle(l.b[i*8:]) }
A shape/requests_generated.go +214 -0
@@ -0,0 +1,214 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package shape
3+
4+import "bnema.dev/xturbo/xproto"
5+import "encoding/binary"
6+import "bnema.dev/xturbo"
7+
8+func QueryVersion(b *xturbo.Buf) xturbo.Seq {
9+ if b.Ext == nil {
10+ b.Fail(xturbo.ErrExtMissing)
11+ return 0
12+ }
13+ major := b.Ext.Major(xturbo.ExtShape)
14+ if major == 0 {
15+ b.Fail(xturbo.ErrExtMissing)
16+ return 0
17+ }
18+ p, seq := b.Request(major, 0, 0)
19+ if p == nil {
20+ return 0
21+ }
22+ return seq
23+}
24+
25+func Rectangles(b *xturbo.Buf, operation So, destinationKind Sk, ordering xproto.ClipOrdering, destinationWindow xproto.Window, xOffset int16, yOffset int16, rectangles []xproto.Rectangle) xturbo.Seq {
26+ size := 0
27+ size += 1
28+ size += 1
29+ size += 1
30+ size += 1
31+ size += 4
32+ size += 2
33+ size += 2
34+ size += len(rectangles) * 8
35+ size = (size + 3) &^ 3
36+ if b.Ext == nil {
37+ b.Fail(xturbo.ErrExtMissing)
38+ return 0
39+ }
40+ major := b.Ext.Major(xturbo.ExtShape)
41+ if major == 0 {
42+ b.Fail(xturbo.ErrExtMissing)
43+ return 0
44+ }
45+ p, seq := b.Request(major, 1, size)
46+ if p == nil {
47+ return 0
48+ }
49+ off := 0
50+ p[off:][0] = byte(operation)
51+ off += 1
52+ p[off:][0] = byte(destinationKind)
53+ off += 1
54+ p[off:][0] = byte(ordering)
55+ off += 1
56+ off += 1
57+ binary.LittleEndian.PutUint32(p[off:], uint32(destinationWindow))
58+ off += 4
59+ binary.LittleEndian.PutUint16(p[off:], uint16(xOffset))
60+ off += 2
61+ binary.LittleEndian.PutUint16(p[off:], uint16(yOffset))
62+ off += 2
63+ for i := range rectangles {
64+ rectangles[i].Put(p[off:])
65+ off += 8
66+ }
67+ return seq
68+}
69+
70+func Mask(b *xturbo.Buf, operation So, destinationKind Sk, destinationWindow xproto.Window, xOffset int16, yOffset int16, sourceBitmap xproto.Pixmap) xturbo.Seq {
71+ if b.Ext == nil {
72+ b.Fail(xturbo.ErrExtMissing)
73+ return 0
74+ }
75+ major := b.Ext.Major(xturbo.ExtShape)
76+ if major == 0 {
77+ b.Fail(xturbo.ErrExtMissing)
78+ return 0
79+ }
80+ p, seq := b.Request(major, 2, 16)
81+ if p == nil {
82+ return 0
83+ }
84+ p[0:][0] = byte(operation)
85+ p[1:][0] = byte(destinationKind)
86+ binary.LittleEndian.PutUint32(p[4:], uint32(destinationWindow))
87+ binary.LittleEndian.PutUint16(p[8:], uint16(xOffset))
88+ binary.LittleEndian.PutUint16(p[10:], uint16(yOffset))
89+ binary.LittleEndian.PutUint32(p[12:], uint32(sourceBitmap))
90+ return seq
91+}
92+
93+func Combine(b *xturbo.Buf, operation So, destinationKind Sk, sourceKind Sk, destinationWindow xproto.Window, xOffset int16, yOffset int16, sourceWindow xproto.Window) xturbo.Seq {
94+ if b.Ext == nil {
95+ b.Fail(xturbo.ErrExtMissing)
96+ return 0
97+ }
98+ major := b.Ext.Major(xturbo.ExtShape)
99+ if major == 0 {
100+ b.Fail(xturbo.ErrExtMissing)
101+ return 0
102+ }
103+ p, seq := b.Request(major, 3, 16)
104+ if p == nil {
105+ return 0
106+ }
107+ p[0:][0] = byte(operation)
108+ p[1:][0] = byte(destinationKind)
109+ p[2:][0] = byte(sourceKind)
110+ binary.LittleEndian.PutUint32(p[4:], uint32(destinationWindow))
111+ binary.LittleEndian.PutUint16(p[8:], uint16(xOffset))
112+ binary.LittleEndian.PutUint16(p[10:], uint16(yOffset))
113+ binary.LittleEndian.PutUint32(p[12:], uint32(sourceWindow))
114+ return seq
115+}
116+
117+func Offset(b *xturbo.Buf, destinationKind Sk, destinationWindow xproto.Window, xOffset int16, yOffset int16) xturbo.Seq {
118+ if b.Ext == nil {
119+ b.Fail(xturbo.ErrExtMissing)
120+ return 0
121+ }
122+ major := b.Ext.Major(xturbo.ExtShape)
123+ if major == 0 {
124+ b.Fail(xturbo.ErrExtMissing)
125+ return 0
126+ }
127+ p, seq := b.Request(major, 4, 12)
128+ if p == nil {
129+ return 0
130+ }
131+ p[0:][0] = byte(destinationKind)
132+ binary.LittleEndian.PutUint32(p[4:], uint32(destinationWindow))
133+ binary.LittleEndian.PutUint16(p[8:], uint16(xOffset))
134+ binary.LittleEndian.PutUint16(p[10:], uint16(yOffset))
135+ return seq
136+}
137+
138+func QueryExtents(b *xturbo.Buf, destinationWindow xproto.Window) xturbo.Seq {
139+ if b.Ext == nil {
140+ b.Fail(xturbo.ErrExtMissing)
141+ return 0
142+ }
143+ major := b.Ext.Major(xturbo.ExtShape)
144+ if major == 0 {
145+ b.Fail(xturbo.ErrExtMissing)
146+ return 0
147+ }
148+ p, seq := b.Request(major, 5, 4)
149+ if p == nil {
150+ return 0
151+ }
152+ binary.LittleEndian.PutUint32(p[0:], uint32(destinationWindow))
153+ return seq
154+}
155+
156+func SelectInput(b *xturbo.Buf, destinationWindow xproto.Window, enable bool) xturbo.Seq {
157+ if b.Ext == nil {
158+ b.Fail(xturbo.ErrExtMissing)
159+ return 0
160+ }
161+ major := b.Ext.Major(xturbo.ExtShape)
162+ if major == 0 {
163+ b.Fail(xturbo.ErrExtMissing)
164+ return 0
165+ }
166+ p, seq := b.Request(major, 6, 8)
167+ if p == nil {
168+ return 0
169+ }
170+ binary.LittleEndian.PutUint32(p[0:], uint32(destinationWindow))
171+ if enable {
172+ p[4:][0] = 1
173+ } else {
174+ p[4:][0] = 0
175+ }
176+ return seq
177+}
178+
179+func InputSelected(b *xturbo.Buf, destinationWindow xproto.Window) xturbo.Seq {
180+ if b.Ext == nil {
181+ b.Fail(xturbo.ErrExtMissing)
182+ return 0
183+ }
184+ major := b.Ext.Major(xturbo.ExtShape)
185+ if major == 0 {
186+ b.Fail(xturbo.ErrExtMissing)
187+ return 0
188+ }
189+ p, seq := b.Request(major, 7, 4)
190+ if p == nil {
191+ return 0
192+ }
193+ binary.LittleEndian.PutUint32(p[0:], uint32(destinationWindow))
194+ return seq
195+}
196+
197+func GetRectangles(b *xturbo.Buf, window xproto.Window, sourceKind Sk) xturbo.Seq {
198+ if b.Ext == nil {
199+ b.Fail(xturbo.ErrExtMissing)
200+ return 0
201+ }
202+ major := b.Ext.Major(xturbo.ExtShape)
203+ if major == 0 {
204+ b.Fail(xturbo.ErrExtMissing)
205+ return 0
206+ }
207+ p, seq := b.Request(major, 8, 8)
208+ if p == nil {
209+ return 0
210+ }
211+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
212+ p[4:][0] = byte(sourceKind)
213+ return seq
214+}
@@ -0,0 +1,214 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package shape
3+
4+import "bnema.dev/xturbo/xproto"
5+import "encoding/binary"
6+import "bnema.dev/xturbo"
7+
8+func QueryVersion(b *xturbo.Buf) xturbo.Seq {
9+ if b.Ext == nil {
10+ b.Fail(xturbo.ErrExtMissing)
11+ return 0
12+ }
13+ major := b.Ext.Major(xturbo.ExtShape)
14+ if major == 0 {
15+ b.Fail(xturbo.ErrExtMissing)
16+ return 0
17+ }
18+ p, seq := b.Request(major, 0, 0)
19+ if p == nil {
20+ return 0
21+ }
22+ return seq
23+}
24+
25+func Rectangles(b *xturbo.Buf, operation So, destinationKind Sk, ordering xproto.ClipOrdering, destinationWindow xproto.Window, xOffset int16, yOffset int16, rectangles []xproto.Rectangle) xturbo.Seq {
26+ size := 0
27+ size += 1
28+ size += 1
29+ size += 1
30+ size += 1
31+ size += 4
32+ size += 2
33+ size += 2
34+ size += len(rectangles) * 8
35+ size = (size + 3) &^ 3
36+ if b.Ext == nil {
37+ b.Fail(xturbo.ErrExtMissing)
38+ return 0
39+ }
40+ major := b.Ext.Major(xturbo.ExtShape)
41+ if major == 0 {
42+ b.Fail(xturbo.ErrExtMissing)
43+ return 0
44+ }
45+ p, seq := b.Request(major, 1, size)
46+ if p == nil {
47+ return 0
48+ }
49+ off := 0
50+ p[off:][0] = byte(operation)
51+ off += 1
52+ p[off:][0] = byte(destinationKind)
53+ off += 1
54+ p[off:][0] = byte(ordering)
55+ off += 1
56+ off += 1
57+ binary.LittleEndian.PutUint32(p[off:], uint32(destinationWindow))
58+ off += 4
59+ binary.LittleEndian.PutUint16(p[off:], uint16(xOffset))
60+ off += 2
61+ binary.LittleEndian.PutUint16(p[off:], uint16(yOffset))
62+ off += 2
63+ for i := range rectangles {
64+ rectangles[i].Put(p[off:])
65+ off += 8
66+ }
67+ return seq
68+}
69+
70+func Mask(b *xturbo.Buf, operation So, destinationKind Sk, destinationWindow xproto.Window, xOffset int16, yOffset int16, sourceBitmap xproto.Pixmap) xturbo.Seq {
71+ if b.Ext == nil {
72+ b.Fail(xturbo.ErrExtMissing)
73+ return 0
74+ }
75+ major := b.Ext.Major(xturbo.ExtShape)
76+ if major == 0 {
77+ b.Fail(xturbo.ErrExtMissing)
78+ return 0
79+ }
80+ p, seq := b.Request(major, 2, 16)
81+ if p == nil {
82+ return 0
83+ }
84+ p[0:][0] = byte(operation)
85+ p[1:][0] = byte(destinationKind)
86+ binary.LittleEndian.PutUint32(p[4:], uint32(destinationWindow))
87+ binary.LittleEndian.PutUint16(p[8:], uint16(xOffset))
88+ binary.LittleEndian.PutUint16(p[10:], uint16(yOffset))
89+ binary.LittleEndian.PutUint32(p[12:], uint32(sourceBitmap))
90+ return seq
91+}
92+
93+func Combine(b *xturbo.Buf, operation So, destinationKind Sk, sourceKind Sk, destinationWindow xproto.Window, xOffset int16, yOffset int16, sourceWindow xproto.Window) xturbo.Seq {
94+ if b.Ext == nil {
95+ b.Fail(xturbo.ErrExtMissing)
96+ return 0
97+ }
98+ major := b.Ext.Major(xturbo.ExtShape)
99+ if major == 0 {
100+ b.Fail(xturbo.ErrExtMissing)
101+ return 0
102+ }
103+ p, seq := b.Request(major, 3, 16)
104+ if p == nil {
105+ return 0
106+ }
107+ p[0:][0] = byte(operation)
108+ p[1:][0] = byte(destinationKind)
109+ p[2:][0] = byte(sourceKind)
110+ binary.LittleEndian.PutUint32(p[4:], uint32(destinationWindow))
111+ binary.LittleEndian.PutUint16(p[8:], uint16(xOffset))
112+ binary.LittleEndian.PutUint16(p[10:], uint16(yOffset))
113+ binary.LittleEndian.PutUint32(p[12:], uint32(sourceWindow))
114+ return seq
115+}
116+
117+func Offset(b *xturbo.Buf, destinationKind Sk, destinationWindow xproto.Window, xOffset int16, yOffset int16) xturbo.Seq {
118+ if b.Ext == nil {
119+ b.Fail(xturbo.ErrExtMissing)
120+ return 0
121+ }
122+ major := b.Ext.Major(xturbo.ExtShape)
123+ if major == 0 {
124+ b.Fail(xturbo.ErrExtMissing)
125+ return 0
126+ }
127+ p, seq := b.Request(major, 4, 12)
128+ if p == nil {
129+ return 0
130+ }
131+ p[0:][0] = byte(destinationKind)
132+ binary.LittleEndian.PutUint32(p[4:], uint32(destinationWindow))
133+ binary.LittleEndian.PutUint16(p[8:], uint16(xOffset))
134+ binary.LittleEndian.PutUint16(p[10:], uint16(yOffset))
135+ return seq
136+}
137+
138+func QueryExtents(b *xturbo.Buf, destinationWindow xproto.Window) xturbo.Seq {
139+ if b.Ext == nil {
140+ b.Fail(xturbo.ErrExtMissing)
141+ return 0
142+ }
143+ major := b.Ext.Major(xturbo.ExtShape)
144+ if major == 0 {
145+ b.Fail(xturbo.ErrExtMissing)
146+ return 0
147+ }
148+ p, seq := b.Request(major, 5, 4)
149+ if p == nil {
150+ return 0
151+ }
152+ binary.LittleEndian.PutUint32(p[0:], uint32(destinationWindow))
153+ return seq
154+}
155+
156+func SelectInput(b *xturbo.Buf, destinationWindow xproto.Window, enable bool) xturbo.Seq {
157+ if b.Ext == nil {
158+ b.Fail(xturbo.ErrExtMissing)
159+ return 0
160+ }
161+ major := b.Ext.Major(xturbo.ExtShape)
162+ if major == 0 {
163+ b.Fail(xturbo.ErrExtMissing)
164+ return 0
165+ }
166+ p, seq := b.Request(major, 6, 8)
167+ if p == nil {
168+ return 0
169+ }
170+ binary.LittleEndian.PutUint32(p[0:], uint32(destinationWindow))
171+ if enable {
172+ p[4:][0] = 1
173+ } else {
174+ p[4:][0] = 0
175+ }
176+ return seq
177+}
178+
179+func InputSelected(b *xturbo.Buf, destinationWindow xproto.Window) xturbo.Seq {
180+ if b.Ext == nil {
181+ b.Fail(xturbo.ErrExtMissing)
182+ return 0
183+ }
184+ major := b.Ext.Major(xturbo.ExtShape)
185+ if major == 0 {
186+ b.Fail(xturbo.ErrExtMissing)
187+ return 0
188+ }
189+ p, seq := b.Request(major, 7, 4)
190+ if p == nil {
191+ return 0
192+ }
193+ binary.LittleEndian.PutUint32(p[0:], uint32(destinationWindow))
194+ return seq
195+}
196+
197+func GetRectangles(b *xturbo.Buf, window xproto.Window, sourceKind Sk) xturbo.Seq {
198+ if b.Ext == nil {
199+ b.Fail(xturbo.ErrExtMissing)
200+ return 0
201+ }
202+ major := b.Ext.Major(xturbo.ExtShape)
203+ if major == 0 {
204+ b.Fail(xturbo.ErrExtMissing)
205+ return 0
206+ }
207+ p, seq := b.Request(major, 8, 8)
208+ if p == nil {
209+ return 0
210+ }
211+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
212+ p[4:][0] = byte(sourceKind)
213+ return seq
214+}
A shape/sizes_test.go +23 -0
@@ -0,0 +1,23 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package shape
3+
4+import "testing"
5+
6+func TestWireSizes(t *testing.T) {
7+ if got := 32; got != 32 {
8+ t.Errorf("event Notify fixed size = %d", got)
9+ }
10+ if got := 32; got != 32 {
11+ t.Errorf("reply QueryVersion fixed size = %d", got)
12+ }
13+ if got := 32; got != 32 {
14+ t.Errorf("reply QueryExtents fixed size = %d", got)
15+ }
16+ if got := 32; got != 32 {
17+ t.Errorf("reply InputSelected fixed size = %d", got)
18+ }
19+ if got := 32; got != 32 {
20+ t.Errorf("reply GetRectangles fixed size = %d", got)
21+ }
22+
23+}
@@ -0,0 +1,23 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package shape
3+
4+import "testing"
5+
6+func TestWireSizes(t *testing.T) {
7+ if got := 32; got != 32 {
8+ t.Errorf("event Notify fixed size = %d", got)
9+ }
10+ if got := 32; got != 32 {
11+ t.Errorf("reply QueryVersion fixed size = %d", got)
12+ }
13+ if got := 32; got != 32 {
14+ t.Errorf("reply QueryExtents fixed size = %d", got)
15+ }
16+ if got := 32; got != 32 {
17+ t.Errorf("reply InputSelected fixed size = %d", got)
18+ }
19+ if got := 32; got != 32 {
20+ t.Errorf("reply GetRectangles fixed size = %d", got)
21+ }
22+
23+}
A shape/types_generated.go +20 -0
@@ -0,0 +1,20 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package shape
3+
4+type Op uint8
5+
6+type Kind uint8
7+
8+type So uint8
9+
10+const SoSet So = 0
11+const SoUnion So = 1
12+const SoIntersect So = 2
13+const SoSubtract So = 3
14+const SoInvert So = 4
15+
16+type Sk uint8
17+
18+const SkBounding Sk = 0
19+const SkClip Sk = 1
20+const SkInput Sk = 2
@@ -0,0 +1,20 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package shape
3+
4+type Op uint8
5+
6+type Kind uint8
7+
8+type So uint8
9+
10+const SoSet So = 0
11+const SoUnion So = 1
12+const SoIntersect So = 2
13+const SoSubtract So = 3
14+const SoInvert So = 4
15+
16+type Sk uint8
17+
18+const SkBounding Sk = 0
19+const SkClip Sk = 1
20+const SkInput Sk = 2
A testdata/golden/render/CreatePicture.req.hex +3 -0
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+8b0408000300200001002000290000003100000001000000fbffffff07000000
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+8b0408000300200001002000290000003100000001000000fbffffff07000000
A testdata/golden/render/QueryPictFormats.reply.hex +3 -0
@@ -0,0 +1,3 @@
1+# source: Xvfb reply via raw socketpair tee to an independent reference request
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+01001200cf0200001700000001000000060000001001000000000000000000002300000001010000000000000000000000000000000001000000000024000000010800000000000000000000000000000000ff000000000025000000012000001000ff000800ff000000ff001800ff000000000026000000012000001000ff000800ff000000ff00000000000000000027000000012000000800ff001000ff001800ff000000ff000000000028000000012000000800ff001000ff001800ff00000000000000000029000000011800001000ff000800ff000000ff0000000000000000002a000000011800000000ff000800ff001000ff0000000000000000002b0000000110000008000f0004000f0000000f0000000000000000002c0000000110000000000f0004000f0008000f0000000000000000002d000000011000000a001f0005001f0000001f0000000000000000002e0000000110000000001f0005001f000a001f0000000000000000002f000000011000000a001f0005001f0000001f000f00010000000000300000000110000000001f0005001f000a001f000f0001000000000031000000011000000b001f0005003f0000001f000000000000000000320000000110000000001f0005003f000b001f000000000000000000330000000110000008000f0004000f0000000f000c000f0000000000340000000110000000000f0004000f0008000f000c000f000000000035000000012000000000ff000800ff001000ff00000000000000000036000000012000001400ff030a00ff030000ff031e0003000000000037000000012000001400ff030a00ff030000ff03000000000000000038000000012000000000ff030a00ff031400ff031e0003000000000039000000012000000000ff030a00ff031400ff03000000000000000006000000230000001800000100000000210000002900000022000000290000009102000029000000920200002900000093020000290000009402000029000000950200002900000096020000290000009702000029000000980200002900000099020000290000009a020000290000009b020000290000009c020000290000009d020000290000009e020000290000009f02000029000000a002000029000000a102000029000000a202000029000000a302000029000000a402000029000000a502000029000000a602000029000000a702000029000000a802000029000000a902000029000000aa02000029000000ab02000029000000ac02000029000000ad02000029000000ae02000029000000af02000029000000b002000029000000b102000029000000b202000029000000b302000029000000b402000029000000b502000029000000b602000029000000b702000029000000b802000029000000b902000029000000ba02000029000000bb02000029000000bc02000029000000bd02000029000000be02000029000000bf02000029000000c002000029000000c102000029000000c202000029000000c302000029000000c402000029000000c502000029000000c602000029000000c702000029000000c802000029000000c902000029000000ca02000029000000cb02000029000000cc02000029000000cd02000029000000ce02000029000000cf02000029000000d002000029000000d102000029000000d202000029000000d302000029000000d402000029000000d502000029000000d602000029000000d702000029000000d802000029000000d902000029000000da02000029000000db02000029000000dc02000029000000dd02000029000000de02000029000000df02000029000000e002000029000000e102000029000000e202000029000000e302000029000000e402000029000000e502000029000000e602000029000000e702000029000000e802000029000000e902000029000000ea02000029000000eb02000029000000ec02000029000000ed02000029000000ee02000029000000ef02000029000000f002000029000000f102000029000000f202000029000000f302000029000000f402000029000000f502000029000000f602000029000000f702000029000000f802000029000000f902000029000000fa02000029000000fb02000029000000fc02000029000000fd02000029000000fe02000029000000ff0200002900000000030000290000000103000029000000020300002900000003030000290000000403000029000000050300002900000006030000290000000703000029000000080300002900000009030000290000000a030000290000000b030000290000000c030000290000000d030000290000000e030000290000000f0300002900000010030000290000001103000029000000120300002900000013030000290000001403000029000000150300002900000016030000290000001703000029000000180300002900000019030000290000001a030000290000001b030000290000001c030000290000001d030000290000001e030000290000001f0300002900000020030000290000002103000029000000220300002900000023030000290000002403000029000000250300002900000026030000290000002703000029000000280300002900000029030000290000002a030000290000002b030000290000002c030000290000002d030000290000002e030000290000002f0300002900000030030000290000003103000029000000320300002900000033030000290000003403000029000000350300002900000036030000290000003703000029000000380300002900000039030000290000003a030000290000003b030000290000003c030000290000003d030000290000003e030000290000003f0300002900000040030000290000004103000029000000420300002900000043030000290000004403000029000000450300002900000046030000290000004703000029000000480300002900000049030000290000004a030000290000004b030000290000004c030000290000004d030000290000004e030000290000004f0300002900000050030000290000005103000029000000520300002900000053030000290000005403000029000000550300002900000056030000290000005703000029000000580300002900000059030000290000005a030000290000005b030000290000005c030000290000005d030000290000005e030000290000005f0300002900000060030000290000006103000029000000620300002900000063030000290000006403000029000000650300002900000066030000290000006703000029000000680300002900000069030000290000006a030000290000006b030000290000006c030000290000006d030000290000006e030000290000006f0300002900000070030000290000007103000029000000720300002900000073030000290000007403000029000000750300002900000076030000290000007703000029000000780300002900000079030000290000007a030000290000007b030000290000007c030000290000007d030000290000007e030000290000007f0300002900000080030000290000008103000029000000820300002900000083030000290000008403000029000000850300002900000086030000290000008703000029000000880300002900000089030000290000008a030000290000008b030000290000008c030000290000008d030000290000008e030000290000000100000000000000040000000000000008000000000000001000000000000000200010000000000040000000250000008f0300002500000090030000250000009103000025000000920300002500000093030000250000009403000025000000950300002500000096030000250000009703000025000000980300002500000099030000250000009a030000250000009b030000250000009c030000250000009d03000025000000
@@ -0,0 +1,3 @@
1+# source: Xvfb reply via raw socketpair tee to an independent reference request
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+01001200cf0200001700000001000000060000001001000000000000000000002300000001010000000000000000000000000000000001000000000024000000010800000000000000000000000000000000ff000000000025000000012000001000ff000800ff000000ff001800ff000000000026000000012000001000ff000800ff000000ff00000000000000000027000000012000000800ff001000ff001800ff000000ff000000000028000000012000000800ff001000ff001800ff00000000000000000029000000011800001000ff000800ff000000ff0000000000000000002a000000011800000000ff000800ff001000ff0000000000000000002b0000000110000008000f0004000f0000000f0000000000000000002c0000000110000000000f0004000f0008000f0000000000000000002d000000011000000a001f0005001f0000001f0000000000000000002e0000000110000000001f0005001f000a001f0000000000000000002f000000011000000a001f0005001f0000001f000f00010000000000300000000110000000001f0005001f000a001f000f0001000000000031000000011000000b001f0005003f0000001f000000000000000000320000000110000000001f0005003f000b001f000000000000000000330000000110000008000f0004000f0000000f000c000f0000000000340000000110000000000f0004000f0008000f000c000f000000000035000000012000000000ff000800ff001000ff00000000000000000036000000012000001400ff030a00ff030000ff031e0003000000000037000000012000001400ff030a00ff030000ff03000000000000000038000000012000000000ff030a00ff031400ff031e0003000000000039000000012000000000ff030a00ff031400ff03000000000000000006000000230000001800000100000000210000002900000022000000290000009102000029000000920200002900000093020000290000009402000029000000950200002900000096020000290000009702000029000000980200002900000099020000290000009a020000290000009b020000290000009c020000290000009d020000290000009e020000290000009f02000029000000a002000029000000a102000029000000a202000029000000a302000029000000a402000029000000a502000029000000a602000029000000a702000029000000a802000029000000a902000029000000aa02000029000000ab02000029000000ac02000029000000ad02000029000000ae02000029000000af02000029000000b002000029000000b102000029000000b202000029000000b302000029000000b402000029000000b502000029000000b602000029000000b702000029000000b802000029000000b902000029000000ba02000029000000bb02000029000000bc02000029000000bd02000029000000be02000029000000bf02000029000000c002000029000000c102000029000000c202000029000000c302000029000000c402000029000000c502000029000000c602000029000000c702000029000000c802000029000000c902000029000000ca02000029000000cb02000029000000cc02000029000000cd02000029000000ce02000029000000cf02000029000000d002000029000000d102000029000000d202000029000000d302000029000000d402000029000000d502000029000000d602000029000000d702000029000000d802000029000000d902000029000000da02000029000000db02000029000000dc02000029000000dd02000029000000de02000029000000df02000029000000e002000029000000e102000029000000e202000029000000e302000029000000e402000029000000e502000029000000e602000029000000e702000029000000e802000029000000e902000029000000ea02000029000000eb02000029000000ec02000029000000ed02000029000000ee02000029000000ef02000029000000f002000029000000f102000029000000f202000029000000f302000029000000f402000029000000f502000029000000f602000029000000f702000029000000f802000029000000f902000029000000fa02000029000000fb02000029000000fc02000029000000fd02000029000000fe02000029000000ff0200002900000000030000290000000103000029000000020300002900000003030000290000000403000029000000050300002900000006030000290000000703000029000000080300002900000009030000290000000a030000290000000b030000290000000c030000290000000d030000290000000e030000290000000f0300002900000010030000290000001103000029000000120300002900000013030000290000001403000029000000150300002900000016030000290000001703000029000000180300002900000019030000290000001a030000290000001b030000290000001c030000290000001d030000290000001e030000290000001f0300002900000020030000290000002103000029000000220300002900000023030000290000002403000029000000250300002900000026030000290000002703000029000000280300002900000029030000290000002a030000290000002b030000290000002c030000290000002d030000290000002e030000290000002f0300002900000030030000290000003103000029000000320300002900000033030000290000003403000029000000350300002900000036030000290000003703000029000000380300002900000039030000290000003a030000290000003b030000290000003c030000290000003d030000290000003e030000290000003f0300002900000040030000290000004103000029000000420300002900000043030000290000004403000029000000450300002900000046030000290000004703000029000000480300002900000049030000290000004a030000290000004b030000290000004c030000290000004d030000290000004e030000290000004f0300002900000050030000290000005103000029000000520300002900000053030000290000005403000029000000550300002900000056030000290000005703000029000000580300002900000059030000290000005a030000290000005b030000290000005c030000290000005d030000290000005e030000290000005f0300002900000060030000290000006103000029000000620300002900000063030000290000006403000029000000650300002900000066030000290000006703000029000000680300002900000069030000290000006a030000290000006b030000290000006c030000290000006d030000290000006e030000290000006f0300002900000070030000290000007103000029000000720300002900000073030000290000007403000029000000750300002900000076030000290000007703000029000000780300002900000079030000290000007a030000290000007b030000290000007c030000290000007d030000290000007e030000290000007f0300002900000080030000290000008103000029000000820300002900000083030000290000008403000029000000850300002900000086030000290000008703000029000000880300002900000089030000290000008a030000290000008b030000290000008c030000290000008d030000290000008e030000290000000100000000000000040000000000000008000000000000001000000000000000200010000000000040000000250000008f0300002500000090030000250000009103000025000000920300002500000093030000250000009403000025000000950300002500000096030000250000009703000025000000980300002500000099030000250000009a030000250000009b030000250000009c030000250000009d03000025000000
A testdata/golden/res/QueryClientIds.reply.hex +3 -0
@@ -0,0 +1,3 @@
1+# source: Xvfb reply via raw socketpair tee to an independent reference request
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+01000a0006000000020000000000000000000000000000000000000000000000000000000100000000000000000020000100000000000000
@@ -0,0 +1,3 @@
1+# source: Xvfb reply via raw socketpair tee to an independent reference request
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+01000a0006000000020000000000000000000000000000000000000000000000000000000100000000000000000020000100000000000000
A testdata/golden/res/QueryClientIds.req.hex +3 -0
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+94040400010000000000000001000000
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+94040400010000000000000001000000
A testdata/golden/xfixes/QueryVersion.reply.hex +3 -0
@@ -0,0 +1,3 @@
1+# source: Xvfb reply via raw socketpair tee to an independent reference request
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+0100020000000000060000000000000000000000000000000000000000000000
@@ -0,0 +1,3 @@
1+# source: Xvfb reply via raw socketpair tee to an independent reference request
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+0100020000000000060000000000000000000000000000000000000000000000
A testdata/golden/xfixes/QueryVersion.req.hex +3 -0
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+8a0003000600000000000000
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+8a0003000600000000000000
A testdata/golden/xproto/ChangeProperty.req.hex +3 -0
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+120007009f030000e70000001f000000080000000300000061626300
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+120007009f030000e70000001f000000080000000300000061626300
A testdata/golden/xproto/ChangeWindowAttributes.req.hex +3 -0
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+0200050001002000000600000000000001000000
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+0200050001002000000600000000000001000000
A testdata/golden/xproto/ConfigureWindow.req.hex +3 -0
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+0c0003000100200000000000
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+0c0003000100200000000000
A testdata/golden/xproto/ConfigureWindowAll.req.hex +3 -0
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+0c000a00010020007f000000fdffffff090000006000000048000000020000000200200000000000
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+0c000a00010020007f000000fdffffff090000006000000048000000020000000200200000000000
A testdata/golden/xproto/ConfigureWindowSparse.req.hex +3 -0
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+0c0006000100200045000000f9ffffff5000000000000000
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+0c0006000100200045000000f9ffffff5000000000000000
A testdata/golden/xproto/CreateWindow.req.hex +3 -0
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+01000b00010020009f0300000000000040003000000001000000000002060000563412000100000000000000
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+01000b00010020009f0300000000000040003000000001000000000002060000563412000100000000000000
A testdata/golden/xproto/GetGeometry.reply.hex +3 -0
@@ -0,0 +1,3 @@
1+# source: Xvfb reply via raw socketpair tee to an independent reference request
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+01180400000000009f0300000000000020035802000000000000000000000000
@@ -0,0 +1,3 @@
1+# source: Xvfb reply via raw socketpair tee to an independent reference request
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+01180400000000009f0300000000000020035802000000000000000000000000
A testdata/golden/xproto/GetGeometry.req.hex +3 -0
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+0e0002009f030000
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+0e0002009f030000
A testdata/golden/xproto/GetProperty.reply.hex +3 -0
A testdata/golden/xproto/GetPropertyEmpty.reply.hex +3 -0
A testdata/golden/xproto/GetWindowAttributes.reply.hex +3 -0
A testdata/golden/xproto/InternAtom.reply.hex +3 -0
A testdata/golden/xproto/InternAtom.req.hex +3 -0
A testdata/golden/xproto/ListExtensions.reply.hex +3 -0
A testdata/golden/xproto/MapWindow.req.hex +3 -0
A testdata/golden/xproto/QueryExtension.reply.hex +3 -0
A testdata/golden/xproto/QueryTree.reply.hex +3 -0
A values_test.go +103 -0
A xcmisc/replies_fuzz_test.go +60 -0
A xcmisc/replies_generated.go +80 -0
A xcmisc/requests_generated.go +59 -0
A xcmisc/sizes_test.go +17 -0
A xcmisc/types_generated.go +2 -0
A xfixes/replies_fuzz_test.go +136 -0
A xfixes/replies_generated.go +242 -0
A xfixes/requests_generated.go +766 -0
A xfixes/sizes_test.go +32 -0
A xfixes/types_generated.go +55 -0
A xproto/replies_fuzz_test.go +895 -0
A xproto/replies_generated.go +1964 -0
A xproto/requests_generated.go +2780 -0
A xproto/requests_test.go +83 -0
A xproto/sizes_test.go +293 -0
A xproto/types_generated.go +1353 -0
A xproto/types_test.go +54 -0

Comments4 open / 4

bnema outdated

T2.1 implemented: strict source-located XML AST for all 9 pinned modules, rejection tests, parser fuzz seed. Local make check and CGO_ENABLED=0 go build ./... pass; 3-second parser fuzz run passed (416270 executions). T1.1 is on main (ba4ad52), CI run 221 green, repo public. Stopped before T2.2/T2.3 for a public naming-contract decision: xproto WINDOW xidtype and Window enum both map to Go Window under the specified rules (likewise ATOM/Atom, CURSOR/Cursor, PIXMAP/Pixmap, FONT/Font; render PICTURE/Picture). Should these enums reuse the XID type for constants, or receive a distinct name (please specify the naming rule)? No workaround chosen. T2.4 must wait for T2.2/T2.3; AST preserves expressions, imports, attributes and XML field order. No goldens captured yet.

bnema outdated

T2.2 (85a51dd) and T2.3 are implemented. Applied the decided enum/XID type reuse rule; other declaration collisions are fatal. All nine packages compile; manifest-ordered root ExtIDs, type/struct/union encoders and size checks are generated. Fixed requests include core data-byte handling, negotiated extension major opcodes, padding and sticky-error guards. Full make check passed independently after each task (unfiltered output), CGO-disabled build passed, request/Buf allocation tests passed, and benchmarks show 0 B/op, 0 allocs/op. Local xtrace is glibc execution tracing, so the permitted raw socketpair tee fallback captures independent reference encodings accepted by Xvfb. Three request goldens committed; capture update also passes with race enabled. Decisions: variable structs have owned encoding forms now (borrowed View/Iter APIs remain with list/reply tasks); generation wiring brought forward so gen-check verifies this work. xfixes signatures use render/shape types where the XML imports require them (matching actual wire types). T2.4: extend resolveRequests beyond its explicit list/switch gate, lower AST length expressions with renderExpr, add derived-length and mismatch handling, extend independent capture encoder for InternAtom/ChangeProperty/res.QueryClientIds. Buf already supports aligned reservation, zeroing, sticky errors and growth; transport/ack updates remain Phase 3. CI 222 and 223 green; checking latest run next. Keep this MR draft; do not merge.

bnema outdated

Final verification: CI 224 logs show make check and make xserver passed, as did gen-check. Additional local 10-second parser fuzz run passed (~3.57 million executions); clean CGO_ENABLED=0 go test -count=1 ./... and go build ./... passed. Both signed task commits verified with GPG. Working trees clean, origin is ermite only; MR remains WIP/unmerged.

bnema outdated

T2.4 completed in signed commit 582be88. Full make check and make xserver passed; CGO_ENABLED=0 build passed; independent raw socketpair/Xvfb tee captured InternAtom, ChangeProperty (GetProperty read-back), and XRes QueryClientIds (negotiated XRes 1.2). Race-enabled capture update passed. Allocation tests cover InternAtom, 4 KiB ChangeProperty, and fixed struct lists; all zero. Benchmarks: InternAtom 7.714 ns/op, ChangeProperty4KiB 73.58 ns/op, both 0 B/op and 0 allocs/op. Decisions: support implicit list-name_len refs used by QueryTextExtents only when no explicit field exists; reject derived length truncation with ErrBadLength; bring SendEvent fixed-array signature forward from the explicit public contract. T2.5 should remove the switch gate in resolveRequests and implement typed Values structs/setters; request list sizes/offsets now use running body offsets, with final four-byte rounding. Shared lengths stay explicit (e.g. render AddGlyphs); variable structs use Size/Put. T2.5–T2.8 and T3.1–T3.5 not started; stopping at this clean boundary due to long context. Same branch/worktree, MR draft, no tag.

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
l
merge request: the list of files (j k move, enter opens, esc back)
M
merge request: the merge menu; there 1–3 pick the mode, D deletes the branch, enter merges
R
merge request: mark the head read
esc
close a dialog, leave a field

Branches 1

Tags 1

↑↓ moveenter openesc close