detached 8e6fe5c

feat(xtgen): encode fixed requests with captured wire goldens

commit
8e6fe5c385ec0c7334a5b626149497024cd03110
author
brice · · 2026-10-22 06:25 UTC
parent
85a51dd
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
checks
2/2
25 files · +2967 -0
A bigreq/requests_generated.go +21 -0
@@ -0,0 +1,21 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package bigreq
3+
4+import "bnema.dev/xturbo"
5+
6+func Enable(b *xturbo.Buf) xturbo.Seq {
7+ if b.Ext == nil {
8+ b.Fail(xturbo.ErrExtMissing)
9+ return 0
10+ }
11+ major := b.Ext.Major(xturbo.ExtBigRequests)
12+ if major == 0 {
13+ b.Fail(xturbo.ErrExtMissing)
14+ return 0
15+ }
16+ p, seq := b.Request(major, 0, 0)
17+ if p == nil {
18+ return 0
19+ }
20+ return seq
21+}
@@ -0,0 +1,21 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package bigreq
3+
4+import "bnema.dev/xturbo"
5+
6+func Enable(b *xturbo.Buf) xturbo.Seq {
7+ if b.Ext == nil {
8+ b.Fail(xturbo.ErrExtMissing)
9+ return 0
10+ }
11+ major := b.Ext.Major(xturbo.ExtBigRequests)
12+ if major == 0 {
13+ b.Fail(xturbo.ErrExtMissing)
14+ return 0
15+ }
16+ p, seq := b.Request(major, 0, 0)
17+ if p == nil {
18+ return 0
19+ }
20+ return seq
21+}
A buf.go +92 -0
@@ -0,0 +1,92 @@
1+package xturbo
2+
3+import (
4+ "encoding/binary"
5+ "errors"
6+)
7+
8+// Seq identifies a request; zero is invalid.
9+type Seq uint64
10+
11+var (
12+ ErrRequestTooLarge = errors.New("xturbo: request too large")
13+ ErrExtMissing = errors.New("xturbo: extension missing")
14+ ErrBadLength = errors.New("xturbo: bad length")
15+ ErrSeqOverflow = errors.New("xturbo: sequence overflow")
16+)
17+
18+// Buf is the caller-owned request encoder. The transport will own flushing and
19+// acknowledgment in Phase 3. It is not safe for concurrent use.
20+type Buf struct {
21+ Ext *ExtTable
22+ b []byte
23+ flushed int
24+ next, acked Seq
25+ maxReq uint32
26+ err error
27+}
28+
29+func NewBuf(size int) *Buf {
30+ if size <= 0 {
31+ size = 64 << 10
32+ }
33+ return &Buf{b: make([]byte, 0, size), next: 1, maxReq: 262140}
34+}
35+func (b *Buf) Fail(err error) {
36+ if b.err == nil {
37+ b.err = err
38+ }
39+}
40+func (b *Buf) Err() error { return b.err }
41+func (b *Buf) Reset() { b.b = b.b[:0]; b.flushed = 0 }
42+func (b *Buf) Bytes() []byte { return b.b[b.flushed:] }
43+func (b *Buf) Len() int { return len(b.b) - b.flushed }
44+func (b *Buf) Next() Seq { return b.next }
45+
46+// Request reserves a zeroed, four-byte-aligned body after the wire header.
47+// BIG-REQUESTS enablement is transport-owned; maxReq starts at the core limit.
48+func (b *Buf) Request(major, data uint8, body int) ([]byte, Seq) {
49+ if b.err != nil {
50+ return nil, 0
51+ }
52+ if body < 0 || body&3 != 0 {
53+ b.Fail(ErrBadLength)
54+ return nil, 0
55+ }
56+ if uint64(body)+4 > uint64(b.maxReq) {
57+ b.Fail(ErrRequestTooLarge)
58+ return nil, 0
59+ }
60+ if b.next-b.acked >= 0xffff {
61+ b.Fail(ErrSeqOverflow)
62+ return nil, 0
63+ }
64+ header := 4
65+ if (body+4)/4 > 0xffff {
66+ header = 8
67+ }
68+ total := body + header
69+ start := len(b.b)
70+ if total > cap(b.b)-start {
71+ capacity := cap(b.b) * 2
72+ if capacity < start+total {
73+ capacity = start + total
74+ }
75+ grown := make([]byte, start, capacity)
76+ copy(grown, b.b)
77+ b.b = grown
78+ }
79+ b.b = b.b[:start+total]
80+ p := b.b[start:]
81+ clear(p)
82+ p[0] = major
83+ p[1] = data
84+ if header == 4 {
85+ binary.LittleEndian.PutUint16(p[2:], uint16(total/4))
86+ } else {
87+ binary.LittleEndian.PutUint32(p[4:], uint32(total/4))
88+ }
89+ seq := b.next
90+ b.next++
91+ return p[header:], seq
92+}
@@ -0,0 +1,92 @@
1+package xturbo
2+
3+import (
4+ "encoding/binary"
5+ "errors"
6+)
7+
8+// Seq identifies a request; zero is invalid.
9+type Seq uint64
10+
11+var (
12+ ErrRequestTooLarge = errors.New("xturbo: request too large")
13+ ErrExtMissing = errors.New("xturbo: extension missing")
14+ ErrBadLength = errors.New("xturbo: bad length")
15+ ErrSeqOverflow = errors.New("xturbo: sequence overflow")
16+)
17+
18+// Buf is the caller-owned request encoder. The transport will own flushing and
19+// acknowledgment in Phase 3. It is not safe for concurrent use.
20+type Buf struct {
21+ Ext *ExtTable
22+ b []byte
23+ flushed int
24+ next, acked Seq
25+ maxReq uint32
26+ err error
27+}
28+
29+func NewBuf(size int) *Buf {
30+ if size <= 0 {
31+ size = 64 << 10
32+ }
33+ return &Buf{b: make([]byte, 0, size), next: 1, maxReq: 262140}
34+}
35+func (b *Buf) Fail(err error) {
36+ if b.err == nil {
37+ b.err = err
38+ }
39+}
40+func (b *Buf) Err() error { return b.err }
41+func (b *Buf) Reset() { b.b = b.b[:0]; b.flushed = 0 }
42+func (b *Buf) Bytes() []byte { return b.b[b.flushed:] }
43+func (b *Buf) Len() int { return len(b.b) - b.flushed }
44+func (b *Buf) Next() Seq { return b.next }
45+
46+// Request reserves a zeroed, four-byte-aligned body after the wire header.
47+// BIG-REQUESTS enablement is transport-owned; maxReq starts at the core limit.
48+func (b *Buf) Request(major, data uint8, body int) ([]byte, Seq) {
49+ if b.err != nil {
50+ return nil, 0
51+ }
52+ if body < 0 || body&3 != 0 {
53+ b.Fail(ErrBadLength)
54+ return nil, 0
55+ }
56+ if uint64(body)+4 > uint64(b.maxReq) {
57+ b.Fail(ErrRequestTooLarge)
58+ return nil, 0
59+ }
60+ if b.next-b.acked >= 0xffff {
61+ b.Fail(ErrSeqOverflow)
62+ return nil, 0
63+ }
64+ header := 4
65+ if (body+4)/4 > 0xffff {
66+ header = 8
67+ }
68+ total := body + header
69+ start := len(b.b)
70+ if total > cap(b.b)-start {
71+ capacity := cap(b.b) * 2
72+ if capacity < start+total {
73+ capacity = start + total
74+ }
75+ grown := make([]byte, start, capacity)
76+ copy(grown, b.b)
77+ b.b = grown
78+ }
79+ b.b = b.b[:start+total]
80+ p := b.b[start:]
81+ clear(p)
82+ p[0] = major
83+ p[1] = data
84+ if header == 4 {
85+ binary.LittleEndian.PutUint16(p[2:], uint16(total/4))
86+ } else {
87+ binary.LittleEndian.PutUint32(p[4:], uint32(total/4))
88+ }
89+ seq := b.next
90+ b.next++
91+ return p[header:], seq
92+}
A buf_test.go +69 -0
@@ -0,0 +1,69 @@
1+package xturbo
2+
3+import (
4+ "bytes"
5+ "encoding/binary"
6+ "errors"
7+ "testing"
8+)
9+
10+func TestBufRequest(t *testing.T) {
11+ b := NewBuf(4)
12+ p, seq := b.Request(8, 2, 4)
13+ if seq != 1 || len(p) != 4 || !bytes.Equal(b.Bytes(), []byte{8, 2, 2, 0, 0, 0, 0, 0}) {
14+ t.Fatalf("%x %d", b.Bytes(), seq)
15+ }
16+ p[0] = 255
17+ b.Reset()
18+ p, seq = b.Request(14, 0, 4)
19+ if seq != 2 || p[0] != 0 || b.Next() != 3 || b.Len() != 8 {
20+ t.Fatal("reset sequence/zeroing")
21+ }
22+ first := errors.New("first")
23+ b.Fail(first)
24+ b.Fail(ErrBadLength)
25+ p, seq = b.Request(1, 0, 0)
26+ if p != nil || seq != 0 || b.Err() != first {
27+ t.Fatal("sticky error")
28+ }
29+}
30+func TestBufLimits(t *testing.T) {
31+ for _, body := range []int{-1, 1, 262140} {
32+ b := NewBuf(0)
33+ p, s := b.Request(1, 0, body)
34+ if p != nil || s != 0 || b.Err() == nil || b.Len() != 0 {
35+ t.Fatal(body)
36+ }
37+ }
38+ b := NewBuf(0)
39+ b.next = 0xffff
40+ if p, s := b.Request(1, 0, 0); p != nil || s != 0 || b.Err() != ErrSeqOverflow {
41+ t.Fatal("overflow")
42+ }
43+ b = NewBuf(0)
44+ b.maxReq = 1 << 20
45+ p, s := b.Request(1, 0, 262140)
46+ if s != 1 || len(p) != 262140 || binary.LittleEndian.Uint16(b.Bytes()[2:]) != 0 || binary.LittleEndian.Uint32(b.Bytes()[4:]) != 65537 {
47+ t.Fatal("BIG-REQUESTS header")
48+ }
49+}
50+func TestAllocBufRequest(t *testing.T) {
51+ for _, body := range []int{4, 65536} {
52+ b := NewBuf(128 << 10)
53+ if n := testing.AllocsPerRun(1000, func() { b.Reset(); b.Request(1, 0, body) }); n != 0 {
54+ t.Fatal(n)
55+ }
56+ if b.Err() != nil {
57+ t.Fatal(b.Err())
58+ }
59+ }
60+}
61+func BenchmarkBufRequest(b *testing.B) {
62+ buf := NewBuf(0)
63+ b.ReportAllocs()
64+ for b.Loop() {
65+ buf.Reset()
66+ buf.acked = buf.next
67+ buf.Request(1, 0, 4)
68+ }
69+}
@@ -0,0 +1,69 @@
1+package xturbo
2+
3+import (
4+ "bytes"
5+ "encoding/binary"
6+ "errors"
7+ "testing"
8+)
9+
10+func TestBufRequest(t *testing.T) {
11+ b := NewBuf(4)
12+ p, seq := b.Request(8, 2, 4)
13+ if seq != 1 || len(p) != 4 || !bytes.Equal(b.Bytes(), []byte{8, 2, 2, 0, 0, 0, 0, 0}) {
14+ t.Fatalf("%x %d", b.Bytes(), seq)
15+ }
16+ p[0] = 255
17+ b.Reset()
18+ p, seq = b.Request(14, 0, 4)
19+ if seq != 2 || p[0] != 0 || b.Next() != 3 || b.Len() != 8 {
20+ t.Fatal("reset sequence/zeroing")
21+ }
22+ first := errors.New("first")
23+ b.Fail(first)
24+ b.Fail(ErrBadLength)
25+ p, seq = b.Request(1, 0, 0)
26+ if p != nil || seq != 0 || b.Err() != first {
27+ t.Fatal("sticky error")
28+ }
29+}
30+func TestBufLimits(t *testing.T) {
31+ for _, body := range []int{-1, 1, 262140} {
32+ b := NewBuf(0)
33+ p, s := b.Request(1, 0, body)
34+ if p != nil || s != 0 || b.Err() == nil || b.Len() != 0 {
35+ t.Fatal(body)
36+ }
37+ }
38+ b := NewBuf(0)
39+ b.next = 0xffff
40+ if p, s := b.Request(1, 0, 0); p != nil || s != 0 || b.Err() != ErrSeqOverflow {
41+ t.Fatal("overflow")
42+ }
43+ b = NewBuf(0)
44+ b.maxReq = 1 << 20
45+ p, s := b.Request(1, 0, 262140)
46+ if s != 1 || len(p) != 262140 || binary.LittleEndian.Uint16(b.Bytes()[2:]) != 0 || binary.LittleEndian.Uint32(b.Bytes()[4:]) != 65537 {
47+ t.Fatal("BIG-REQUESTS header")
48+ }
49+}
50+func TestAllocBufRequest(t *testing.T) {
51+ for _, body := range []int{4, 65536} {
52+ b := NewBuf(128 << 10)
53+ if n := testing.AllocsPerRun(1000, func() { b.Reset(); b.Request(1, 0, body) }); n != 0 {
54+ t.Fatal(n)
55+ }
56+ if b.Err() != nil {
57+ t.Fatal(b.Err())
58+ }
59+ }
60+}
61+func BenchmarkBufRequest(b *testing.B) {
62+ buf := NewBuf(0)
63+ b.ReportAllocs()
64+ for b.Loop() {
65+ buf.Reset()
66+ buf.acked = buf.next
67+ buf.Request(1, 0, 4)
68+ }
69+}
M cmd/xtgen/main.go +3 -0
@@ -29,6 +29,9 @@ func main() {
2929 if err == nil {
3030 err = emitTypes(modules)
3131 }
32+ if err == nil {
33+ err = emitRequests(modules)
34+ }
3235 if err != nil {
3336 fmt.Fprintln(os.Stderr, err)
3437 os.Exit(1)
@@ -29,6 +29,9 @@ func main() {
29 if err == nil {29 if err == nil {
30 err = emitTypes(modules)30 err = emitTypes(modules)
31 }31 }
32+ if err == nil {
33+ err = emitRequests(modules)
34+ }
32 if err != nil {35 if err != nil {
33 fmt.Fprintln(os.Stderr, err)36 fmt.Fprintln(os.Stderr, err)
34 os.Exit(1)37 os.Exit(1)
A cmd/xtgen/requests.go +182 -0
@@ -0,0 +1,182 @@
1+package main
2+
3+import (
4+ "fmt"
5+ "path/filepath"
6+ "strconv"
7+ "strings"
8+)
9+
10+type Request struct {
11+ Name string
12+ Opcode uint8
13+ DataByte *Field
14+ Fixed int
15+ Params, Fields []Field
16+ Node *Node
17+}
18+
19+// resolveRequests implements the fixed-body subset. Lists and value lists are
20+// deliberately left in the AST for T2.4/T2.5, not emitted as incomplete APIs.
21+func resolveRequests(m *Module) ([]Request, error) {
22+ var out []Request
23+ for _, n := range m.Root.Children {
24+ if n.Kind != "request" {
25+ continue
26+ }
27+ supported := true
28+ for _, f := range n.Children {
29+ if f.Kind == "list" || f.Kind == "switch" {
30+ supported = false
31+ }
32+ }
33+ if !supported {
34+ continue
35+ }
36+ name := goName(n.Attr["name"])
37+ if err := m.claim(name, n); err != nil {
38+ return nil, err
39+ }
40+ opcode, _ := strconv.Atoi(n.Attr["opcode"])
41+ r := Request{Name: name, Opcode: uint8(opcode), Node: n}
42+ off := 4
43+ first := true
44+ for _, n := range n.Children {
45+ if n.Kind == "reply" || n.Kind == "doc" {
46+ continue
47+ }
48+ f := Field{Name: goName(n.Attr["name"]), Param: paramName(n.Attr["name"]), Kind: n.Kind, Node: n, Off: off - 4}
49+ if n.Kind == "pad" {
50+ if n.Attr["align"] != "" {
51+ a, _ := strconv.Atoi(n.Attr["align"])
52+ f.Size = (-off) & (a - 1)
53+ } else {
54+ f.Size, _ = strconv.Atoi(n.Attr["bytes"])
55+ }
56+ } else {
57+ typ, err := lookup(m, n.Attr["type"])
58+ if err != nil {
59+ return nil, n.fail("%v", err)
60+ }
61+ if typ.Variable {
62+ return nil, n.fail("variable field requires list support")
63+ }
64+ f.Type = typ
65+ f.Size = typ.Size
66+ f.GoType = qualified(m, typ.Module, typ.GoType)
67+ if enum := n.Attr["enum"]; enum != "" {
68+ e, owner := findEnum(m, enum)
69+ if e == nil {
70+ return nil, n.fail("unknown enum %s", enum)
71+ }
72+ f.GoType = qualified(m, owner, e.Name)
73+ }
74+ if mask := n.Attr["mask"]; mask != "" {
75+ e, owner := findEnum(m, mask)
76+ if e == nil {
77+ return nil, n.fail("unknown mask %s", mask)
78+ }
79+ f.GoType = qualified(m, owner, e.Name)
80+ }
81+ if n.Kind == "field" {
82+ r.Params = append(r.Params, f)
83+ }
84+ if n.Kind == "exprfield" {
85+ f.Expr = n.Children[0]
86+ }
87+ }
88+ // Core's first XML byte is header byte 1; extensions have no data byte.
89+ if first && m.ExtName == "" {
90+ if f.Size != 1 {
91+ return nil, n.fail("core request first member must occupy header data byte")
92+ }
93+ if f.Kind != "pad" {
94+ copy := f
95+ r.DataByte = &copy
96+ }
97+ first = false
98+ continue
99+ }
100+ first = false
101+ r.Fields = append(r.Fields, f)
102+ off += f.Size
103+ }
104+ r.Fixed = (off - 4 + 3) &^ 3
105+ out = append(out, r)
106+ }
107+ return out, nil
108+}
109+func requestDecl(m *Module, r Request) (string, error) {
110+ var b strings.Builder
111+ fmt.Fprintf(&b, "func %s(b *xturbo.Buf", r.Name)
112+ for _, p := range r.Params {
113+ fmt.Fprintf(&b, ", %s %s", p.Param, p.GoType)
114+ }
115+ b.WriteString(") xturbo.Seq {\n")
116+ major := fmt.Sprint(r.Opcode)
117+ data := "0"
118+ if m.ExtName != "" {
119+ fmt.Fprintf(&b, "if b.Ext==nil { b.Fail(xturbo.ErrExtMissing); return 0 }; major:=b.Ext.Major(xturbo.Ext%s); if major==0 { b.Fail(xturbo.ErrExtMissing); return 0 };\n", m.ExtName)
120+ major = "major"
121+ data = fmt.Sprint(r.Opcode)
122+ } else if r.DataByte != nil {
123+ f := r.DataByte
124+ if f.Type.Base == "bool" {
125+ fmt.Fprintf(&b, "var data uint8; if %s { data=1 };", f.Param)
126+ data = "data"
127+ } else {
128+ data = "uint8(" + f.Param + ")"
129+ }
130+ }
131+ fmt.Fprintf(&b, "p,seq:=b.Request(%s,%s,%d); if p==nil { return 0 };\n", major, data, r.Fixed)
132+ for _, f := range r.Fields {
133+ if f.Kind == "pad" {
134+ continue
135+ }
136+ src := f.Param
137+ if f.Kind == "exprfield" {
138+ var err error
139+ src, err = renderExpr(f.Expr, func(s string) string { return "int(" + paramName(s) + ")" }, m)
140+ if err != nil {
141+ return "", err
142+ }
143+ }
144+ dst := fmt.Sprintf("p[%d:]", f.Off)
145+ if isScalar(f.Type) {
146+ b.WriteString(putScalar(f.Type, src, dst))
147+ } else {
148+ fmt.Fprintf(&b, "%s.Put(%s);", src, dst)
149+ }
150+ }
151+ b.WriteString("return seq }\n")
152+ return b.String(), nil
153+}
154+func emitRequests(modules []*Module) error {
155+ for _, m := range modules {
156+ requests, err := resolveRequests(m)
157+ if err != nil {
158+ return err
159+ }
160+ data := struct {
161+ Pkg string
162+ Decls []string
163+ }{Pkg: m.Pkg}
164+ for _, r := range requests {
165+ decl, err := requestDecl(m, r)
166+ if err != nil {
167+ return err
168+ }
169+ data.Decls = append(data.Decls, decl)
170+ }
171+ all := strings.Join(data.Decls, "\n")
172+ imp := importsFor(m, all)
173+ if len(requests) > 0 {
174+ imp += "\nimport \"bnema.dev/xturbo\""
175+ }
176+ data.Decls = append([]string{imp}, data.Decls...)
177+ if err := writeTemplate(filepath.Join(m.Pkg, "requests_generated.go"), "requests", data); err != nil {
178+ return err
179+ }
180+ }
181+ return nil
182+}
@@ -0,0 +1,182 @@
1+package main
2+
3+import (
4+ "fmt"
5+ "path/filepath"
6+ "strconv"
7+ "strings"
8+)
9+
10+type Request struct {
11+ Name string
12+ Opcode uint8
13+ DataByte *Field
14+ Fixed int
15+ Params, Fields []Field
16+ Node *Node
17+}
18+
19+// resolveRequests implements the fixed-body subset. Lists and value lists are
20+// deliberately left in the AST for T2.4/T2.5, not emitted as incomplete APIs.
21+func resolveRequests(m *Module) ([]Request, error) {
22+ var out []Request
23+ for _, n := range m.Root.Children {
24+ if n.Kind != "request" {
25+ continue
26+ }
27+ supported := true
28+ for _, f := range n.Children {
29+ if f.Kind == "list" || f.Kind == "switch" {
30+ supported = false
31+ }
32+ }
33+ if !supported {
34+ continue
35+ }
36+ name := goName(n.Attr["name"])
37+ if err := m.claim(name, n); err != nil {
38+ return nil, err
39+ }
40+ opcode, _ := strconv.Atoi(n.Attr["opcode"])
41+ r := Request{Name: name, Opcode: uint8(opcode), Node: n}
42+ off := 4
43+ first := true
44+ for _, n := range n.Children {
45+ if n.Kind == "reply" || n.Kind == "doc" {
46+ continue
47+ }
48+ f := Field{Name: goName(n.Attr["name"]), Param: paramName(n.Attr["name"]), Kind: n.Kind, Node: n, Off: off - 4}
49+ if n.Kind == "pad" {
50+ if n.Attr["align"] != "" {
51+ a, _ := strconv.Atoi(n.Attr["align"])
52+ f.Size = (-off) & (a - 1)
53+ } else {
54+ f.Size, _ = strconv.Atoi(n.Attr["bytes"])
55+ }
56+ } else {
57+ typ, err := lookup(m, n.Attr["type"])
58+ if err != nil {
59+ return nil, n.fail("%v", err)
60+ }
61+ if typ.Variable {
62+ return nil, n.fail("variable field requires list support")
63+ }
64+ f.Type = typ
65+ f.Size = typ.Size
66+ f.GoType = qualified(m, typ.Module, typ.GoType)
67+ if enum := n.Attr["enum"]; enum != "" {
68+ e, owner := findEnum(m, enum)
69+ if e == nil {
70+ return nil, n.fail("unknown enum %s", enum)
71+ }
72+ f.GoType = qualified(m, owner, e.Name)
73+ }
74+ if mask := n.Attr["mask"]; mask != "" {
75+ e, owner := findEnum(m, mask)
76+ if e == nil {
77+ return nil, n.fail("unknown mask %s", mask)
78+ }
79+ f.GoType = qualified(m, owner, e.Name)
80+ }
81+ if n.Kind == "field" {
82+ r.Params = append(r.Params, f)
83+ }
84+ if n.Kind == "exprfield" {
85+ f.Expr = n.Children[0]
86+ }
87+ }
88+ // Core's first XML byte is header byte 1; extensions have no data byte.
89+ if first && m.ExtName == "" {
90+ if f.Size != 1 {
91+ return nil, n.fail("core request first member must occupy header data byte")
92+ }
93+ if f.Kind != "pad" {
94+ copy := f
95+ r.DataByte = &copy
96+ }
97+ first = false
98+ continue
99+ }
100+ first = false
101+ r.Fields = append(r.Fields, f)
102+ off += f.Size
103+ }
104+ r.Fixed = (off - 4 + 3) &^ 3
105+ out = append(out, r)
106+ }
107+ return out, nil
108+}
109+func requestDecl(m *Module, r Request) (string, error) {
110+ var b strings.Builder
111+ fmt.Fprintf(&b, "func %s(b *xturbo.Buf", r.Name)
112+ for _, p := range r.Params {
113+ fmt.Fprintf(&b, ", %s %s", p.Param, p.GoType)
114+ }
115+ b.WriteString(") xturbo.Seq {\n")
116+ major := fmt.Sprint(r.Opcode)
117+ data := "0"
118+ if m.ExtName != "" {
119+ fmt.Fprintf(&b, "if b.Ext==nil { b.Fail(xturbo.ErrExtMissing); return 0 }; major:=b.Ext.Major(xturbo.Ext%s); if major==0 { b.Fail(xturbo.ErrExtMissing); return 0 };\n", m.ExtName)
120+ major = "major"
121+ data = fmt.Sprint(r.Opcode)
122+ } else if r.DataByte != nil {
123+ f := r.DataByte
124+ if f.Type.Base == "bool" {
125+ fmt.Fprintf(&b, "var data uint8; if %s { data=1 };", f.Param)
126+ data = "data"
127+ } else {
128+ data = "uint8(" + f.Param + ")"
129+ }
130+ }
131+ fmt.Fprintf(&b, "p,seq:=b.Request(%s,%s,%d); if p==nil { return 0 };\n", major, data, r.Fixed)
132+ for _, f := range r.Fields {
133+ if f.Kind == "pad" {
134+ continue
135+ }
136+ src := f.Param
137+ if f.Kind == "exprfield" {
138+ var err error
139+ src, err = renderExpr(f.Expr, func(s string) string { return "int(" + paramName(s) + ")" }, m)
140+ if err != nil {
141+ return "", err
142+ }
143+ }
144+ dst := fmt.Sprintf("p[%d:]", f.Off)
145+ if isScalar(f.Type) {
146+ b.WriteString(putScalar(f.Type, src, dst))
147+ } else {
148+ fmt.Fprintf(&b, "%s.Put(%s);", src, dst)
149+ }
150+ }
151+ b.WriteString("return seq }\n")
152+ return b.String(), nil
153+}
154+func emitRequests(modules []*Module) error {
155+ for _, m := range modules {
156+ requests, err := resolveRequests(m)
157+ if err != nil {
158+ return err
159+ }
160+ data := struct {
161+ Pkg string
162+ Decls []string
163+ }{Pkg: m.Pkg}
164+ for _, r := range requests {
165+ decl, err := requestDecl(m, r)
166+ if err != nil {
167+ return err
168+ }
169+ data.Decls = append(data.Decls, decl)
170+ }
171+ all := strings.Join(data.Decls, "\n")
172+ imp := importsFor(m, all)
173+ if len(requests) > 0 {
174+ imp += "\nimport \"bnema.dev/xturbo\""
175+ }
176+ data.Decls = append([]string{imp}, data.Decls...)
177+ if err := writeTemplate(filepath.Join(m.Pkg, "requests_generated.go"), "requests", data); err != nil {
178+ return err
179+ }
180+ }
181+ return nil
182+}
M cmd/xtgen/resolve_test.go +29 -0
@@ -101,3 +101,32 @@ func TestRenderExpr(t *testing.T) {
101101 t.Fatalf("%s %v", got, err)
102102 }
103103 }
104+
105+func TestFixedRequests(t *testing.T) {
106+ ms := testModules(t)
107+ for _, m := range ms {
108+ requests, err := resolveRequests(m)
109+ if err != nil {
110+ t.Fatal(err)
111+ }
112+ for _, r := range requests {
113+ decl, err := requestDecl(m, r)
114+ if err != nil {
115+ t.Fatal(err)
116+ }
117+ if !strings.Contains(decl, "if p==nil { return 0 }") {
118+ t.Fatal("missing sticky-error guard")
119+ }
120+ if m.Header == "xproto" && r.Name == "MapWindow" {
121+ if r.Fixed != 4 || len(r.Params) != 1 || r.Fields[0].Off != 0 {
122+ t.Fatal("MapWindow layout")
123+ }
124+ }
125+ if m.Header == "xfixes" && r.Name == "QueryVersion" {
126+ if r.Fixed != 8 || r.DataByte != nil || r.Fields[1].Off != 4 {
127+ t.Fatal("extension layout")
128+ }
129+ }
130+ }
131+ }
132+}
@@ -101,3 +101,32 @@ func TestRenderExpr(t *testing.T) {
101 t.Fatalf("%s %v", got, err)101 t.Fatalf("%s %v", got, err)
102 }102 }
103 }103 }
104+
105+func TestFixedRequests(t *testing.T) {
106+ ms := testModules(t)
107+ for _, m := range ms {
108+ requests, err := resolveRequests(m)
109+ if err != nil {
110+ t.Fatal(err)
111+ }
112+ for _, r := range requests {
113+ decl, err := requestDecl(m, r)
114+ if err != nil {
115+ t.Fatal(err)
116+ }
117+ if !strings.Contains(decl, "if p==nil { return 0 }") {
118+ t.Fatal("missing sticky-error guard")
119+ }
120+ if m.Header == "xproto" && r.Name == "MapWindow" {
121+ if r.Fixed != 4 || len(r.Params) != 1 || r.Fields[0].Off != 0 {
122+ t.Fatal("MapWindow layout")
123+ }
124+ }
125+ if m.Header == "xfixes" && r.Name == "QueryVersion" {
126+ if r.Fixed != 8 || r.DataByte != nil || r.Fields[1].Off != 4 {
127+ t.Fatal("extension layout")
128+ }
129+ }
130+ }
131+ }
132+}
A cmd/xtgen/templates/requests.tmpl +5 -0
@@ -0,0 +1,5 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package {{.Pkg}}
3+{{range .Decls}}
4+{{.}}
5+{{end}}
@@ -0,0 +1,5 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package {{.Pkg}}
3+{{range .Decls}}
4+{{.}}
5+{{end}}
A composite/requests_generated.go +176 -0
@@ -0,0 +1,176 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package composite
3+
4+import "bnema.dev/xturbo/xfixes"
5+import "bnema.dev/xturbo/xproto"
6+import "encoding/binary"
7+import "bnema.dev/xturbo"
8+
9+func QueryVersion(b *xturbo.Buf, clientMajorVersion uint32, clientMinorVersion uint32) xturbo.Seq {
10+ if b.Ext == nil {
11+ b.Fail(xturbo.ErrExtMissing)
12+ return 0
13+ }
14+ major := b.Ext.Major(xturbo.ExtComposite)
15+ if major == 0 {
16+ b.Fail(xturbo.ErrExtMissing)
17+ return 0
18+ }
19+ p, seq := b.Request(major, 0, 8)
20+ if p == nil {
21+ return 0
22+ }
23+ binary.LittleEndian.PutUint32(p[0:], uint32(clientMajorVersion))
24+ binary.LittleEndian.PutUint32(p[4:], uint32(clientMinorVersion))
25+ return seq
26+}
27+
28+func RedirectWindow(b *xturbo.Buf, window xproto.Window, update Redirect) xturbo.Seq {
29+ if b.Ext == nil {
30+ b.Fail(xturbo.ErrExtMissing)
31+ return 0
32+ }
33+ major := b.Ext.Major(xturbo.ExtComposite)
34+ if major == 0 {
35+ b.Fail(xturbo.ErrExtMissing)
36+ return 0
37+ }
38+ p, seq := b.Request(major, 1, 8)
39+ if p == nil {
40+ return 0
41+ }
42+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
43+ p[4:][0] = byte(update)
44+ return seq
45+}
46+
47+func RedirectSubwindows(b *xturbo.Buf, window xproto.Window, update Redirect) xturbo.Seq {
48+ if b.Ext == nil {
49+ b.Fail(xturbo.ErrExtMissing)
50+ return 0
51+ }
52+ major := b.Ext.Major(xturbo.ExtComposite)
53+ if major == 0 {
54+ b.Fail(xturbo.ErrExtMissing)
55+ return 0
56+ }
57+ p, seq := b.Request(major, 2, 8)
58+ if p == nil {
59+ return 0
60+ }
61+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
62+ p[4:][0] = byte(update)
63+ return seq
64+}
65+
66+func UnredirectWindow(b *xturbo.Buf, window xproto.Window, update Redirect) xturbo.Seq {
67+ if b.Ext == nil {
68+ b.Fail(xturbo.ErrExtMissing)
69+ return 0
70+ }
71+ major := b.Ext.Major(xturbo.ExtComposite)
72+ if major == 0 {
73+ b.Fail(xturbo.ErrExtMissing)
74+ return 0
75+ }
76+ p, seq := b.Request(major, 3, 8)
77+ if p == nil {
78+ return 0
79+ }
80+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
81+ p[4:][0] = byte(update)
82+ return seq
83+}
84+
85+func UnredirectSubwindows(b *xturbo.Buf, window xproto.Window, update Redirect) xturbo.Seq {
86+ if b.Ext == nil {
87+ b.Fail(xturbo.ErrExtMissing)
88+ return 0
89+ }
90+ major := b.Ext.Major(xturbo.ExtComposite)
91+ if major == 0 {
92+ b.Fail(xturbo.ErrExtMissing)
93+ return 0
94+ }
95+ p, seq := b.Request(major, 4, 8)
96+ if p == nil {
97+ return 0
98+ }
99+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
100+ p[4:][0] = byte(update)
101+ return seq
102+}
103+
104+func CreateRegionFromBorderClip(b *xturbo.Buf, region xfixes.Region, window xproto.Window) xturbo.Seq {
105+ if b.Ext == nil {
106+ b.Fail(xturbo.ErrExtMissing)
107+ return 0
108+ }
109+ major := b.Ext.Major(xturbo.ExtComposite)
110+ if major == 0 {
111+ b.Fail(xturbo.ErrExtMissing)
112+ return 0
113+ }
114+ p, seq := b.Request(major, 5, 8)
115+ if p == nil {
116+ return 0
117+ }
118+ binary.LittleEndian.PutUint32(p[0:], uint32(region))
119+ binary.LittleEndian.PutUint32(p[4:], uint32(window))
120+ return seq
121+}
122+
123+func NameWindowPixmap(b *xturbo.Buf, window xproto.Window, pixmap xproto.Pixmap) xturbo.Seq {
124+ if b.Ext == nil {
125+ b.Fail(xturbo.ErrExtMissing)
126+ return 0
127+ }
128+ major := b.Ext.Major(xturbo.ExtComposite)
129+ if major == 0 {
130+ b.Fail(xturbo.ErrExtMissing)
131+ return 0
132+ }
133+ p, seq := b.Request(major, 6, 8)
134+ if p == nil {
135+ return 0
136+ }
137+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
138+ binary.LittleEndian.PutUint32(p[4:], uint32(pixmap))
139+ return seq
140+}
141+
142+func GetOverlayWindow(b *xturbo.Buf, window xproto.Window) xturbo.Seq {
143+ if b.Ext == nil {
144+ b.Fail(xturbo.ErrExtMissing)
145+ return 0
146+ }
147+ major := b.Ext.Major(xturbo.ExtComposite)
148+ if major == 0 {
149+ b.Fail(xturbo.ErrExtMissing)
150+ return 0
151+ }
152+ p, seq := b.Request(major, 7, 4)
153+ if p == nil {
154+ return 0
155+ }
156+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
157+ return seq
158+}
159+
160+func ReleaseOverlayWindow(b *xturbo.Buf, window xproto.Window) xturbo.Seq {
161+ if b.Ext == nil {
162+ b.Fail(xturbo.ErrExtMissing)
163+ return 0
164+ }
165+ major := b.Ext.Major(xturbo.ExtComposite)
166+ if major == 0 {
167+ b.Fail(xturbo.ErrExtMissing)
168+ return 0
169+ }
170+ p, seq := b.Request(major, 8, 4)
171+ if p == nil {
172+ return 0
173+ }
174+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
175+ return seq
176+}
@@ -0,0 +1,176 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package composite
3+
4+import "bnema.dev/xturbo/xfixes"
5+import "bnema.dev/xturbo/xproto"
6+import "encoding/binary"
7+import "bnema.dev/xturbo"
8+
9+func QueryVersion(b *xturbo.Buf, clientMajorVersion uint32, clientMinorVersion uint32) xturbo.Seq {
10+ if b.Ext == nil {
11+ b.Fail(xturbo.ErrExtMissing)
12+ return 0
13+ }
14+ major := b.Ext.Major(xturbo.ExtComposite)
15+ if major == 0 {
16+ b.Fail(xturbo.ErrExtMissing)
17+ return 0
18+ }
19+ p, seq := b.Request(major, 0, 8)
20+ if p == nil {
21+ return 0
22+ }
23+ binary.LittleEndian.PutUint32(p[0:], uint32(clientMajorVersion))
24+ binary.LittleEndian.PutUint32(p[4:], uint32(clientMinorVersion))
25+ return seq
26+}
27+
28+func RedirectWindow(b *xturbo.Buf, window xproto.Window, update Redirect) xturbo.Seq {
29+ if b.Ext == nil {
30+ b.Fail(xturbo.ErrExtMissing)
31+ return 0
32+ }
33+ major := b.Ext.Major(xturbo.ExtComposite)
34+ if major == 0 {
35+ b.Fail(xturbo.ErrExtMissing)
36+ return 0
37+ }
38+ p, seq := b.Request(major, 1, 8)
39+ if p == nil {
40+ return 0
41+ }
42+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
43+ p[4:][0] = byte(update)
44+ return seq
45+}
46+
47+func RedirectSubwindows(b *xturbo.Buf, window xproto.Window, update Redirect) xturbo.Seq {
48+ if b.Ext == nil {
49+ b.Fail(xturbo.ErrExtMissing)
50+ return 0
51+ }
52+ major := b.Ext.Major(xturbo.ExtComposite)
53+ if major == 0 {
54+ b.Fail(xturbo.ErrExtMissing)
55+ return 0
56+ }
57+ p, seq := b.Request(major, 2, 8)
58+ if p == nil {
59+ return 0
60+ }
61+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
62+ p[4:][0] = byte(update)
63+ return seq
64+}
65+
66+func UnredirectWindow(b *xturbo.Buf, window xproto.Window, update Redirect) xturbo.Seq {
67+ if b.Ext == nil {
68+ b.Fail(xturbo.ErrExtMissing)
69+ return 0
70+ }
71+ major := b.Ext.Major(xturbo.ExtComposite)
72+ if major == 0 {
73+ b.Fail(xturbo.ErrExtMissing)
74+ return 0
75+ }
76+ p, seq := b.Request(major, 3, 8)
77+ if p == nil {
78+ return 0
79+ }
80+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
81+ p[4:][0] = byte(update)
82+ return seq
83+}
84+
85+func UnredirectSubwindows(b *xturbo.Buf, window xproto.Window, update Redirect) xturbo.Seq {
86+ if b.Ext == nil {
87+ b.Fail(xturbo.ErrExtMissing)
88+ return 0
89+ }
90+ major := b.Ext.Major(xturbo.ExtComposite)
91+ if major == 0 {
92+ b.Fail(xturbo.ErrExtMissing)
93+ return 0
94+ }
95+ p, seq := b.Request(major, 4, 8)
96+ if p == nil {
97+ return 0
98+ }
99+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
100+ p[4:][0] = byte(update)
101+ return seq
102+}
103+
104+func CreateRegionFromBorderClip(b *xturbo.Buf, region xfixes.Region, window xproto.Window) xturbo.Seq {
105+ if b.Ext == nil {
106+ b.Fail(xturbo.ErrExtMissing)
107+ return 0
108+ }
109+ major := b.Ext.Major(xturbo.ExtComposite)
110+ if major == 0 {
111+ b.Fail(xturbo.ErrExtMissing)
112+ return 0
113+ }
114+ p, seq := b.Request(major, 5, 8)
115+ if p == nil {
116+ return 0
117+ }
118+ binary.LittleEndian.PutUint32(p[0:], uint32(region))
119+ binary.LittleEndian.PutUint32(p[4:], uint32(window))
120+ return seq
121+}
122+
123+func NameWindowPixmap(b *xturbo.Buf, window xproto.Window, pixmap xproto.Pixmap) xturbo.Seq {
124+ if b.Ext == nil {
125+ b.Fail(xturbo.ErrExtMissing)
126+ return 0
127+ }
128+ major := b.Ext.Major(xturbo.ExtComposite)
129+ if major == 0 {
130+ b.Fail(xturbo.ErrExtMissing)
131+ return 0
132+ }
133+ p, seq := b.Request(major, 6, 8)
134+ if p == nil {
135+ return 0
136+ }
137+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
138+ binary.LittleEndian.PutUint32(p[4:], uint32(pixmap))
139+ return seq
140+}
141+
142+func GetOverlayWindow(b *xturbo.Buf, window xproto.Window) xturbo.Seq {
143+ if b.Ext == nil {
144+ b.Fail(xturbo.ErrExtMissing)
145+ return 0
146+ }
147+ major := b.Ext.Major(xturbo.ExtComposite)
148+ if major == 0 {
149+ b.Fail(xturbo.ErrExtMissing)
150+ return 0
151+ }
152+ p, seq := b.Request(major, 7, 4)
153+ if p == nil {
154+ return 0
155+ }
156+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
157+ return seq
158+}
159+
160+func ReleaseOverlayWindow(b *xturbo.Buf, window xproto.Window) xturbo.Seq {
161+ if b.Ext == nil {
162+ b.Fail(xturbo.ErrExtMissing)
163+ return 0
164+ }
165+ major := b.Ext.Major(xturbo.ExtComposite)
166+ if major == 0 {
167+ b.Fail(xturbo.ErrExtMissing)
168+ return 0
169+ }
170+ p, seq := b.Request(major, 8, 4)
171+ if p == nil {
172+ return 0
173+ }
174+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
175+ return seq
176+}
A ext.go +27 -0
@@ -0,0 +1,27 @@
1+package xturbo
2+
3+// ExtInfo is a negotiated extension's wire opcode and event/error bases.
4+type ExtInfo struct {
5+ Present bool
6+ Major, FirstEvent, FirstError uint8
7+}
8+
9+// ExtTable is populated during setup. Fixed arrays avoid lookup allocations.
10+// Reverse mapping is completed with the read-side runtime in Phase 3.
11+type ExtTable struct{ info [extCount]ExtInfo }
12+
13+func (t *ExtTable) Set(id ExtID, major, firstEvent, firstError uint8) {
14+ if id < extCount {
15+ t.info[id] = ExtInfo{true, major, firstEvent, firstError}
16+ }
17+}
18+func (t *ExtTable) Info(id ExtID) ExtInfo {
19+ if id >= extCount {
20+ return ExtInfo{}
21+ }
22+ if id == ExtCore {
23+ return ExtInfo{Present: true}
24+ }
25+ return t.info[id]
26+}
27+func (t *ExtTable) Major(id ExtID) uint8 { return t.Info(id).Major }
@@ -0,0 +1,27 @@
1+package xturbo
2+
3+// ExtInfo is a negotiated extension's wire opcode and event/error bases.
4+type ExtInfo struct {
5+ Present bool
6+ Major, FirstEvent, FirstError uint8
7+}
8+
9+// ExtTable is populated during setup. Fixed arrays avoid lookup allocations.
10+// Reverse mapping is completed with the read-side runtime in Phase 3.
11+type ExtTable struct{ info [extCount]ExtInfo }
12+
13+func (t *ExtTable) Set(id ExtID, major, firstEvent, firstError uint8) {
14+ if id < extCount {
15+ t.info[id] = ExtInfo{true, major, firstEvent, firstError}
16+ }
17+}
18+func (t *ExtTable) Info(id ExtID) ExtInfo {
19+ if id >= extCount {
20+ return ExtInfo{}
21+ }
22+ if id == ExtCore {
23+ return ExtInfo{Present: true}
24+ }
25+ return t.info[id]
26+}
27+func (t *ExtTable) Major(id ExtID) uint8 { return t.Info(id).Major }
A ge/requests_generated.go +24 -0
@@ -0,0 +1,24 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package ge
3+
4+import "encoding/binary"
5+import "bnema.dev/xturbo"
6+
7+func QueryVersion(b *xturbo.Buf, clientMajorVersion uint16, clientMinorVersion uint16) xturbo.Seq {
8+ if b.Ext == nil {
9+ b.Fail(xturbo.ErrExtMissing)
10+ return 0
11+ }
12+ major := b.Ext.Major(xturbo.ExtGenericEvent)
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+ binary.LittleEndian.PutUint16(p[0:], uint16(clientMajorVersion))
22+ binary.LittleEndian.PutUint16(p[2:], uint16(clientMinorVersion))
23+ return seq
24+}
@@ -0,0 +1,24 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package ge
3+
4+import "encoding/binary"
5+import "bnema.dev/xturbo"
6+
7+func QueryVersion(b *xturbo.Buf, clientMajorVersion uint16, clientMinorVersion uint16) xturbo.Seq {
8+ if b.Ext == nil {
9+ b.Fail(xturbo.ErrExtMissing)
10+ return 0
11+ }
12+ major := b.Ext.Major(xturbo.ExtGenericEvent)
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+ binary.LittleEndian.PutUint16(p[0:], uint16(clientMajorVersion))
22+ binary.LittleEndian.PutUint16(p[2:], uint16(clientMinorVersion))
23+ return seq
24+}
A internal/xtest/README.md +19 -0
@@ -0,0 +1,19 @@
1+# Wire goldens
2+
3+Refresh the T2.3 fixtures from the repository root:
4+
5+```
6+PATH="$PATH:/usr/sbin" go test -tags xserver ./internal/xtest -update
7+```
8+
9+The local `/usr/sbin/xtrace` is glibc's program execution tracer, not the X11
10+protocol proxy. The permitted fallback uses a raw Unix socketpair tee connected
11+to a fresh Xvfb server. A small independent reference encoder (not the generated
12+bindings) sends the requests; the tee records their actual bytes. GetGeometry's
13+successful response also establishes that the preceding MapWindow was accepted.
14+The captured target is the root window; XFIXES's major opcode is negotiated.
15+Tests read target/opcode from the fixture, not a hard-coded server assignment.
16+No runtime Conn is needed at this phase.
17+
18+T2.4 should extend the independent encoder and capture cases for list requests.
19+Replies, events and runtime integration belong to their subsequent tasks.
@@ -0,0 +1,19 @@
1+# Wire goldens
2+
3+Refresh the T2.3 fixtures from the repository root:
4+
5+```
6+PATH="$PATH:/usr/sbin" go test -tags xserver ./internal/xtest -update
7+```
8+
9+The local `/usr/sbin/xtrace` is glibc's program execution tracer, not the X11
10+protocol proxy. The permitted fallback uses a raw Unix socketpair tee connected
11+to a fresh Xvfb server. A small independent reference encoder (not the generated
12+bindings) sends the requests; the tee records their actual bytes. GetGeometry's
13+successful response also establishes that the preceding MapWindow was accepted.
14+The captured target is the root window; XFIXES's major opcode is negotiated.
15+Tests read target/opcode from the fixture, not a hard-coded server assignment.
16+No runtime Conn is needed at this phase.
17+
18+T2.4 should extend the independent encoder and capture cases for list requests.
19+Replies, events and runtime integration belong to their subsequent tasks.
A internal/xtest/capture_test.go +195 -0
@@ -0,0 +1,195 @@
1+//go:build xserver
2+
3+package xtest
4+
5+import (
6+ "bytes"
7+ "encoding/binary"
8+ "encoding/hex"
9+ "flag"
10+ "fmt"
11+ "io"
12+ "net"
13+ "os"
14+ "os/exec"
15+ "path/filepath"
16+ "strconv"
17+ "strings"
18+ "testing"
19+ "time"
20+
21+ "golang.org/x/sys/unix"
22+)
23+
24+var update = flag.Bool("update", false, "refresh request goldens using Xvfb and a raw socketpair tee")
25+
26+func TestCaptureRequests(t *testing.T) {
27+ if !*update {
28+ t.Skip("pass -update to capture request goldens")
29+ }
30+ // displayfd avoids display-number races and tells us when Xvfb is ready.
31+ r, w, err := os.Pipe()
32+ if err != nil {
33+ t.Fatal(err)
34+ }
35+ defer r.Close()
36+ cmd := exec.Command("Xvfb", "-displayfd", "3", "-screen", "0", "800x600x24", "-nolisten", "tcp", "-ac")
37+ cmd.ExtraFiles = []*os.File{w}
38+ var log bytes.Buffer
39+ cmd.Stderr = &log
40+ if err = cmd.Start(); err != nil {
41+ w.Close()
42+ t.Fatal(err)
43+ }
44+ w.Close()
45+ defer func() { _ = cmd.Process.Kill(); _ = cmd.Wait() }()
46+ _ = r.SetReadDeadline(time.Now().Add(5 * time.Second))
47+ var display [32]byte
48+ n, err := r.Read(display[:])
49+ if err != nil {
50+ t.Fatalf("Xvfb: %v: %s", err, log.String())
51+ }
52+ num, err := strconv.Atoi(strings.TrimSpace(string(display[:n])))
53+ if err != nil {
54+ t.Fatal(err)
55+ }
56+ server, err := net.DialTimeout("unix", fmt.Sprintf("/tmp/.X11-unix/X%d", num), 5*time.Second)
57+ if err != nil {
58+ t.Fatal(err)
59+ }
60+ defer server.Close()
61+ fds, err := unix.Socketpair(unix.AF_UNIX, unix.SOCK_STREAM|unix.SOCK_CLOEXEC, 0)
62+ if err != nil {
63+ t.Fatal(err)
64+ }
65+ a := os.NewFile(uintptr(fds[0]), "capture-client")
66+ b := os.NewFile(uintptr(fds[1]), "capture-tee")
67+ client, err := net.FileConn(a)
68+ a.Close()
69+ if err != nil {
70+ b.Close()
71+ t.Fatal(err)
72+ }
73+ defer client.Close()
74+ tee, err := net.FileConn(b)
75+ b.Close()
76+ if err != nil {
77+ t.Fatal(err)
78+ }
79+ defer tee.Close()
80+ _ = client.SetDeadline(time.Now().Add(5 * time.Second))
81+ _ = server.SetDeadline(time.Now().Add(5 * time.Second))
82+ var recorded bytes.Buffer
83+ copied := make(chan error, 1)
84+ go func() { _, err := io.Copy(server, io.TeeReader(tee, &recorded)); copied <- err }()
85+ go func() { _, _ = io.Copy(tee, server) }()
86+ write := func(p []byte) {
87+ t.Helper()
88+ if _, err := client.Write(p); err != nil {
89+ t.Fatal(err)
90+ }
91+ }
92+ read := func(p []byte) {
93+ t.Helper()
94+ if _, err := io.ReadFull(client, p); err != nil {
95+ t.Fatal(err)
96+ }
97+ }
98+ // Independent reference encoder: no generated bindings participate in capture.
99+ write([]byte{'l', 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0})
100+ var setupHead [8]byte
101+ read(setupHead[:])
102+ if setupHead[0] != 1 {
103+ t.Fatalf("setup failed: %x", setupHead)
104+ }
105+ setup := make([]byte, int(binary.LittleEndian.Uint16(setupHead[6:]))*4)
106+ read(setup)
107+ vendorLen := int(binary.LittleEndian.Uint16(setup[16:]))
108+ formats := int(setup[21])
109+ screenOff := 32 + (vendorLen+3)&^3 + 8*formats
110+ root := binary.LittleEndian.Uint32(setup[screenOff:])
111+ // Query XFIXES dynamically rather than assuming a server-specific major opcode.
112+ query := []byte{98, 0, 4, 0, 6, 0, 0, 0, 'X', 'F', 'I', 'X', 'E', 'S', 0, 0}
113+ write(query)
114+ packet := func() []byte {
115+ t.Helper()
116+ head := make([]byte, 32)
117+ read(head)
118+ if head[0] == 1 {
119+ tail := make([]byte, int(binary.LittleEndian.Uint32(head[4:]))*4)
120+ read(tail)
121+ head = append(head, tail...)
122+ }
123+ return head
124+ }
125+ ext := packet()
126+ if ext[0] != 1 || ext[8] != 1 {
127+ t.Fatalf("XFIXES unavailable: %x", ext)
128+ }
129+ major := ext[9]
130+ version := make([]byte, 12)
131+ version[0] = major
132+ version[2] = 3
133+ binary.LittleEndian.PutUint32(version[4:], 6)
134+ write(version)
135+ reply := packet()
136+ if reply[0] != 1 {
137+ t.Fatalf("QueryVersion failed: %x", reply)
138+ }
139+ mapReq := make([]byte, 8)
140+ mapReq[0] = 8
141+ mapReq[2] = 2
142+ binary.LittleEndian.PutUint32(mapReq[4:], root)
143+ write(mapReq)
144+ geometry := append([]byte(nil), mapReq...)
145+ geometry[0] = 14
146+ write(geometry)
147+ geom := packet()
148+ if geom[0] != 1 || binary.LittleEndian.Uint16(geom[2:]) != 4 {
149+ t.Fatalf("MapWindow/GetGeometry rejected: %x", geom)
150+ }
151+ // Closing the client drains the request direction; wait before inspecting tee.
152+ client.Close()
153+ select {
154+ case err := <-copied:
155+ if err != nil {
156+ t.Fatal(err)
157+ }
158+ case <-time.After(5 * time.Second):
159+ t.Fatal("tee did not drain")
160+ }
161+ stream := recorded.Bytes()
162+ requests := stream[12:]
163+ captured := map[string][]byte{}
164+ for len(requests) > 0 {
165+ size := int(binary.LittleEndian.Uint16(requests[2:])) * 4
166+ if size < 4 || size > len(requests) {
167+ t.Fatal("malformed capture")
168+ }
169+ p := requests[:size]
170+ switch p[0] {
171+ case 8:
172+ captured["xproto/MapWindow"] = p
173+ case 14:
174+ captured["xproto/GetGeometry"] = p
175+ default:
176+ if p[0] == major {
177+ captured["xfixes/QueryVersion"] = p
178+ }
179+ }
180+ requests = requests[size:]
181+ }
182+ if len(captured) != 3 {
183+ t.Fatal("missing captured requests")
184+ }
185+ for name, p := range captured {
186+ path := filepath.Join("../../testdata/golden", name+".req.hex")
187+ if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
188+ t.Fatal(err)
189+ }
190+ text := "# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted\n# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace\n" + hex.EncodeToString(p) + "\n"
191+ if err := os.WriteFile(path, []byte(text), 0644); err != nil {
192+ t.Fatal(err)
193+ }
194+ }
195+}
@@ -0,0 +1,195 @@
1+//go:build xserver
2+
3+package xtest
4+
5+import (
6+ "bytes"
7+ "encoding/binary"
8+ "encoding/hex"
9+ "flag"
10+ "fmt"
11+ "io"
12+ "net"
13+ "os"
14+ "os/exec"
15+ "path/filepath"
16+ "strconv"
17+ "strings"
18+ "testing"
19+ "time"
20+
21+ "golang.org/x/sys/unix"
22+)
23+
24+var update = flag.Bool("update", false, "refresh request goldens using Xvfb and a raw socketpair tee")
25+
26+func TestCaptureRequests(t *testing.T) {
27+ if !*update {
28+ t.Skip("pass -update to capture request goldens")
29+ }
30+ // displayfd avoids display-number races and tells us when Xvfb is ready.
31+ r, w, err := os.Pipe()
32+ if err != nil {
33+ t.Fatal(err)
34+ }
35+ defer r.Close()
36+ cmd := exec.Command("Xvfb", "-displayfd", "3", "-screen", "0", "800x600x24", "-nolisten", "tcp", "-ac")
37+ cmd.ExtraFiles = []*os.File{w}
38+ var log bytes.Buffer
39+ cmd.Stderr = &log
40+ if err = cmd.Start(); err != nil {
41+ w.Close()
42+ t.Fatal(err)
43+ }
44+ w.Close()
45+ defer func() { _ = cmd.Process.Kill(); _ = cmd.Wait() }()
46+ _ = r.SetReadDeadline(time.Now().Add(5 * time.Second))
47+ var display [32]byte
48+ n, err := r.Read(display[:])
49+ if err != nil {
50+ t.Fatalf("Xvfb: %v: %s", err, log.String())
51+ }
52+ num, err := strconv.Atoi(strings.TrimSpace(string(display[:n])))
53+ if err != nil {
54+ t.Fatal(err)
55+ }
56+ server, err := net.DialTimeout("unix", fmt.Sprintf("/tmp/.X11-unix/X%d", num), 5*time.Second)
57+ if err != nil {
58+ t.Fatal(err)
59+ }
60+ defer server.Close()
61+ fds, err := unix.Socketpair(unix.AF_UNIX, unix.SOCK_STREAM|unix.SOCK_CLOEXEC, 0)
62+ if err != nil {
63+ t.Fatal(err)
64+ }
65+ a := os.NewFile(uintptr(fds[0]), "capture-client")
66+ b := os.NewFile(uintptr(fds[1]), "capture-tee")
67+ client, err := net.FileConn(a)
68+ a.Close()
69+ if err != nil {
70+ b.Close()
71+ t.Fatal(err)
72+ }
73+ defer client.Close()
74+ tee, err := net.FileConn(b)
75+ b.Close()
76+ if err != nil {
77+ t.Fatal(err)
78+ }
79+ defer tee.Close()
80+ _ = client.SetDeadline(time.Now().Add(5 * time.Second))
81+ _ = server.SetDeadline(time.Now().Add(5 * time.Second))
82+ var recorded bytes.Buffer
83+ copied := make(chan error, 1)
84+ go func() { _, err := io.Copy(server, io.TeeReader(tee, &recorded)); copied <- err }()
85+ go func() { _, _ = io.Copy(tee, server) }()
86+ write := func(p []byte) {
87+ t.Helper()
88+ if _, err := client.Write(p); err != nil {
89+ t.Fatal(err)
90+ }
91+ }
92+ read := func(p []byte) {
93+ t.Helper()
94+ if _, err := io.ReadFull(client, p); err != nil {
95+ t.Fatal(err)
96+ }
97+ }
98+ // Independent reference encoder: no generated bindings participate in capture.
99+ write([]byte{'l', 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0})
100+ var setupHead [8]byte
101+ read(setupHead[:])
102+ if setupHead[0] != 1 {
103+ t.Fatalf("setup failed: %x", setupHead)
104+ }
105+ setup := make([]byte, int(binary.LittleEndian.Uint16(setupHead[6:]))*4)
106+ read(setup)
107+ vendorLen := int(binary.LittleEndian.Uint16(setup[16:]))
108+ formats := int(setup[21])
109+ screenOff := 32 + (vendorLen+3)&^3 + 8*formats
110+ root := binary.LittleEndian.Uint32(setup[screenOff:])
111+ // Query XFIXES dynamically rather than assuming a server-specific major opcode.
112+ query := []byte{98, 0, 4, 0, 6, 0, 0, 0, 'X', 'F', 'I', 'X', 'E', 'S', 0, 0}
113+ write(query)
114+ packet := func() []byte {
115+ t.Helper()
116+ head := make([]byte, 32)
117+ read(head)
118+ if head[0] == 1 {
119+ tail := make([]byte, int(binary.LittleEndian.Uint32(head[4:]))*4)
120+ read(tail)
121+ head = append(head, tail...)
122+ }
123+ return head
124+ }
125+ ext := packet()
126+ if ext[0] != 1 || ext[8] != 1 {
127+ t.Fatalf("XFIXES unavailable: %x", ext)
128+ }
129+ major := ext[9]
130+ version := make([]byte, 12)
131+ version[0] = major
132+ version[2] = 3
133+ binary.LittleEndian.PutUint32(version[4:], 6)
134+ write(version)
135+ reply := packet()
136+ if reply[0] != 1 {
137+ t.Fatalf("QueryVersion failed: %x", reply)
138+ }
139+ mapReq := make([]byte, 8)
140+ mapReq[0] = 8
141+ mapReq[2] = 2
142+ binary.LittleEndian.PutUint32(mapReq[4:], root)
143+ write(mapReq)
144+ geometry := append([]byte(nil), mapReq...)
145+ geometry[0] = 14
146+ write(geometry)
147+ geom := packet()
148+ if geom[0] != 1 || binary.LittleEndian.Uint16(geom[2:]) != 4 {
149+ t.Fatalf("MapWindow/GetGeometry rejected: %x", geom)
150+ }
151+ // Closing the client drains the request direction; wait before inspecting tee.
152+ client.Close()
153+ select {
154+ case err := <-copied:
155+ if err != nil {
156+ t.Fatal(err)
157+ }
158+ case <-time.After(5 * time.Second):
159+ t.Fatal("tee did not drain")
160+ }
161+ stream := recorded.Bytes()
162+ requests := stream[12:]
163+ captured := map[string][]byte{}
164+ for len(requests) > 0 {
165+ size := int(binary.LittleEndian.Uint16(requests[2:])) * 4
166+ if size < 4 || size > len(requests) {
167+ t.Fatal("malformed capture")
168+ }
169+ p := requests[:size]
170+ switch p[0] {
171+ case 8:
172+ captured["xproto/MapWindow"] = p
173+ case 14:
174+ captured["xproto/GetGeometry"] = p
175+ default:
176+ if p[0] == major {
177+ captured["xfixes/QueryVersion"] = p
178+ }
179+ }
180+ requests = requests[size:]
181+ }
182+ if len(captured) != 3 {
183+ t.Fatal("missing captured requests")
184+ }
185+ for name, p := range captured {
186+ path := filepath.Join("../../testdata/golden", name+".req.hex")
187+ if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
188+ t.Fatal(err)
189+ }
190+ text := "# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted\n# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace\n" + hex.EncodeToString(p) + "\n"
191+ if err := os.WriteFile(path, []byte(text), 0644); err != nil {
192+ t.Fatal(err)
193+ }
194+ }
195+}
A internal/xtest/golden.go +22 -0
@@ -0,0 +1,22 @@
1+// Package xtest provides wire fixtures shared by binding tests.
2+package xtest
3+
4+import (
5+ "encoding/hex"
6+ "os"
7+ "strings"
8+)
9+
10+// LoadHex reads whitespace-separated hex with optional # comments.
11+func LoadHex(path string) ([]byte, error) {
12+ b, err := os.ReadFile(path)
13+ if err != nil {
14+ return nil, err
15+ }
16+ var text strings.Builder
17+ for line := range strings.SplitSeq(string(b), "\n") {
18+ line, _, _ = strings.Cut(line, "#")
19+ text.WriteString(strings.Join(strings.Fields(line), ""))
20+ }
21+ return hex.DecodeString(text.String())
22+}
@@ -0,0 +1,22 @@
1+// Package xtest provides wire fixtures shared by binding tests.
2+package xtest
3+
4+import (
5+ "encoding/hex"
6+ "os"
7+ "strings"
8+)
9+
10+// LoadHex reads whitespace-separated hex with optional # comments.
11+func LoadHex(path string) ([]byte, error) {
12+ b, err := os.ReadFile(path)
13+ if err != nil {
14+ return nil, err
15+ }
16+ var text strings.Builder
17+ for line := range strings.SplitSeq(string(b), "\n") {
18+ line, _, _ = strings.Cut(line, "#")
19+ text.WriteString(strings.Join(strings.Fields(line), ""))
20+ }
21+ return hex.DecodeString(text.String())
22+}
A render/requests_generated.go +240 -0
@@ -0,0 +1,240 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package render
3+
4+import "bnema.dev/xturbo/xproto"
5+import "encoding/binary"
6+import "bnema.dev/xturbo"
7+
8+func QueryVersion(b *xturbo.Buf, clientMajorVersion uint32, clientMinorVersion uint32) xturbo.Seq {
9+ if b.Ext == nil {
10+ b.Fail(xturbo.ErrExtMissing)
11+ return 0
12+ }
13+ major := b.Ext.Major(xturbo.ExtRender)
14+ if major == 0 {
15+ b.Fail(xturbo.ErrExtMissing)
16+ return 0
17+ }
18+ p, seq := b.Request(major, 0, 8)
19+ if p == nil {
20+ return 0
21+ }
22+ binary.LittleEndian.PutUint32(p[0:], uint32(clientMajorVersion))
23+ binary.LittleEndian.PutUint32(p[4:], uint32(clientMinorVersion))
24+ return seq
25+}
26+
27+func QueryPictFormats(b *xturbo.Buf) xturbo.Seq {
28+ if b.Ext == nil {
29+ b.Fail(xturbo.ErrExtMissing)
30+ return 0
31+ }
32+ major := b.Ext.Major(xturbo.ExtRender)
33+ if major == 0 {
34+ b.Fail(xturbo.ErrExtMissing)
35+ return 0
36+ }
37+ p, seq := b.Request(major, 1, 0)
38+ if p == nil {
39+ return 0
40+ }
41+ return seq
42+}
43+
44+func QueryPictIndexValues(b *xturbo.Buf, format Pictformat) xturbo.Seq {
45+ if b.Ext == nil {
46+ b.Fail(xturbo.ErrExtMissing)
47+ return 0
48+ }
49+ major := b.Ext.Major(xturbo.ExtRender)
50+ if major == 0 {
51+ b.Fail(xturbo.ErrExtMissing)
52+ return 0
53+ }
54+ p, seq := b.Request(major, 2, 4)
55+ if p == nil {
56+ return 0
57+ }
58+ binary.LittleEndian.PutUint32(p[0:], uint32(format))
59+ return seq
60+}
61+
62+func FreePicture(b *xturbo.Buf, picture Picture) xturbo.Seq {
63+ if b.Ext == nil {
64+ b.Fail(xturbo.ErrExtMissing)
65+ return 0
66+ }
67+ major := b.Ext.Major(xturbo.ExtRender)
68+ if major == 0 {
69+ b.Fail(xturbo.ErrExtMissing)
70+ return 0
71+ }
72+ p, seq := b.Request(major, 7, 4)
73+ if p == nil {
74+ return 0
75+ }
76+ binary.LittleEndian.PutUint32(p[0:], uint32(picture))
77+ return seq
78+}
79+
80+func Composite(b *xturbo.Buf, op PictOp, src Picture, mask Picture, dst Picture, srcX int16, srcY int16, maskX int16, maskY int16, dstX int16, dstY int16, width uint16, height uint16) xturbo.Seq {
81+ if b.Ext == nil {
82+ b.Fail(xturbo.ErrExtMissing)
83+ return 0
84+ }
85+ major := b.Ext.Major(xturbo.ExtRender)
86+ if major == 0 {
87+ b.Fail(xturbo.ErrExtMissing)
88+ return 0
89+ }
90+ p, seq := b.Request(major, 8, 32)
91+ if p == nil {
92+ return 0
93+ }
94+ p[0:][0] = byte(op)
95+ binary.LittleEndian.PutUint32(p[4:], uint32(src))
96+ binary.LittleEndian.PutUint32(p[8:], uint32(mask))
97+ binary.LittleEndian.PutUint32(p[12:], uint32(dst))
98+ binary.LittleEndian.PutUint16(p[16:], uint16(srcX))
99+ binary.LittleEndian.PutUint16(p[18:], uint16(srcY))
100+ binary.LittleEndian.PutUint16(p[20:], uint16(maskX))
101+ binary.LittleEndian.PutUint16(p[22:], uint16(maskY))
102+ binary.LittleEndian.PutUint16(p[24:], uint16(dstX))
103+ binary.LittleEndian.PutUint16(p[26:], uint16(dstY))
104+ binary.LittleEndian.PutUint16(p[28:], uint16(width))
105+ binary.LittleEndian.PutUint16(p[30:], uint16(height))
106+ return seq
107+}
108+
109+func CreateGlyphSet(b *xturbo.Buf, gsid Glyphset, format Pictformat) xturbo.Seq {
110+ if b.Ext == nil {
111+ b.Fail(xturbo.ErrExtMissing)
112+ return 0
113+ }
114+ major := b.Ext.Major(xturbo.ExtRender)
115+ if major == 0 {
116+ b.Fail(xturbo.ErrExtMissing)
117+ return 0
118+ }
119+ p, seq := b.Request(major, 17, 8)
120+ if p == nil {
121+ return 0
122+ }
123+ binary.LittleEndian.PutUint32(p[0:], uint32(gsid))
124+ binary.LittleEndian.PutUint32(p[4:], uint32(format))
125+ return seq
126+}
127+
128+func ReferenceGlyphSet(b *xturbo.Buf, gsid Glyphset, existing Glyphset) xturbo.Seq {
129+ if b.Ext == nil {
130+ b.Fail(xturbo.ErrExtMissing)
131+ return 0
132+ }
133+ major := b.Ext.Major(xturbo.ExtRender)
134+ if major == 0 {
135+ b.Fail(xturbo.ErrExtMissing)
136+ return 0
137+ }
138+ p, seq := b.Request(major, 18, 8)
139+ if p == nil {
140+ return 0
141+ }
142+ binary.LittleEndian.PutUint32(p[0:], uint32(gsid))
143+ binary.LittleEndian.PutUint32(p[4:], uint32(existing))
144+ return seq
145+}
146+
147+func FreeGlyphSet(b *xturbo.Buf, glyphset Glyphset) xturbo.Seq {
148+ if b.Ext == nil {
149+ b.Fail(xturbo.ErrExtMissing)
150+ return 0
151+ }
152+ major := b.Ext.Major(xturbo.ExtRender)
153+ if major == 0 {
154+ b.Fail(xturbo.ErrExtMissing)
155+ return 0
156+ }
157+ p, seq := b.Request(major, 19, 4)
158+ if p == nil {
159+ return 0
160+ }
161+ binary.LittleEndian.PutUint32(p[0:], uint32(glyphset))
162+ return seq
163+}
164+
165+func CreateCursor(b *xturbo.Buf, cid xproto.Cursor, source Picture, x uint16, y uint16) xturbo.Seq {
166+ if b.Ext == nil {
167+ b.Fail(xturbo.ErrExtMissing)
168+ return 0
169+ }
170+ major := b.Ext.Major(xturbo.ExtRender)
171+ if major == 0 {
172+ b.Fail(xturbo.ErrExtMissing)
173+ return 0
174+ }
175+ p, seq := b.Request(major, 27, 12)
176+ if p == nil {
177+ return 0
178+ }
179+ binary.LittleEndian.PutUint32(p[0:], uint32(cid))
180+ binary.LittleEndian.PutUint32(p[4:], uint32(source))
181+ binary.LittleEndian.PutUint16(p[8:], uint16(x))
182+ binary.LittleEndian.PutUint16(p[10:], uint16(y))
183+ return seq
184+}
185+
186+func SetPictureTransform(b *xturbo.Buf, picture Picture, transform Transform) xturbo.Seq {
187+ if b.Ext == nil {
188+ b.Fail(xturbo.ErrExtMissing)
189+ return 0
190+ }
191+ major := b.Ext.Major(xturbo.ExtRender)
192+ if major == 0 {
193+ b.Fail(xturbo.ErrExtMissing)
194+ return 0
195+ }
196+ p, seq := b.Request(major, 28, 40)
197+ if p == nil {
198+ return 0
199+ }
200+ binary.LittleEndian.PutUint32(p[0:], uint32(picture))
201+ transform.Put(p[4:])
202+ return seq
203+}
204+
205+func QueryFilters(b *xturbo.Buf, drawable xproto.Drawable) xturbo.Seq {
206+ if b.Ext == nil {
207+ b.Fail(xturbo.ErrExtMissing)
208+ return 0
209+ }
210+ major := b.Ext.Major(xturbo.ExtRender)
211+ if major == 0 {
212+ b.Fail(xturbo.ErrExtMissing)
213+ return 0
214+ }
215+ p, seq := b.Request(major, 29, 4)
216+ if p == nil {
217+ return 0
218+ }
219+ binary.LittleEndian.PutUint32(p[0:], uint32(drawable))
220+ return seq
221+}
222+
223+func CreateSolidFill(b *xturbo.Buf, picture Picture, color Color) xturbo.Seq {
224+ if b.Ext == nil {
225+ b.Fail(xturbo.ErrExtMissing)
226+ return 0
227+ }
228+ major := b.Ext.Major(xturbo.ExtRender)
229+ if major == 0 {
230+ b.Fail(xturbo.ErrExtMissing)
231+ return 0
232+ }
233+ p, seq := b.Request(major, 33, 12)
234+ if p == nil {
235+ return 0
236+ }
237+ binary.LittleEndian.PutUint32(p[0:], uint32(picture))
238+ color.Put(p[4:])
239+ return seq
240+}
@@ -0,0 +1,240 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package render
3+
4+import "bnema.dev/xturbo/xproto"
5+import "encoding/binary"
6+import "bnema.dev/xturbo"
7+
8+func QueryVersion(b *xturbo.Buf, clientMajorVersion uint32, clientMinorVersion uint32) xturbo.Seq {
9+ if b.Ext == nil {
10+ b.Fail(xturbo.ErrExtMissing)
11+ return 0
12+ }
13+ major := b.Ext.Major(xturbo.ExtRender)
14+ if major == 0 {
15+ b.Fail(xturbo.ErrExtMissing)
16+ return 0
17+ }
18+ p, seq := b.Request(major, 0, 8)
19+ if p == nil {
20+ return 0
21+ }
22+ binary.LittleEndian.PutUint32(p[0:], uint32(clientMajorVersion))
23+ binary.LittleEndian.PutUint32(p[4:], uint32(clientMinorVersion))
24+ return seq
25+}
26+
27+func QueryPictFormats(b *xturbo.Buf) xturbo.Seq {
28+ if b.Ext == nil {
29+ b.Fail(xturbo.ErrExtMissing)
30+ return 0
31+ }
32+ major := b.Ext.Major(xturbo.ExtRender)
33+ if major == 0 {
34+ b.Fail(xturbo.ErrExtMissing)
35+ return 0
36+ }
37+ p, seq := b.Request(major, 1, 0)
38+ if p == nil {
39+ return 0
40+ }
41+ return seq
42+}
43+
44+func QueryPictIndexValues(b *xturbo.Buf, format Pictformat) xturbo.Seq {
45+ if b.Ext == nil {
46+ b.Fail(xturbo.ErrExtMissing)
47+ return 0
48+ }
49+ major := b.Ext.Major(xturbo.ExtRender)
50+ if major == 0 {
51+ b.Fail(xturbo.ErrExtMissing)
52+ return 0
53+ }
54+ p, seq := b.Request(major, 2, 4)
55+ if p == nil {
56+ return 0
57+ }
58+ binary.LittleEndian.PutUint32(p[0:], uint32(format))
59+ return seq
60+}
61+
62+func FreePicture(b *xturbo.Buf, picture Picture) xturbo.Seq {
63+ if b.Ext == nil {
64+ b.Fail(xturbo.ErrExtMissing)
65+ return 0
66+ }
67+ major := b.Ext.Major(xturbo.ExtRender)
68+ if major == 0 {
69+ b.Fail(xturbo.ErrExtMissing)
70+ return 0
71+ }
72+ p, seq := b.Request(major, 7, 4)
73+ if p == nil {
74+ return 0
75+ }
76+ binary.LittleEndian.PutUint32(p[0:], uint32(picture))
77+ return seq
78+}
79+
80+func Composite(b *xturbo.Buf, op PictOp, src Picture, mask Picture, dst Picture, srcX int16, srcY int16, maskX int16, maskY int16, dstX int16, dstY int16, width uint16, height uint16) xturbo.Seq {
81+ if b.Ext == nil {
82+ b.Fail(xturbo.ErrExtMissing)
83+ return 0
84+ }
85+ major := b.Ext.Major(xturbo.ExtRender)
86+ if major == 0 {
87+ b.Fail(xturbo.ErrExtMissing)
88+ return 0
89+ }
90+ p, seq := b.Request(major, 8, 32)
91+ if p == nil {
92+ return 0
93+ }
94+ p[0:][0] = byte(op)
95+ binary.LittleEndian.PutUint32(p[4:], uint32(src))
96+ binary.LittleEndian.PutUint32(p[8:], uint32(mask))
97+ binary.LittleEndian.PutUint32(p[12:], uint32(dst))
98+ binary.LittleEndian.PutUint16(p[16:], uint16(srcX))
99+ binary.LittleEndian.PutUint16(p[18:], uint16(srcY))
100+ binary.LittleEndian.PutUint16(p[20:], uint16(maskX))
101+ binary.LittleEndian.PutUint16(p[22:], uint16(maskY))
102+ binary.LittleEndian.PutUint16(p[24:], uint16(dstX))
103+ binary.LittleEndian.PutUint16(p[26:], uint16(dstY))
104+ binary.LittleEndian.PutUint16(p[28:], uint16(width))
105+ binary.LittleEndian.PutUint16(p[30:], uint16(height))
106+ return seq
107+}
108+
109+func CreateGlyphSet(b *xturbo.Buf, gsid Glyphset, format Pictformat) xturbo.Seq {
110+ if b.Ext == nil {
111+ b.Fail(xturbo.ErrExtMissing)
112+ return 0
113+ }
114+ major := b.Ext.Major(xturbo.ExtRender)
115+ if major == 0 {
116+ b.Fail(xturbo.ErrExtMissing)
117+ return 0
118+ }
119+ p, seq := b.Request(major, 17, 8)
120+ if p == nil {
121+ return 0
122+ }
123+ binary.LittleEndian.PutUint32(p[0:], uint32(gsid))
124+ binary.LittleEndian.PutUint32(p[4:], uint32(format))
125+ return seq
126+}
127+
128+func ReferenceGlyphSet(b *xturbo.Buf, gsid Glyphset, existing Glyphset) xturbo.Seq {
129+ if b.Ext == nil {
130+ b.Fail(xturbo.ErrExtMissing)
131+ return 0
132+ }
133+ major := b.Ext.Major(xturbo.ExtRender)
134+ if major == 0 {
135+ b.Fail(xturbo.ErrExtMissing)
136+ return 0
137+ }
138+ p, seq := b.Request(major, 18, 8)
139+ if p == nil {
140+ return 0
141+ }
142+ binary.LittleEndian.PutUint32(p[0:], uint32(gsid))
143+ binary.LittleEndian.PutUint32(p[4:], uint32(existing))
144+ return seq
145+}
146+
147+func FreeGlyphSet(b *xturbo.Buf, glyphset Glyphset) xturbo.Seq {
148+ if b.Ext == nil {
149+ b.Fail(xturbo.ErrExtMissing)
150+ return 0
151+ }
152+ major := b.Ext.Major(xturbo.ExtRender)
153+ if major == 0 {
154+ b.Fail(xturbo.ErrExtMissing)
155+ return 0
156+ }
157+ p, seq := b.Request(major, 19, 4)
158+ if p == nil {
159+ return 0
160+ }
161+ binary.LittleEndian.PutUint32(p[0:], uint32(glyphset))
162+ return seq
163+}
164+
165+func CreateCursor(b *xturbo.Buf, cid xproto.Cursor, source Picture, x uint16, y uint16) xturbo.Seq {
166+ if b.Ext == nil {
167+ b.Fail(xturbo.ErrExtMissing)
168+ return 0
169+ }
170+ major := b.Ext.Major(xturbo.ExtRender)
171+ if major == 0 {
172+ b.Fail(xturbo.ErrExtMissing)
173+ return 0
174+ }
175+ p, seq := b.Request(major, 27, 12)
176+ if p == nil {
177+ return 0
178+ }
179+ binary.LittleEndian.PutUint32(p[0:], uint32(cid))
180+ binary.LittleEndian.PutUint32(p[4:], uint32(source))
181+ binary.LittleEndian.PutUint16(p[8:], uint16(x))
182+ binary.LittleEndian.PutUint16(p[10:], uint16(y))
183+ return seq
184+}
185+
186+func SetPictureTransform(b *xturbo.Buf, picture Picture, transform Transform) xturbo.Seq {
187+ if b.Ext == nil {
188+ b.Fail(xturbo.ErrExtMissing)
189+ return 0
190+ }
191+ major := b.Ext.Major(xturbo.ExtRender)
192+ if major == 0 {
193+ b.Fail(xturbo.ErrExtMissing)
194+ return 0
195+ }
196+ p, seq := b.Request(major, 28, 40)
197+ if p == nil {
198+ return 0
199+ }
200+ binary.LittleEndian.PutUint32(p[0:], uint32(picture))
201+ transform.Put(p[4:])
202+ return seq
203+}
204+
205+func QueryFilters(b *xturbo.Buf, drawable xproto.Drawable) xturbo.Seq {
206+ if b.Ext == nil {
207+ b.Fail(xturbo.ErrExtMissing)
208+ return 0
209+ }
210+ major := b.Ext.Major(xturbo.ExtRender)
211+ if major == 0 {
212+ b.Fail(xturbo.ErrExtMissing)
213+ return 0
214+ }
215+ p, seq := b.Request(major, 29, 4)
216+ if p == nil {
217+ return 0
218+ }
219+ binary.LittleEndian.PutUint32(p[0:], uint32(drawable))
220+ return seq
221+}
222+
223+func CreateSolidFill(b *xturbo.Buf, picture Picture, color Color) xturbo.Seq {
224+ if b.Ext == nil {
225+ b.Fail(xturbo.ErrExtMissing)
226+ return 0
227+ }
228+ major := b.Ext.Major(xturbo.ExtRender)
229+ if major == 0 {
230+ b.Fail(xturbo.ErrExtMissing)
231+ return 0
232+ }
233+ p, seq := b.Request(major, 33, 12)
234+ if p == nil {
235+ return 0
236+ }
237+ binary.LittleEndian.PutUint32(p[0:], uint32(picture))
238+ color.Put(p[4:])
239+ return seq
240+}
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/requests_generated.go +77 -0
@@ -0,0 +1,77 @@
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+}
@@ -0,0 +1,77 @@
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+}
A shape/requests_generated.go +169 -0
@@ -0,0 +1,169 @@
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 Mask(b *xturbo.Buf, operation So, destinationKind Sk, destinationWindow xproto.Window, xOffset int16, yOffset int16, sourceBitmap xproto.Pixmap) xturbo.Seq {
26+ if b.Ext == nil {
27+ b.Fail(xturbo.ErrExtMissing)
28+ return 0
29+ }
30+ major := b.Ext.Major(xturbo.ExtShape)
31+ if major == 0 {
32+ b.Fail(xturbo.ErrExtMissing)
33+ return 0
34+ }
35+ p, seq := b.Request(major, 2, 16)
36+ if p == nil {
37+ return 0
38+ }
39+ p[0:][0] = byte(operation)
40+ p[1:][0] = byte(destinationKind)
41+ binary.LittleEndian.PutUint32(p[4:], uint32(destinationWindow))
42+ binary.LittleEndian.PutUint16(p[8:], uint16(xOffset))
43+ binary.LittleEndian.PutUint16(p[10:], uint16(yOffset))
44+ binary.LittleEndian.PutUint32(p[12:], uint32(sourceBitmap))
45+ return seq
46+}
47+
48+func Combine(b *xturbo.Buf, operation So, destinationKind Sk, sourceKind Sk, destinationWindow xproto.Window, xOffset int16, yOffset int16, sourceWindow xproto.Window) xturbo.Seq {
49+ if b.Ext == nil {
50+ b.Fail(xturbo.ErrExtMissing)
51+ return 0
52+ }
53+ major := b.Ext.Major(xturbo.ExtShape)
54+ if major == 0 {
55+ b.Fail(xturbo.ErrExtMissing)
56+ return 0
57+ }
58+ p, seq := b.Request(major, 3, 16)
59+ if p == nil {
60+ return 0
61+ }
62+ p[0:][0] = byte(operation)
63+ p[1:][0] = byte(destinationKind)
64+ p[2:][0] = byte(sourceKind)
65+ binary.LittleEndian.PutUint32(p[4:], uint32(destinationWindow))
66+ binary.LittleEndian.PutUint16(p[8:], uint16(xOffset))
67+ binary.LittleEndian.PutUint16(p[10:], uint16(yOffset))
68+ binary.LittleEndian.PutUint32(p[12:], uint32(sourceWindow))
69+ return seq
70+}
71+
72+func Offset(b *xturbo.Buf, destinationKind Sk, destinationWindow xproto.Window, xOffset int16, yOffset int16) xturbo.Seq {
73+ if b.Ext == nil {
74+ b.Fail(xturbo.ErrExtMissing)
75+ return 0
76+ }
77+ major := b.Ext.Major(xturbo.ExtShape)
78+ if major == 0 {
79+ b.Fail(xturbo.ErrExtMissing)
80+ return 0
81+ }
82+ p, seq := b.Request(major, 4, 12)
83+ if p == nil {
84+ return 0
85+ }
86+ p[0:][0] = byte(destinationKind)
87+ binary.LittleEndian.PutUint32(p[4:], uint32(destinationWindow))
88+ binary.LittleEndian.PutUint16(p[8:], uint16(xOffset))
89+ binary.LittleEndian.PutUint16(p[10:], uint16(yOffset))
90+ return seq
91+}
92+
93+func QueryExtents(b *xturbo.Buf, destinationWindow 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, 5, 4)
104+ if p == nil {
105+ return 0
106+ }
107+ binary.LittleEndian.PutUint32(p[0:], uint32(destinationWindow))
108+ return seq
109+}
110+
111+func SelectInput(b *xturbo.Buf, destinationWindow xproto.Window, enable bool) xturbo.Seq {
112+ if b.Ext == nil {
113+ b.Fail(xturbo.ErrExtMissing)
114+ return 0
115+ }
116+ major := b.Ext.Major(xturbo.ExtShape)
117+ if major == 0 {
118+ b.Fail(xturbo.ErrExtMissing)
119+ return 0
120+ }
121+ p, seq := b.Request(major, 6, 8)
122+ if p == nil {
123+ return 0
124+ }
125+ binary.LittleEndian.PutUint32(p[0:], uint32(destinationWindow))
126+ if enable {
127+ p[4:][0] = 1
128+ } else {
129+ p[4:][0] = 0
130+ }
131+ return seq
132+}
133+
134+func InputSelected(b *xturbo.Buf, destinationWindow xproto.Window) xturbo.Seq {
135+ if b.Ext == nil {
136+ b.Fail(xturbo.ErrExtMissing)
137+ return 0
138+ }
139+ major := b.Ext.Major(xturbo.ExtShape)
140+ if major == 0 {
141+ b.Fail(xturbo.ErrExtMissing)
142+ return 0
143+ }
144+ p, seq := b.Request(major, 7, 4)
145+ if p == nil {
146+ return 0
147+ }
148+ binary.LittleEndian.PutUint32(p[0:], uint32(destinationWindow))
149+ return seq
150+}
151+
152+func GetRectangles(b *xturbo.Buf, window xproto.Window, sourceKind Sk) xturbo.Seq {
153+ if b.Ext == nil {
154+ b.Fail(xturbo.ErrExtMissing)
155+ return 0
156+ }
157+ major := b.Ext.Major(xturbo.ExtShape)
158+ if major == 0 {
159+ b.Fail(xturbo.ErrExtMissing)
160+ return 0
161+ }
162+ p, seq := b.Request(major, 8, 8)
163+ if p == nil {
164+ return 0
165+ }
166+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
167+ p[4:][0] = byte(sourceKind)
168+ return seq
169+}
@@ -0,0 +1,169 @@
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 Mask(b *xturbo.Buf, operation So, destinationKind Sk, destinationWindow xproto.Window, xOffset int16, yOffset int16, sourceBitmap xproto.Pixmap) xturbo.Seq {
26+ if b.Ext == nil {
27+ b.Fail(xturbo.ErrExtMissing)
28+ return 0
29+ }
30+ major := b.Ext.Major(xturbo.ExtShape)
31+ if major == 0 {
32+ b.Fail(xturbo.ErrExtMissing)
33+ return 0
34+ }
35+ p, seq := b.Request(major, 2, 16)
36+ if p == nil {
37+ return 0
38+ }
39+ p[0:][0] = byte(operation)
40+ p[1:][0] = byte(destinationKind)
41+ binary.LittleEndian.PutUint32(p[4:], uint32(destinationWindow))
42+ binary.LittleEndian.PutUint16(p[8:], uint16(xOffset))
43+ binary.LittleEndian.PutUint16(p[10:], uint16(yOffset))
44+ binary.LittleEndian.PutUint32(p[12:], uint32(sourceBitmap))
45+ return seq
46+}
47+
48+func Combine(b *xturbo.Buf, operation So, destinationKind Sk, sourceKind Sk, destinationWindow xproto.Window, xOffset int16, yOffset int16, sourceWindow xproto.Window) xturbo.Seq {
49+ if b.Ext == nil {
50+ b.Fail(xturbo.ErrExtMissing)
51+ return 0
52+ }
53+ major := b.Ext.Major(xturbo.ExtShape)
54+ if major == 0 {
55+ b.Fail(xturbo.ErrExtMissing)
56+ return 0
57+ }
58+ p, seq := b.Request(major, 3, 16)
59+ if p == nil {
60+ return 0
61+ }
62+ p[0:][0] = byte(operation)
63+ p[1:][0] = byte(destinationKind)
64+ p[2:][0] = byte(sourceKind)
65+ binary.LittleEndian.PutUint32(p[4:], uint32(destinationWindow))
66+ binary.LittleEndian.PutUint16(p[8:], uint16(xOffset))
67+ binary.LittleEndian.PutUint16(p[10:], uint16(yOffset))
68+ binary.LittleEndian.PutUint32(p[12:], uint32(sourceWindow))
69+ return seq
70+}
71+
72+func Offset(b *xturbo.Buf, destinationKind Sk, destinationWindow xproto.Window, xOffset int16, yOffset int16) xturbo.Seq {
73+ if b.Ext == nil {
74+ b.Fail(xturbo.ErrExtMissing)
75+ return 0
76+ }
77+ major := b.Ext.Major(xturbo.ExtShape)
78+ if major == 0 {
79+ b.Fail(xturbo.ErrExtMissing)
80+ return 0
81+ }
82+ p, seq := b.Request(major, 4, 12)
83+ if p == nil {
84+ return 0
85+ }
86+ p[0:][0] = byte(destinationKind)
87+ binary.LittleEndian.PutUint32(p[4:], uint32(destinationWindow))
88+ binary.LittleEndian.PutUint16(p[8:], uint16(xOffset))
89+ binary.LittleEndian.PutUint16(p[10:], uint16(yOffset))
90+ return seq
91+}
92+
93+func QueryExtents(b *xturbo.Buf, destinationWindow 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, 5, 4)
104+ if p == nil {
105+ return 0
106+ }
107+ binary.LittleEndian.PutUint32(p[0:], uint32(destinationWindow))
108+ return seq
109+}
110+
111+func SelectInput(b *xturbo.Buf, destinationWindow xproto.Window, enable bool) xturbo.Seq {
112+ if b.Ext == nil {
113+ b.Fail(xturbo.ErrExtMissing)
114+ return 0
115+ }
116+ major := b.Ext.Major(xturbo.ExtShape)
117+ if major == 0 {
118+ b.Fail(xturbo.ErrExtMissing)
119+ return 0
120+ }
121+ p, seq := b.Request(major, 6, 8)
122+ if p == nil {
123+ return 0
124+ }
125+ binary.LittleEndian.PutUint32(p[0:], uint32(destinationWindow))
126+ if enable {
127+ p[4:][0] = 1
128+ } else {
129+ p[4:][0] = 0
130+ }
131+ return seq
132+}
133+
134+func InputSelected(b *xturbo.Buf, destinationWindow xproto.Window) xturbo.Seq {
135+ if b.Ext == nil {
136+ b.Fail(xturbo.ErrExtMissing)
137+ return 0
138+ }
139+ major := b.Ext.Major(xturbo.ExtShape)
140+ if major == 0 {
141+ b.Fail(xturbo.ErrExtMissing)
142+ return 0
143+ }
144+ p, seq := b.Request(major, 7, 4)
145+ if p == nil {
146+ return 0
147+ }
148+ binary.LittleEndian.PutUint32(p[0:], uint32(destinationWindow))
149+ return seq
150+}
151+
152+func GetRectangles(b *xturbo.Buf, window xproto.Window, sourceKind Sk) xturbo.Seq {
153+ if b.Ext == nil {
154+ b.Fail(xturbo.ErrExtMissing)
155+ return 0
156+ }
157+ major := b.Ext.Major(xturbo.ExtShape)
158+ if major == 0 {
159+ b.Fail(xturbo.ErrExtMissing)
160+ return 0
161+ }
162+ p, seq := b.Request(major, 8, 8)
163+ if p == nil {
164+ return 0
165+ }
166+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
167+ p[4:][0] = byte(sourceKind)
168+ return seq
169+}
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/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/MapWindow.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+080002009f030000
@@ -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+080002009f030000
A xcmisc/requests_generated.go +59 -0
@@ -0,0 +1,59 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package xcmisc
3+
4+import "encoding/binary"
5+import "bnema.dev/xturbo"
6+
7+func GetVersion(b *xturbo.Buf, clientMajorVersion uint16, clientMinorVersion uint16) xturbo.Seq {
8+ if b.Ext == nil {
9+ b.Fail(xturbo.ErrExtMissing)
10+ return 0
11+ }
12+ major := b.Ext.Major(xturbo.ExtXCMisc)
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+ binary.LittleEndian.PutUint16(p[0:], uint16(clientMajorVersion))
22+ binary.LittleEndian.PutUint16(p[2:], uint16(clientMinorVersion))
23+ return seq
24+}
25+
26+func GetXIDRange(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.ExtXCMisc)
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 GetXIDList(b *xturbo.Buf, count uint32) xturbo.Seq {
44+ if b.Ext == nil {
45+ b.Fail(xturbo.ErrExtMissing)
46+ return 0
47+ }
48+ major := b.Ext.Major(xturbo.ExtXCMisc)
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(count))
58+ return seq
59+}
@@ -0,0 +1,59 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package xcmisc
3+
4+import "encoding/binary"
5+import "bnema.dev/xturbo"
6+
7+func GetVersion(b *xturbo.Buf, clientMajorVersion uint16, clientMinorVersion uint16) xturbo.Seq {
8+ if b.Ext == nil {
9+ b.Fail(xturbo.ErrExtMissing)
10+ return 0
11+ }
12+ major := b.Ext.Major(xturbo.ExtXCMisc)
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+ binary.LittleEndian.PutUint16(p[0:], uint16(clientMajorVersion))
22+ binary.LittleEndian.PutUint16(p[2:], uint16(clientMinorVersion))
23+ return seq
24+}
25+
26+func GetXIDRange(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.ExtXCMisc)
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 GetXIDList(b *xturbo.Buf, count uint32) xturbo.Seq {
44+ if b.Ext == nil {
45+ b.Fail(xturbo.ErrExtMissing)
46+ return 0
47+ }
48+ major := b.Ext.Major(xturbo.ExtXCMisc)
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(count))
58+ return seq
59+}
A xfixes/requests_generated.go +585 -0
@@ -0,0 +1,585 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package xfixes
3+
4+import "bnema.dev/xturbo/render"
5+import "bnema.dev/xturbo/shape"
6+import "bnema.dev/xturbo/xproto"
7+import "encoding/binary"
8+import "bnema.dev/xturbo"
9+
10+func QueryVersion(b *xturbo.Buf, clientMajorVersion uint32, clientMinorVersion uint32) xturbo.Seq {
11+ if b.Ext == nil {
12+ b.Fail(xturbo.ErrExtMissing)
13+ return 0
14+ }
15+ major := b.Ext.Major(xturbo.ExtXFixes)
16+ if major == 0 {
17+ b.Fail(xturbo.ErrExtMissing)
18+ return 0
19+ }
20+ p, seq := b.Request(major, 0, 8)
21+ if p == nil {
22+ return 0
23+ }
24+ binary.LittleEndian.PutUint32(p[0:], uint32(clientMajorVersion))
25+ binary.LittleEndian.PutUint32(p[4:], uint32(clientMinorVersion))
26+ return seq
27+}
28+
29+func ChangeSaveSet(b *xturbo.Buf, mode SaveSetMode, target SaveSetTarget, map_ SaveSetMapping, window xproto.Window) xturbo.Seq {
30+ if b.Ext == nil {
31+ b.Fail(xturbo.ErrExtMissing)
32+ return 0
33+ }
34+ major := b.Ext.Major(xturbo.ExtXFixes)
35+ if major == 0 {
36+ b.Fail(xturbo.ErrExtMissing)
37+ return 0
38+ }
39+ p, seq := b.Request(major, 1, 8)
40+ if p == nil {
41+ return 0
42+ }
43+ p[0:][0] = byte(mode)
44+ p[1:][0] = byte(target)
45+ p[2:][0] = byte(map_)
46+ binary.LittleEndian.PutUint32(p[4:], uint32(window))
47+ return seq
48+}
49+
50+func SelectSelectionInput(b *xturbo.Buf, window xproto.Window, selection xproto.Atom, eventMask SelectionEventMask) xturbo.Seq {
51+ if b.Ext == nil {
52+ b.Fail(xturbo.ErrExtMissing)
53+ return 0
54+ }
55+ major := b.Ext.Major(xturbo.ExtXFixes)
56+ if major == 0 {
57+ b.Fail(xturbo.ErrExtMissing)
58+ return 0
59+ }
60+ p, seq := b.Request(major, 2, 12)
61+ if p == nil {
62+ return 0
63+ }
64+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
65+ binary.LittleEndian.PutUint32(p[4:], uint32(selection))
66+ binary.LittleEndian.PutUint32(p[8:], uint32(eventMask))
67+ return seq
68+}
69+
70+func SelectCursorInput(b *xturbo.Buf, window xproto.Window, eventMask CursorNotifyMask) xturbo.Seq {
71+ if b.Ext == nil {
72+ b.Fail(xturbo.ErrExtMissing)
73+ return 0
74+ }
75+ major := b.Ext.Major(xturbo.ExtXFixes)
76+ if major == 0 {
77+ b.Fail(xturbo.ErrExtMissing)
78+ return 0
79+ }
80+ p, seq := b.Request(major, 3, 8)
81+ if p == nil {
82+ return 0
83+ }
84+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
85+ binary.LittleEndian.PutUint32(p[4:], uint32(eventMask))
86+ return seq
87+}
88+
89+func GetCursorImage(b *xturbo.Buf) xturbo.Seq {
90+ if b.Ext == nil {
91+ b.Fail(xturbo.ErrExtMissing)
92+ return 0
93+ }
94+ major := b.Ext.Major(xturbo.ExtXFixes)
95+ if major == 0 {
96+ b.Fail(xturbo.ErrExtMissing)
97+ return 0
98+ }
99+ p, seq := b.Request(major, 4, 0)
100+ if p == nil {
101+ return 0
102+ }
103+ return seq
104+}
105+
106+func CreateRegionFromBitmap(b *xturbo.Buf, region Region, bitmap xproto.Pixmap) xturbo.Seq {
107+ if b.Ext == nil {
108+ b.Fail(xturbo.ErrExtMissing)
109+ return 0
110+ }
111+ major := b.Ext.Major(xturbo.ExtXFixes)
112+ if major == 0 {
113+ b.Fail(xturbo.ErrExtMissing)
114+ return 0
115+ }
116+ p, seq := b.Request(major, 6, 8)
117+ if p == nil {
118+ return 0
119+ }
120+ binary.LittleEndian.PutUint32(p[0:], uint32(region))
121+ binary.LittleEndian.PutUint32(p[4:], uint32(bitmap))
122+ return seq
123+}
124+
125+func CreateRegionFromWindow(b *xturbo.Buf, region Region, window xproto.Window, kind shape.Sk) xturbo.Seq {
126+ if b.Ext == nil {
127+ b.Fail(xturbo.ErrExtMissing)
128+ return 0
129+ }
130+ major := b.Ext.Major(xturbo.ExtXFixes)
131+ if major == 0 {
132+ b.Fail(xturbo.ErrExtMissing)
133+ return 0
134+ }
135+ p, seq := b.Request(major, 7, 12)
136+ if p == nil {
137+ return 0
138+ }
139+ binary.LittleEndian.PutUint32(p[0:], uint32(region))
140+ binary.LittleEndian.PutUint32(p[4:], uint32(window))
141+ p[8:][0] = byte(kind)
142+ return seq
143+}
144+
145+func CreateRegionFromGC(b *xturbo.Buf, region Region, gc xproto.Gcontext) xturbo.Seq {
146+ if b.Ext == nil {
147+ b.Fail(xturbo.ErrExtMissing)
148+ return 0
149+ }
150+ major := b.Ext.Major(xturbo.ExtXFixes)
151+ if major == 0 {
152+ b.Fail(xturbo.ErrExtMissing)
153+ return 0
154+ }
155+ p, seq := b.Request(major, 8, 8)
156+ if p == nil {
157+ return 0
158+ }
159+ binary.LittleEndian.PutUint32(p[0:], uint32(region))
160+ binary.LittleEndian.PutUint32(p[4:], uint32(gc))
161+ return seq
162+}
163+
164+func CreateRegionFromPicture(b *xturbo.Buf, region Region, picture render.Picture) xturbo.Seq {
165+ if b.Ext == nil {
166+ b.Fail(xturbo.ErrExtMissing)
167+ return 0
168+ }
169+ major := b.Ext.Major(xturbo.ExtXFixes)
170+ if major == 0 {
171+ b.Fail(xturbo.ErrExtMissing)
172+ return 0
173+ }
174+ p, seq := b.Request(major, 9, 8)
175+ if p == nil {
176+ return 0
177+ }
178+ binary.LittleEndian.PutUint32(p[0:], uint32(region))
179+ binary.LittleEndian.PutUint32(p[4:], uint32(picture))
180+ return seq
181+}
182+
183+func DestroyRegion(b *xturbo.Buf, region Region) xturbo.Seq {
184+ if b.Ext == nil {
185+ b.Fail(xturbo.ErrExtMissing)
186+ return 0
187+ }
188+ major := b.Ext.Major(xturbo.ExtXFixes)
189+ if major == 0 {
190+ b.Fail(xturbo.ErrExtMissing)
191+ return 0
192+ }
193+ p, seq := b.Request(major, 10, 4)
194+ if p == nil {
195+ return 0
196+ }
197+ binary.LittleEndian.PutUint32(p[0:], uint32(region))
198+ return seq
199+}
200+
201+func CopyRegion(b *xturbo.Buf, source Region, destination Region) xturbo.Seq {
202+ if b.Ext == nil {
203+ b.Fail(xturbo.ErrExtMissing)
204+ return 0
205+ }
206+ major := b.Ext.Major(xturbo.ExtXFixes)
207+ if major == 0 {
208+ b.Fail(xturbo.ErrExtMissing)
209+ return 0
210+ }
211+ p, seq := b.Request(major, 12, 8)
212+ if p == nil {
213+ return 0
214+ }
215+ binary.LittleEndian.PutUint32(p[0:], uint32(source))
216+ binary.LittleEndian.PutUint32(p[4:], uint32(destination))
217+ return seq
218+}
219+
220+func UnionRegion(b *xturbo.Buf, source1 Region, source2 Region, destination Region) xturbo.Seq {
221+ if b.Ext == nil {
222+ b.Fail(xturbo.ErrExtMissing)
223+ return 0
224+ }
225+ major := b.Ext.Major(xturbo.ExtXFixes)
226+ if major == 0 {
227+ b.Fail(xturbo.ErrExtMissing)
228+ return 0
229+ }
230+ p, seq := b.Request(major, 13, 12)
231+ if p == nil {
232+ return 0
233+ }
234+ binary.LittleEndian.PutUint32(p[0:], uint32(source1))
235+ binary.LittleEndian.PutUint32(p[4:], uint32(source2))
236+ binary.LittleEndian.PutUint32(p[8:], uint32(destination))
237+ return seq
238+}
239+
240+func IntersectRegion(b *xturbo.Buf, source1 Region, source2 Region, destination Region) xturbo.Seq {
241+ if b.Ext == nil {
242+ b.Fail(xturbo.ErrExtMissing)
243+ return 0
244+ }
245+ major := b.Ext.Major(xturbo.ExtXFixes)
246+ if major == 0 {
247+ b.Fail(xturbo.ErrExtMissing)
248+ return 0
249+ }
250+ p, seq := b.Request(major, 14, 12)
251+ if p == nil {
252+ return 0
253+ }
254+ binary.LittleEndian.PutUint32(p[0:], uint32(source1))
255+ binary.LittleEndian.PutUint32(p[4:], uint32(source2))
256+ binary.LittleEndian.PutUint32(p[8:], uint32(destination))
257+ return seq
258+}
259+
260+func SubtractRegion(b *xturbo.Buf, source1 Region, source2 Region, destination Region) xturbo.Seq {
261+ if b.Ext == nil {
262+ b.Fail(xturbo.ErrExtMissing)
263+ return 0
264+ }
265+ major := b.Ext.Major(xturbo.ExtXFixes)
266+ if major == 0 {
267+ b.Fail(xturbo.ErrExtMissing)
268+ return 0
269+ }
270+ p, seq := b.Request(major, 15, 12)
271+ if p == nil {
272+ return 0
273+ }
274+ binary.LittleEndian.PutUint32(p[0:], uint32(source1))
275+ binary.LittleEndian.PutUint32(p[4:], uint32(source2))
276+ binary.LittleEndian.PutUint32(p[8:], uint32(destination))
277+ return seq
278+}
279+
280+func InvertRegion(b *xturbo.Buf, source Region, bounds xproto.Rectangle, destination Region) xturbo.Seq {
281+ if b.Ext == nil {
282+ b.Fail(xturbo.ErrExtMissing)
283+ return 0
284+ }
285+ major := b.Ext.Major(xturbo.ExtXFixes)
286+ if major == 0 {
287+ b.Fail(xturbo.ErrExtMissing)
288+ return 0
289+ }
290+ p, seq := b.Request(major, 16, 16)
291+ if p == nil {
292+ return 0
293+ }
294+ binary.LittleEndian.PutUint32(p[0:], uint32(source))
295+ bounds.Put(p[4:])
296+ binary.LittleEndian.PutUint32(p[12:], uint32(destination))
297+ return seq
298+}
299+
300+func TranslateRegion(b *xturbo.Buf, region Region, dx int16, dy int16) xturbo.Seq {
301+ if b.Ext == nil {
302+ b.Fail(xturbo.ErrExtMissing)
303+ return 0
304+ }
305+ major := b.Ext.Major(xturbo.ExtXFixes)
306+ if major == 0 {
307+ b.Fail(xturbo.ErrExtMissing)
308+ return 0
309+ }
310+ p, seq := b.Request(major, 17, 8)
311+ if p == nil {
312+ return 0
313+ }
314+ binary.LittleEndian.PutUint32(p[0:], uint32(region))
315+ binary.LittleEndian.PutUint16(p[4:], uint16(dx))
316+ binary.LittleEndian.PutUint16(p[6:], uint16(dy))
317+ return seq
318+}
319+
320+func RegionExtents(b *xturbo.Buf, source Region, destination Region) xturbo.Seq {
321+ if b.Ext == nil {
322+ b.Fail(xturbo.ErrExtMissing)
323+ return 0
324+ }
325+ major := b.Ext.Major(xturbo.ExtXFixes)
326+ if major == 0 {
327+ b.Fail(xturbo.ErrExtMissing)
328+ return 0
329+ }
330+ p, seq := b.Request(major, 18, 8)
331+ if p == nil {
332+ return 0
333+ }
334+ binary.LittleEndian.PutUint32(p[0:], uint32(source))
335+ binary.LittleEndian.PutUint32(p[4:], uint32(destination))
336+ return seq
337+}
338+
339+func FetchRegion(b *xturbo.Buf, region Region) xturbo.Seq {
340+ if b.Ext == nil {
341+ b.Fail(xturbo.ErrExtMissing)
342+ return 0
343+ }
344+ major := b.Ext.Major(xturbo.ExtXFixes)
345+ if major == 0 {
346+ b.Fail(xturbo.ErrExtMissing)
347+ return 0
348+ }
349+ p, seq := b.Request(major, 19, 4)
350+ if p == nil {
351+ return 0
352+ }
353+ binary.LittleEndian.PutUint32(p[0:], uint32(region))
354+ return seq
355+}
356+
357+func SetGCClipRegion(b *xturbo.Buf, gc xproto.Gcontext, region Region, xOrigin int16, yOrigin int16) xturbo.Seq {
358+ if b.Ext == nil {
359+ b.Fail(xturbo.ErrExtMissing)
360+ return 0
361+ }
362+ major := b.Ext.Major(xturbo.ExtXFixes)
363+ if major == 0 {
364+ b.Fail(xturbo.ErrExtMissing)
365+ return 0
366+ }
367+ p, seq := b.Request(major, 20, 12)
368+ if p == nil {
369+ return 0
370+ }
371+ binary.LittleEndian.PutUint32(p[0:], uint32(gc))
372+ binary.LittleEndian.PutUint32(p[4:], uint32(region))
373+ binary.LittleEndian.PutUint16(p[8:], uint16(xOrigin))
374+ binary.LittleEndian.PutUint16(p[10:], uint16(yOrigin))
375+ return seq
376+}
377+
378+func SetWindowShapeRegion(b *xturbo.Buf, dest xproto.Window, destKind shape.Sk, xOffset int16, yOffset int16, region Region) xturbo.Seq {
379+ if b.Ext == nil {
380+ b.Fail(xturbo.ErrExtMissing)
381+ return 0
382+ }
383+ major := b.Ext.Major(xturbo.ExtXFixes)
384+ if major == 0 {
385+ b.Fail(xturbo.ErrExtMissing)
386+ return 0
387+ }
388+ p, seq := b.Request(major, 21, 16)
389+ if p == nil {
390+ return 0
391+ }
392+ binary.LittleEndian.PutUint32(p[0:], uint32(dest))
393+ p[4:][0] = byte(destKind)
394+ binary.LittleEndian.PutUint16(p[8:], uint16(xOffset))
395+ binary.LittleEndian.PutUint16(p[10:], uint16(yOffset))
396+ binary.LittleEndian.PutUint32(p[12:], uint32(region))
397+ return seq
398+}
399+
400+func SetPictureClipRegion(b *xturbo.Buf, picture render.Picture, region Region, xOrigin int16, yOrigin int16) xturbo.Seq {
401+ if b.Ext == nil {
402+ b.Fail(xturbo.ErrExtMissing)
403+ return 0
404+ }
405+ major := b.Ext.Major(xturbo.ExtXFixes)
406+ if major == 0 {
407+ b.Fail(xturbo.ErrExtMissing)
408+ return 0
409+ }
410+ p, seq := b.Request(major, 22, 12)
411+ if p == nil {
412+ return 0
413+ }
414+ binary.LittleEndian.PutUint32(p[0:], uint32(picture))
415+ binary.LittleEndian.PutUint32(p[4:], uint32(region))
416+ binary.LittleEndian.PutUint16(p[8:], uint16(xOrigin))
417+ binary.LittleEndian.PutUint16(p[10:], uint16(yOrigin))
418+ return seq
419+}
420+
421+func GetCursorName(b *xturbo.Buf, cursor xproto.Cursor) xturbo.Seq {
422+ if b.Ext == nil {
423+ b.Fail(xturbo.ErrExtMissing)
424+ return 0
425+ }
426+ major := b.Ext.Major(xturbo.ExtXFixes)
427+ if major == 0 {
428+ b.Fail(xturbo.ErrExtMissing)
429+ return 0
430+ }
431+ p, seq := b.Request(major, 24, 4)
432+ if p == nil {
433+ return 0
434+ }
435+ binary.LittleEndian.PutUint32(p[0:], uint32(cursor))
436+ return seq
437+}
438+
439+func GetCursorImageAndName(b *xturbo.Buf) xturbo.Seq {
440+ if b.Ext == nil {
441+ b.Fail(xturbo.ErrExtMissing)
442+ return 0
443+ }
444+ major := b.Ext.Major(xturbo.ExtXFixes)
445+ if major == 0 {
446+ b.Fail(xturbo.ErrExtMissing)
447+ return 0
448+ }
449+ p, seq := b.Request(major, 25, 0)
450+ if p == nil {
451+ return 0
452+ }
453+ return seq
454+}
455+
456+func ChangeCursor(b *xturbo.Buf, source xproto.Cursor, destination xproto.Cursor) xturbo.Seq {
457+ if b.Ext == nil {
458+ b.Fail(xturbo.ErrExtMissing)
459+ return 0
460+ }
461+ major := b.Ext.Major(xturbo.ExtXFixes)
462+ if major == 0 {
463+ b.Fail(xturbo.ErrExtMissing)
464+ return 0
465+ }
466+ p, seq := b.Request(major, 26, 8)
467+ if p == nil {
468+ return 0
469+ }
470+ binary.LittleEndian.PutUint32(p[0:], uint32(source))
471+ binary.LittleEndian.PutUint32(p[4:], uint32(destination))
472+ return seq
473+}
474+
475+func ExpandRegion(b *xturbo.Buf, source Region, destination Region, left uint16, right uint16, top uint16, bottom uint16) xturbo.Seq {
476+ if b.Ext == nil {
477+ b.Fail(xturbo.ErrExtMissing)
478+ return 0
479+ }
480+ major := b.Ext.Major(xturbo.ExtXFixes)
481+ if major == 0 {
482+ b.Fail(xturbo.ErrExtMissing)
483+ return 0
484+ }
485+ p, seq := b.Request(major, 28, 16)
486+ if p == nil {
487+ return 0
488+ }
489+ binary.LittleEndian.PutUint32(p[0:], uint32(source))
490+ binary.LittleEndian.PutUint32(p[4:], uint32(destination))
491+ binary.LittleEndian.PutUint16(p[8:], uint16(left))
492+ binary.LittleEndian.PutUint16(p[10:], uint16(right))
493+ binary.LittleEndian.PutUint16(p[12:], uint16(top))
494+ binary.LittleEndian.PutUint16(p[14:], uint16(bottom))
495+ return seq
496+}
497+
498+func HideCursor(b *xturbo.Buf, window xproto.Window) xturbo.Seq {
499+ if b.Ext == nil {
500+ b.Fail(xturbo.ErrExtMissing)
501+ return 0
502+ }
503+ major := b.Ext.Major(xturbo.ExtXFixes)
504+ if major == 0 {
505+ b.Fail(xturbo.ErrExtMissing)
506+ return 0
507+ }
508+ p, seq := b.Request(major, 29, 4)
509+ if p == nil {
510+ return 0
511+ }
512+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
513+ return seq
514+}
515+
516+func ShowCursor(b *xturbo.Buf, window xproto.Window) xturbo.Seq {
517+ if b.Ext == nil {
518+ b.Fail(xturbo.ErrExtMissing)
519+ return 0
520+ }
521+ major := b.Ext.Major(xturbo.ExtXFixes)
522+ if major == 0 {
523+ b.Fail(xturbo.ErrExtMissing)
524+ return 0
525+ }
526+ p, seq := b.Request(major, 30, 4)
527+ if p == nil {
528+ return 0
529+ }
530+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
531+ return seq
532+}
533+
534+func DeletePointerBarrier(b *xturbo.Buf, barrier Barrier) xturbo.Seq {
535+ if b.Ext == nil {
536+ b.Fail(xturbo.ErrExtMissing)
537+ return 0
538+ }
539+ major := b.Ext.Major(xturbo.ExtXFixes)
540+ if major == 0 {
541+ b.Fail(xturbo.ErrExtMissing)
542+ return 0
543+ }
544+ p, seq := b.Request(major, 32, 4)
545+ if p == nil {
546+ return 0
547+ }
548+ binary.LittleEndian.PutUint32(p[0:], uint32(barrier))
549+ return seq
550+}
551+
552+func SetClientDisconnectMode(b *xturbo.Buf, disconnectMode ClientDisconnectFlags) xturbo.Seq {
553+ if b.Ext == nil {
554+ b.Fail(xturbo.ErrExtMissing)
555+ return 0
556+ }
557+ major := b.Ext.Major(xturbo.ExtXFixes)
558+ if major == 0 {
559+ b.Fail(xturbo.ErrExtMissing)
560+ return 0
561+ }
562+ p, seq := b.Request(major, 33, 4)
563+ if p == nil {
564+ return 0
565+ }
566+ binary.LittleEndian.PutUint32(p[0:], uint32(disconnectMode))
567+ return seq
568+}
569+
570+func GetClientDisconnectMode(b *xturbo.Buf) xturbo.Seq {
571+ if b.Ext == nil {
572+ b.Fail(xturbo.ErrExtMissing)
573+ return 0
574+ }
575+ major := b.Ext.Major(xturbo.ExtXFixes)
576+ if major == 0 {
577+ b.Fail(xturbo.ErrExtMissing)
578+ return 0
579+ }
580+ p, seq := b.Request(major, 34, 0)
581+ if p == nil {
582+ return 0
583+ }
584+ return seq
585+}
@@ -0,0 +1,585 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package xfixes
3+
4+import "bnema.dev/xturbo/render"
5+import "bnema.dev/xturbo/shape"
6+import "bnema.dev/xturbo/xproto"
7+import "encoding/binary"
8+import "bnema.dev/xturbo"
9+
10+func QueryVersion(b *xturbo.Buf, clientMajorVersion uint32, clientMinorVersion uint32) xturbo.Seq {
11+ if b.Ext == nil {
12+ b.Fail(xturbo.ErrExtMissing)
13+ return 0
14+ }
15+ major := b.Ext.Major(xturbo.ExtXFixes)
16+ if major == 0 {
17+ b.Fail(xturbo.ErrExtMissing)
18+ return 0
19+ }
20+ p, seq := b.Request(major, 0, 8)
21+ if p == nil {
22+ return 0
23+ }
24+ binary.LittleEndian.PutUint32(p[0:], uint32(clientMajorVersion))
25+ binary.LittleEndian.PutUint32(p[4:], uint32(clientMinorVersion))
26+ return seq
27+}
28+
29+func ChangeSaveSet(b *xturbo.Buf, mode SaveSetMode, target SaveSetTarget, map_ SaveSetMapping, window xproto.Window) xturbo.Seq {
30+ if b.Ext == nil {
31+ b.Fail(xturbo.ErrExtMissing)
32+ return 0
33+ }
34+ major := b.Ext.Major(xturbo.ExtXFixes)
35+ if major == 0 {
36+ b.Fail(xturbo.ErrExtMissing)
37+ return 0
38+ }
39+ p, seq := b.Request(major, 1, 8)
40+ if p == nil {
41+ return 0
42+ }
43+ p[0:][0] = byte(mode)
44+ p[1:][0] = byte(target)
45+ p[2:][0] = byte(map_)
46+ binary.LittleEndian.PutUint32(p[4:], uint32(window))
47+ return seq
48+}
49+
50+func SelectSelectionInput(b *xturbo.Buf, window xproto.Window, selection xproto.Atom, eventMask SelectionEventMask) xturbo.Seq {
51+ if b.Ext == nil {
52+ b.Fail(xturbo.ErrExtMissing)
53+ return 0
54+ }
55+ major := b.Ext.Major(xturbo.ExtXFixes)
56+ if major == 0 {
57+ b.Fail(xturbo.ErrExtMissing)
58+ return 0
59+ }
60+ p, seq := b.Request(major, 2, 12)
61+ if p == nil {
62+ return 0
63+ }
64+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
65+ binary.LittleEndian.PutUint32(p[4:], uint32(selection))
66+ binary.LittleEndian.PutUint32(p[8:], uint32(eventMask))
67+ return seq
68+}
69+
70+func SelectCursorInput(b *xturbo.Buf, window xproto.Window, eventMask CursorNotifyMask) xturbo.Seq {
71+ if b.Ext == nil {
72+ b.Fail(xturbo.ErrExtMissing)
73+ return 0
74+ }
75+ major := b.Ext.Major(xturbo.ExtXFixes)
76+ if major == 0 {
77+ b.Fail(xturbo.ErrExtMissing)
78+ return 0
79+ }
80+ p, seq := b.Request(major, 3, 8)
81+ if p == nil {
82+ return 0
83+ }
84+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
85+ binary.LittleEndian.PutUint32(p[4:], uint32(eventMask))
86+ return seq
87+}
88+
89+func GetCursorImage(b *xturbo.Buf) xturbo.Seq {
90+ if b.Ext == nil {
91+ b.Fail(xturbo.ErrExtMissing)
92+ return 0
93+ }
94+ major := b.Ext.Major(xturbo.ExtXFixes)
95+ if major == 0 {
96+ b.Fail(xturbo.ErrExtMissing)
97+ return 0
98+ }
99+ p, seq := b.Request(major, 4, 0)
100+ if p == nil {
101+ return 0
102+ }
103+ return seq
104+}
105+
106+func CreateRegionFromBitmap(b *xturbo.Buf, region Region, bitmap xproto.Pixmap) xturbo.Seq {
107+ if b.Ext == nil {
108+ b.Fail(xturbo.ErrExtMissing)
109+ return 0
110+ }
111+ major := b.Ext.Major(xturbo.ExtXFixes)
112+ if major == 0 {
113+ b.Fail(xturbo.ErrExtMissing)
114+ return 0
115+ }
116+ p, seq := b.Request(major, 6, 8)
117+ if p == nil {
118+ return 0
119+ }
120+ binary.LittleEndian.PutUint32(p[0:], uint32(region))
121+ binary.LittleEndian.PutUint32(p[4:], uint32(bitmap))
122+ return seq
123+}
124+
125+func CreateRegionFromWindow(b *xturbo.Buf, region Region, window xproto.Window, kind shape.Sk) xturbo.Seq {
126+ if b.Ext == nil {
127+ b.Fail(xturbo.ErrExtMissing)
128+ return 0
129+ }
130+ major := b.Ext.Major(xturbo.ExtXFixes)
131+ if major == 0 {
132+ b.Fail(xturbo.ErrExtMissing)
133+ return 0
134+ }
135+ p, seq := b.Request(major, 7, 12)
136+ if p == nil {
137+ return 0
138+ }
139+ binary.LittleEndian.PutUint32(p[0:], uint32(region))
140+ binary.LittleEndian.PutUint32(p[4:], uint32(window))
141+ p[8:][0] = byte(kind)
142+ return seq
143+}
144+
145+func CreateRegionFromGC(b *xturbo.Buf, region Region, gc xproto.Gcontext) xturbo.Seq {
146+ if b.Ext == nil {
147+ b.Fail(xturbo.ErrExtMissing)
148+ return 0
149+ }
150+ major := b.Ext.Major(xturbo.ExtXFixes)
151+ if major == 0 {
152+ b.Fail(xturbo.ErrExtMissing)
153+ return 0
154+ }
155+ p, seq := b.Request(major, 8, 8)
156+ if p == nil {
157+ return 0
158+ }
159+ binary.LittleEndian.PutUint32(p[0:], uint32(region))
160+ binary.LittleEndian.PutUint32(p[4:], uint32(gc))
161+ return seq
162+}
163+
164+func CreateRegionFromPicture(b *xturbo.Buf, region Region, picture render.Picture) xturbo.Seq {
165+ if b.Ext == nil {
166+ b.Fail(xturbo.ErrExtMissing)
167+ return 0
168+ }
169+ major := b.Ext.Major(xturbo.ExtXFixes)
170+ if major == 0 {
171+ b.Fail(xturbo.ErrExtMissing)
172+ return 0
173+ }
174+ p, seq := b.Request(major, 9, 8)
175+ if p == nil {
176+ return 0
177+ }
178+ binary.LittleEndian.PutUint32(p[0:], uint32(region))
179+ binary.LittleEndian.PutUint32(p[4:], uint32(picture))
180+ return seq
181+}
182+
183+func DestroyRegion(b *xturbo.Buf, region Region) xturbo.Seq {
184+ if b.Ext == nil {
185+ b.Fail(xturbo.ErrExtMissing)
186+ return 0
187+ }
188+ major := b.Ext.Major(xturbo.ExtXFixes)
189+ if major == 0 {
190+ b.Fail(xturbo.ErrExtMissing)
191+ return 0
192+ }
193+ p, seq := b.Request(major, 10, 4)
194+ if p == nil {
195+ return 0
196+ }
197+ binary.LittleEndian.PutUint32(p[0:], uint32(region))
198+ return seq
199+}
200+
201+func CopyRegion(b *xturbo.Buf, source Region, destination Region) xturbo.Seq {
202+ if b.Ext == nil {
203+ b.Fail(xturbo.ErrExtMissing)
204+ return 0
205+ }
206+ major := b.Ext.Major(xturbo.ExtXFixes)
207+ if major == 0 {
208+ b.Fail(xturbo.ErrExtMissing)
209+ return 0
210+ }
211+ p, seq := b.Request(major, 12, 8)
212+ if p == nil {
213+ return 0
214+ }
215+ binary.LittleEndian.PutUint32(p[0:], uint32(source))
216+ binary.LittleEndian.PutUint32(p[4:], uint32(destination))
217+ return seq
218+}
219+
220+func UnionRegion(b *xturbo.Buf, source1 Region, source2 Region, destination Region) xturbo.Seq {
221+ if b.Ext == nil {
222+ b.Fail(xturbo.ErrExtMissing)
223+ return 0
224+ }
225+ major := b.Ext.Major(xturbo.ExtXFixes)
226+ if major == 0 {
227+ b.Fail(xturbo.ErrExtMissing)
228+ return 0
229+ }
230+ p, seq := b.Request(major, 13, 12)
231+ if p == nil {
232+ return 0
233+ }
234+ binary.LittleEndian.PutUint32(p[0:], uint32(source1))
235+ binary.LittleEndian.PutUint32(p[4:], uint32(source2))
236+ binary.LittleEndian.PutUint32(p[8:], uint32(destination))
237+ return seq
238+}
239+
240+func IntersectRegion(b *xturbo.Buf, source1 Region, source2 Region, destination Region) xturbo.Seq {
241+ if b.Ext == nil {
242+ b.Fail(xturbo.ErrExtMissing)
243+ return 0
244+ }
245+ major := b.Ext.Major(xturbo.ExtXFixes)
246+ if major == 0 {
247+ b.Fail(xturbo.ErrExtMissing)
248+ return 0
249+ }
250+ p, seq := b.Request(major, 14, 12)
251+ if p == nil {
252+ return 0
253+ }
254+ binary.LittleEndian.PutUint32(p[0:], uint32(source1))
255+ binary.LittleEndian.PutUint32(p[4:], uint32(source2))
256+ binary.LittleEndian.PutUint32(p[8:], uint32(destination))
257+ return seq
258+}
259+
260+func SubtractRegion(b *xturbo.Buf, source1 Region, source2 Region, destination Region) xturbo.Seq {
261+ if b.Ext == nil {
262+ b.Fail(xturbo.ErrExtMissing)
263+ return 0
264+ }
265+ major := b.Ext.Major(xturbo.ExtXFixes)
266+ if major == 0 {
267+ b.Fail(xturbo.ErrExtMissing)
268+ return 0
269+ }
270+ p, seq := b.Request(major, 15, 12)
271+ if p == nil {
272+ return 0
273+ }
274+ binary.LittleEndian.PutUint32(p[0:], uint32(source1))
275+ binary.LittleEndian.PutUint32(p[4:], uint32(source2))
276+ binary.LittleEndian.PutUint32(p[8:], uint32(destination))
277+ return seq
278+}
279+
280+func InvertRegion(b *xturbo.Buf, source Region, bounds xproto.Rectangle, destination Region) xturbo.Seq {
281+ if b.Ext == nil {
282+ b.Fail(xturbo.ErrExtMissing)
283+ return 0
284+ }
285+ major := b.Ext.Major(xturbo.ExtXFixes)
286+ if major == 0 {
287+ b.Fail(xturbo.ErrExtMissing)
288+ return 0
289+ }
290+ p, seq := b.Request(major, 16, 16)
291+ if p == nil {
292+ return 0
293+ }
294+ binary.LittleEndian.PutUint32(p[0:], uint32(source))
295+ bounds.Put(p[4:])
296+ binary.LittleEndian.PutUint32(p[12:], uint32(destination))
297+ return seq
298+}
299+
300+func TranslateRegion(b *xturbo.Buf, region Region, dx int16, dy int16) xturbo.Seq {
301+ if b.Ext == nil {
302+ b.Fail(xturbo.ErrExtMissing)
303+ return 0
304+ }
305+ major := b.Ext.Major(xturbo.ExtXFixes)
306+ if major == 0 {
307+ b.Fail(xturbo.ErrExtMissing)
308+ return 0
309+ }
310+ p, seq := b.Request(major, 17, 8)
311+ if p == nil {
312+ return 0
313+ }
314+ binary.LittleEndian.PutUint32(p[0:], uint32(region))
315+ binary.LittleEndian.PutUint16(p[4:], uint16(dx))
316+ binary.LittleEndian.PutUint16(p[6:], uint16(dy))
317+ return seq
318+}
319+
320+func RegionExtents(b *xturbo.Buf, source Region, destination Region) xturbo.Seq {
321+ if b.Ext == nil {
322+ b.Fail(xturbo.ErrExtMissing)
323+ return 0
324+ }
325+ major := b.Ext.Major(xturbo.ExtXFixes)
326+ if major == 0 {
327+ b.Fail(xturbo.ErrExtMissing)
328+ return 0
329+ }
330+ p, seq := b.Request(major, 18, 8)
331+ if p == nil {
332+ return 0
333+ }
334+ binary.LittleEndian.PutUint32(p[0:], uint32(source))
335+ binary.LittleEndian.PutUint32(p[4:], uint32(destination))
336+ return seq
337+}
338+
339+func FetchRegion(b *xturbo.Buf, region Region) xturbo.Seq {
340+ if b.Ext == nil {
341+ b.Fail(xturbo.ErrExtMissing)
342+ return 0
343+ }
344+ major := b.Ext.Major(xturbo.ExtXFixes)
345+ if major == 0 {
346+ b.Fail(xturbo.ErrExtMissing)
347+ return 0
348+ }
349+ p, seq := b.Request(major, 19, 4)
350+ if p == nil {
351+ return 0
352+ }
353+ binary.LittleEndian.PutUint32(p[0:], uint32(region))
354+ return seq
355+}
356+
357+func SetGCClipRegion(b *xturbo.Buf, gc xproto.Gcontext, region Region, xOrigin int16, yOrigin int16) xturbo.Seq {
358+ if b.Ext == nil {
359+ b.Fail(xturbo.ErrExtMissing)
360+ return 0
361+ }
362+ major := b.Ext.Major(xturbo.ExtXFixes)
363+ if major == 0 {
364+ b.Fail(xturbo.ErrExtMissing)
365+ return 0
366+ }
367+ p, seq := b.Request(major, 20, 12)
368+ if p == nil {
369+ return 0
370+ }
371+ binary.LittleEndian.PutUint32(p[0:], uint32(gc))
372+ binary.LittleEndian.PutUint32(p[4:], uint32(region))
373+ binary.LittleEndian.PutUint16(p[8:], uint16(xOrigin))
374+ binary.LittleEndian.PutUint16(p[10:], uint16(yOrigin))
375+ return seq
376+}
377+
378+func SetWindowShapeRegion(b *xturbo.Buf, dest xproto.Window, destKind shape.Sk, xOffset int16, yOffset int16, region Region) xturbo.Seq {
379+ if b.Ext == nil {
380+ b.Fail(xturbo.ErrExtMissing)
381+ return 0
382+ }
383+ major := b.Ext.Major(xturbo.ExtXFixes)
384+ if major == 0 {
385+ b.Fail(xturbo.ErrExtMissing)
386+ return 0
387+ }
388+ p, seq := b.Request(major, 21, 16)
389+ if p == nil {
390+ return 0
391+ }
392+ binary.LittleEndian.PutUint32(p[0:], uint32(dest))
393+ p[4:][0] = byte(destKind)
394+ binary.LittleEndian.PutUint16(p[8:], uint16(xOffset))
395+ binary.LittleEndian.PutUint16(p[10:], uint16(yOffset))
396+ binary.LittleEndian.PutUint32(p[12:], uint32(region))
397+ return seq
398+}
399+
400+func SetPictureClipRegion(b *xturbo.Buf, picture render.Picture, region Region, xOrigin int16, yOrigin int16) xturbo.Seq {
401+ if b.Ext == nil {
402+ b.Fail(xturbo.ErrExtMissing)
403+ return 0
404+ }
405+ major := b.Ext.Major(xturbo.ExtXFixes)
406+ if major == 0 {
407+ b.Fail(xturbo.ErrExtMissing)
408+ return 0
409+ }
410+ p, seq := b.Request(major, 22, 12)
411+ if p == nil {
412+ return 0
413+ }
414+ binary.LittleEndian.PutUint32(p[0:], uint32(picture))
415+ binary.LittleEndian.PutUint32(p[4:], uint32(region))
416+ binary.LittleEndian.PutUint16(p[8:], uint16(xOrigin))
417+ binary.LittleEndian.PutUint16(p[10:], uint16(yOrigin))
418+ return seq
419+}
420+
421+func GetCursorName(b *xturbo.Buf, cursor xproto.Cursor) xturbo.Seq {
422+ if b.Ext == nil {
423+ b.Fail(xturbo.ErrExtMissing)
424+ return 0
425+ }
426+ major := b.Ext.Major(xturbo.ExtXFixes)
427+ if major == 0 {
428+ b.Fail(xturbo.ErrExtMissing)
429+ return 0
430+ }
431+ p, seq := b.Request(major, 24, 4)
432+ if p == nil {
433+ return 0
434+ }
435+ binary.LittleEndian.PutUint32(p[0:], uint32(cursor))
436+ return seq
437+}
438+
439+func GetCursorImageAndName(b *xturbo.Buf) xturbo.Seq {
440+ if b.Ext == nil {
441+ b.Fail(xturbo.ErrExtMissing)
442+ return 0
443+ }
444+ major := b.Ext.Major(xturbo.ExtXFixes)
445+ if major == 0 {
446+ b.Fail(xturbo.ErrExtMissing)
447+ return 0
448+ }
449+ p, seq := b.Request(major, 25, 0)
450+ if p == nil {
451+ return 0
452+ }
453+ return seq
454+}
455+
456+func ChangeCursor(b *xturbo.Buf, source xproto.Cursor, destination xproto.Cursor) xturbo.Seq {
457+ if b.Ext == nil {
458+ b.Fail(xturbo.ErrExtMissing)
459+ return 0
460+ }
461+ major := b.Ext.Major(xturbo.ExtXFixes)
462+ if major == 0 {
463+ b.Fail(xturbo.ErrExtMissing)
464+ return 0
465+ }
466+ p, seq := b.Request(major, 26, 8)
467+ if p == nil {
468+ return 0
469+ }
470+ binary.LittleEndian.PutUint32(p[0:], uint32(source))
471+ binary.LittleEndian.PutUint32(p[4:], uint32(destination))
472+ return seq
473+}
474+
475+func ExpandRegion(b *xturbo.Buf, source Region, destination Region, left uint16, right uint16, top uint16, bottom uint16) xturbo.Seq {
476+ if b.Ext == nil {
477+ b.Fail(xturbo.ErrExtMissing)
478+ return 0
479+ }
480+ major := b.Ext.Major(xturbo.ExtXFixes)
481+ if major == 0 {
482+ b.Fail(xturbo.ErrExtMissing)
483+ return 0
484+ }
485+ p, seq := b.Request(major, 28, 16)
486+ if p == nil {
487+ return 0
488+ }
489+ binary.LittleEndian.PutUint32(p[0:], uint32(source))
490+ binary.LittleEndian.PutUint32(p[4:], uint32(destination))
491+ binary.LittleEndian.PutUint16(p[8:], uint16(left))
492+ binary.LittleEndian.PutUint16(p[10:], uint16(right))
493+ binary.LittleEndian.PutUint16(p[12:], uint16(top))
494+ binary.LittleEndian.PutUint16(p[14:], uint16(bottom))
495+ return seq
496+}
497+
498+func HideCursor(b *xturbo.Buf, window xproto.Window) xturbo.Seq {
499+ if b.Ext == nil {
500+ b.Fail(xturbo.ErrExtMissing)
501+ return 0
502+ }
503+ major := b.Ext.Major(xturbo.ExtXFixes)
504+ if major == 0 {
505+ b.Fail(xturbo.ErrExtMissing)
506+ return 0
507+ }
508+ p, seq := b.Request(major, 29, 4)
509+ if p == nil {
510+ return 0
511+ }
512+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
513+ return seq
514+}
515+
516+func ShowCursor(b *xturbo.Buf, window xproto.Window) xturbo.Seq {
517+ if b.Ext == nil {
518+ b.Fail(xturbo.ErrExtMissing)
519+ return 0
520+ }
521+ major := b.Ext.Major(xturbo.ExtXFixes)
522+ if major == 0 {
523+ b.Fail(xturbo.ErrExtMissing)
524+ return 0
525+ }
526+ p, seq := b.Request(major, 30, 4)
527+ if p == nil {
528+ return 0
529+ }
530+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
531+ return seq
532+}
533+
534+func DeletePointerBarrier(b *xturbo.Buf, barrier Barrier) xturbo.Seq {
535+ if b.Ext == nil {
536+ b.Fail(xturbo.ErrExtMissing)
537+ return 0
538+ }
539+ major := b.Ext.Major(xturbo.ExtXFixes)
540+ if major == 0 {
541+ b.Fail(xturbo.ErrExtMissing)
542+ return 0
543+ }
544+ p, seq := b.Request(major, 32, 4)
545+ if p == nil {
546+ return 0
547+ }
548+ binary.LittleEndian.PutUint32(p[0:], uint32(barrier))
549+ return seq
550+}
551+
552+func SetClientDisconnectMode(b *xturbo.Buf, disconnectMode ClientDisconnectFlags) xturbo.Seq {
553+ if b.Ext == nil {
554+ b.Fail(xturbo.ErrExtMissing)
555+ return 0
556+ }
557+ major := b.Ext.Major(xturbo.ExtXFixes)
558+ if major == 0 {
559+ b.Fail(xturbo.ErrExtMissing)
560+ return 0
561+ }
562+ p, seq := b.Request(major, 33, 4)
563+ if p == nil {
564+ return 0
565+ }
566+ binary.LittleEndian.PutUint32(p[0:], uint32(disconnectMode))
567+ return seq
568+}
569+
570+func GetClientDisconnectMode(b *xturbo.Buf) xturbo.Seq {
571+ if b.Ext == nil {
572+ b.Fail(xturbo.ErrExtMissing)
573+ return 0
574+ }
575+ major := b.Ext.Major(xturbo.ExtXFixes)
576+ if major == 0 {
577+ b.Fail(xturbo.ErrExtMissing)
578+ return 0
579+ }
580+ p, seq := b.Request(major, 34, 0)
581+ if p == nil {
582+ return 0
583+ }
584+ return seq
585+}
A xproto/requests_generated.go +869 -0
@@ -0,0 +1,869 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package xproto
3+
4+import "encoding/binary"
5+import "bnema.dev/xturbo"
6+
7+func GetWindowAttributes(b *xturbo.Buf, window Window) xturbo.Seq {
8+ p, seq := b.Request(3, 0, 4)
9+ if p == nil {
10+ return 0
11+ }
12+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
13+ return seq
14+}
15+
16+func DestroyWindow(b *xturbo.Buf, window Window) xturbo.Seq {
17+ p, seq := b.Request(4, 0, 4)
18+ if p == nil {
19+ return 0
20+ }
21+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
22+ return seq
23+}
24+
25+func DestroySubwindows(b *xturbo.Buf, window Window) xturbo.Seq {
26+ p, seq := b.Request(5, 0, 4)
27+ if p == nil {
28+ return 0
29+ }
30+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
31+ return seq
32+}
33+
34+func ChangeSaveSet(b *xturbo.Buf, mode SetMode, window Window) xturbo.Seq {
35+ p, seq := b.Request(6, uint8(mode), 4)
36+ if p == nil {
37+ return 0
38+ }
39+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
40+ return seq
41+}
42+
43+func ReparentWindow(b *xturbo.Buf, window Window, parent Window, x int16, y int16) xturbo.Seq {
44+ p, seq := b.Request(7, 0, 12)
45+ if p == nil {
46+ return 0
47+ }
48+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
49+ binary.LittleEndian.PutUint32(p[4:], uint32(parent))
50+ binary.LittleEndian.PutUint16(p[8:], uint16(x))
51+ binary.LittleEndian.PutUint16(p[10:], uint16(y))
52+ return seq
53+}
54+
55+func MapWindow(b *xturbo.Buf, window Window) xturbo.Seq {
56+ p, seq := b.Request(8, 0, 4)
57+ if p == nil {
58+ return 0
59+ }
60+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
61+ return seq
62+}
63+
64+func MapSubwindows(b *xturbo.Buf, window Window) xturbo.Seq {
65+ p, seq := b.Request(9, 0, 4)
66+ if p == nil {
67+ return 0
68+ }
69+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
70+ return seq
71+}
72+
73+func UnmapWindow(b *xturbo.Buf, window Window) xturbo.Seq {
74+ p, seq := b.Request(10, 0, 4)
75+ if p == nil {
76+ return 0
77+ }
78+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
79+ return seq
80+}
81+
82+func UnmapSubwindows(b *xturbo.Buf, window Window) xturbo.Seq {
83+ p, seq := b.Request(11, 0, 4)
84+ if p == nil {
85+ return 0
86+ }
87+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
88+ return seq
89+}
90+
91+func CirculateWindow(b *xturbo.Buf, direction Circulate, window Window) xturbo.Seq {
92+ p, seq := b.Request(13, uint8(direction), 4)
93+ if p == nil {
94+ return 0
95+ }
96+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
97+ return seq
98+}
99+
100+func GetGeometry(b *xturbo.Buf, drawable Drawable) xturbo.Seq {
101+ p, seq := b.Request(14, 0, 4)
102+ if p == nil {
103+ return 0
104+ }
105+ binary.LittleEndian.PutUint32(p[0:], uint32(drawable))
106+ return seq
107+}
108+
109+func QueryTree(b *xturbo.Buf, window Window) xturbo.Seq {
110+ p, seq := b.Request(15, 0, 4)
111+ if p == nil {
112+ return 0
113+ }
114+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
115+ return seq
116+}
117+
118+func GetAtomName(b *xturbo.Buf, atom Atom) xturbo.Seq {
119+ p, seq := b.Request(17, 0, 4)
120+ if p == nil {
121+ return 0
122+ }
123+ binary.LittleEndian.PutUint32(p[0:], uint32(atom))
124+ return seq
125+}
126+
127+func DeleteProperty(b *xturbo.Buf, window Window, property Atom) xturbo.Seq {
128+ p, seq := b.Request(19, 0, 8)
129+ if p == nil {
130+ return 0
131+ }
132+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
133+ binary.LittleEndian.PutUint32(p[4:], uint32(property))
134+ return seq
135+}
136+
137+func GetProperty(b *xturbo.Buf, delete bool, window Window, property Atom, type_ Atom, longOffset uint32, longLength uint32) xturbo.Seq {
138+ var data uint8
139+ if delete {
140+ data = 1
141+ }
142+ p, seq := b.Request(20, data, 20)
143+ if p == nil {
144+ return 0
145+ }
146+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
147+ binary.LittleEndian.PutUint32(p[4:], uint32(property))
148+ binary.LittleEndian.PutUint32(p[8:], uint32(type_))
149+ binary.LittleEndian.PutUint32(p[12:], uint32(longOffset))
150+ binary.LittleEndian.PutUint32(p[16:], uint32(longLength))
151+ return seq
152+}
153+
154+func ListProperties(b *xturbo.Buf, window Window) xturbo.Seq {
155+ p, seq := b.Request(21, 0, 4)
156+ if p == nil {
157+ return 0
158+ }
159+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
160+ return seq
161+}
162+
163+func SetSelectionOwner(b *xturbo.Buf, owner Window, selection Atom, time Timestamp) xturbo.Seq {
164+ p, seq := b.Request(22, 0, 12)
165+ if p == nil {
166+ return 0
167+ }
168+ binary.LittleEndian.PutUint32(p[0:], uint32(owner))
169+ binary.LittleEndian.PutUint32(p[4:], uint32(selection))
170+ binary.LittleEndian.PutUint32(p[8:], uint32(time))
171+ return seq
172+}
173+
174+func GetSelectionOwner(b *xturbo.Buf, selection Atom) xturbo.Seq {
175+ p, seq := b.Request(23, 0, 4)
176+ if p == nil {
177+ return 0
178+ }
179+ binary.LittleEndian.PutUint32(p[0:], uint32(selection))
180+ return seq
181+}
182+
183+func ConvertSelection(b *xturbo.Buf, requestor Window, selection Atom, target Atom, property Atom, time Timestamp) xturbo.Seq {
184+ p, seq := b.Request(24, 0, 20)
185+ if p == nil {
186+ return 0
187+ }
188+ binary.LittleEndian.PutUint32(p[0:], uint32(requestor))
189+ binary.LittleEndian.PutUint32(p[4:], uint32(selection))
190+ binary.LittleEndian.PutUint32(p[8:], uint32(target))
191+ binary.LittleEndian.PutUint32(p[12:], uint32(property))
192+ binary.LittleEndian.PutUint32(p[16:], uint32(time))
193+ return seq
194+}
195+
196+func GrabPointer(b *xturbo.Buf, ownerEvents bool, grabWindow Window, eventMask EventMask, pointerMode GrabMode, keyboardMode GrabMode, confineTo Window, cursor Cursor, time Timestamp) xturbo.Seq {
197+ var data uint8
198+ if ownerEvents {
199+ data = 1
200+ }
201+ p, seq := b.Request(26, data, 20)
202+ if p == nil {
203+ return 0
204+ }
205+ binary.LittleEndian.PutUint32(p[0:], uint32(grabWindow))
206+ binary.LittleEndian.PutUint16(p[4:], uint16(eventMask))
207+ p[6:][0] = byte(pointerMode)
208+ p[7:][0] = byte(keyboardMode)
209+ binary.LittleEndian.PutUint32(p[8:], uint32(confineTo))
210+ binary.LittleEndian.PutUint32(p[12:], uint32(cursor))
211+ binary.LittleEndian.PutUint32(p[16:], uint32(time))
212+ return seq
213+}
214+
215+func UngrabPointer(b *xturbo.Buf, time Timestamp) xturbo.Seq {
216+ p, seq := b.Request(27, 0, 4)
217+ if p == nil {
218+ return 0
219+ }
220+ binary.LittleEndian.PutUint32(p[0:], uint32(time))
221+ return seq
222+}
223+
224+func GrabButton(b *xturbo.Buf, ownerEvents bool, grabWindow Window, eventMask EventMask, pointerMode GrabMode, keyboardMode GrabMode, confineTo Window, cursor Cursor, button ButtonIndex, modifiers ModMask) xturbo.Seq {
225+ var data uint8
226+ if ownerEvents {
227+ data = 1
228+ }
229+ p, seq := b.Request(28, data, 20)
230+ if p == nil {
231+ return 0
232+ }
233+ binary.LittleEndian.PutUint32(p[0:], uint32(grabWindow))
234+ binary.LittleEndian.PutUint16(p[4:], uint16(eventMask))
235+ p[6:][0] = byte(pointerMode)
236+ p[7:][0] = byte(keyboardMode)
237+ binary.LittleEndian.PutUint32(p[8:], uint32(confineTo))
238+ binary.LittleEndian.PutUint32(p[12:], uint32(cursor))
239+ p[16:][0] = byte(button)
240+ binary.LittleEndian.PutUint16(p[18:], uint16(modifiers))
241+ return seq
242+}
243+
244+func UngrabButton(b *xturbo.Buf, button ButtonIndex, grabWindow Window, modifiers ModMask) xturbo.Seq {
245+ p, seq := b.Request(29, uint8(button), 8)
246+ if p == nil {
247+ return 0
248+ }
249+ binary.LittleEndian.PutUint32(p[0:], uint32(grabWindow))
250+ binary.LittleEndian.PutUint16(p[4:], uint16(modifiers))
251+ return seq
252+}
253+
254+func ChangeActivePointerGrab(b *xturbo.Buf, cursor Cursor, time Timestamp, eventMask EventMask) xturbo.Seq {
255+ p, seq := b.Request(30, 0, 12)
256+ if p == nil {
257+ return 0
258+ }
259+ binary.LittleEndian.PutUint32(p[0:], uint32(cursor))
260+ binary.LittleEndian.PutUint32(p[4:], uint32(time))
261+ binary.LittleEndian.PutUint16(p[8:], uint16(eventMask))
262+ return seq
263+}
264+
265+func GrabKeyboard(b *xturbo.Buf, ownerEvents bool, grabWindow Window, time Timestamp, pointerMode GrabMode, keyboardMode GrabMode) xturbo.Seq {
266+ var data uint8
267+ if ownerEvents {
268+ data = 1
269+ }
270+ p, seq := b.Request(31, data, 12)
271+ if p == nil {
272+ return 0
273+ }
274+ binary.LittleEndian.PutUint32(p[0:], uint32(grabWindow))
275+ binary.LittleEndian.PutUint32(p[4:], uint32(time))
276+ p[8:][0] = byte(pointerMode)
277+ p[9:][0] = byte(keyboardMode)
278+ return seq
279+}
280+
281+func UngrabKeyboard(b *xturbo.Buf, time Timestamp) xturbo.Seq {
282+ p, seq := b.Request(32, 0, 4)
283+ if p == nil {
284+ return 0
285+ }
286+ binary.LittleEndian.PutUint32(p[0:], uint32(time))
287+ return seq
288+}
289+
290+func GrabKey(b *xturbo.Buf, ownerEvents bool, grabWindow Window, modifiers ModMask, key Keycode, pointerMode GrabMode, keyboardMode GrabMode) xturbo.Seq {
291+ var data uint8
292+ if ownerEvents {
293+ data = 1
294+ }
295+ p, seq := b.Request(33, data, 12)
296+ if p == nil {
297+ return 0
298+ }
299+ binary.LittleEndian.PutUint32(p[0:], uint32(grabWindow))
300+ binary.LittleEndian.PutUint16(p[4:], uint16(modifiers))
301+ p[6:][0] = byte(key)
302+ p[7:][0] = byte(pointerMode)
303+ p[8:][0] = byte(keyboardMode)
304+ return seq
305+}
306+
307+func UngrabKey(b *xturbo.Buf, key Keycode, grabWindow Window, modifiers ModMask) xturbo.Seq {
308+ p, seq := b.Request(34, uint8(key), 8)
309+ if p == nil {
310+ return 0
311+ }
312+ binary.LittleEndian.PutUint32(p[0:], uint32(grabWindow))
313+ binary.LittleEndian.PutUint16(p[4:], uint16(modifiers))
314+ return seq
315+}
316+
317+func AllowEvents(b *xturbo.Buf, mode Allow, time Timestamp) xturbo.Seq {
318+ p, seq := b.Request(35, uint8(mode), 4)
319+ if p == nil {
320+ return 0
321+ }
322+ binary.LittleEndian.PutUint32(p[0:], uint32(time))
323+ return seq
324+}
325+
326+func GrabServer(b *xturbo.Buf) xturbo.Seq {
327+ p, seq := b.Request(36, 0, 0)
328+ if p == nil {
329+ return 0
330+ }
331+ return seq
332+}
333+
334+func UngrabServer(b *xturbo.Buf) xturbo.Seq {
335+ p, seq := b.Request(37, 0, 0)
336+ if p == nil {
337+ return 0
338+ }
339+ return seq
340+}
341+
342+func QueryPointer(b *xturbo.Buf, window Window) xturbo.Seq {
343+ p, seq := b.Request(38, 0, 4)
344+ if p == nil {
345+ return 0
346+ }
347+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
348+ return seq
349+}
350+
351+func GetMotionEvents(b *xturbo.Buf, window Window, start Timestamp, stop Timestamp) xturbo.Seq {
352+ p, seq := b.Request(39, 0, 12)
353+ if p == nil {
354+ return 0
355+ }
356+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
357+ binary.LittleEndian.PutUint32(p[4:], uint32(start))
358+ binary.LittleEndian.PutUint32(p[8:], uint32(stop))
359+ return seq
360+}
361+
362+func TranslateCoordinates(b *xturbo.Buf, srcWindow Window, dstWindow Window, srcX int16, srcY int16) xturbo.Seq {
363+ p, seq := b.Request(40, 0, 12)
364+ if p == nil {
365+ return 0
366+ }
367+ binary.LittleEndian.PutUint32(p[0:], uint32(srcWindow))
368+ binary.LittleEndian.PutUint32(p[4:], uint32(dstWindow))
369+ binary.LittleEndian.PutUint16(p[8:], uint16(srcX))
370+ binary.LittleEndian.PutUint16(p[10:], uint16(srcY))
371+ return seq
372+}
373+
374+func WarpPointer(b *xturbo.Buf, srcWindow Window, dstWindow Window, srcX int16, srcY int16, srcWidth uint16, srcHeight uint16, dstX int16, dstY int16) xturbo.Seq {
375+ p, seq := b.Request(41, 0, 20)
376+ if p == nil {
377+ return 0
378+ }
379+ binary.LittleEndian.PutUint32(p[0:], uint32(srcWindow))
380+ binary.LittleEndian.PutUint32(p[4:], uint32(dstWindow))
381+ binary.LittleEndian.PutUint16(p[8:], uint16(srcX))
382+ binary.LittleEndian.PutUint16(p[10:], uint16(srcY))
383+ binary.LittleEndian.PutUint16(p[12:], uint16(srcWidth))
384+ binary.LittleEndian.PutUint16(p[14:], uint16(srcHeight))
385+ binary.LittleEndian.PutUint16(p[16:], uint16(dstX))
386+ binary.LittleEndian.PutUint16(p[18:], uint16(dstY))
387+ return seq
388+}
389+
390+func SetInputFocus(b *xturbo.Buf, revertTo InputFocus, focus Window, time Timestamp) xturbo.Seq {
391+ p, seq := b.Request(42, uint8(revertTo), 8)
392+ if p == nil {
393+ return 0
394+ }
395+ binary.LittleEndian.PutUint32(p[0:], uint32(focus))
396+ binary.LittleEndian.PutUint32(p[4:], uint32(time))
397+ return seq
398+}
399+
400+func GetInputFocus(b *xturbo.Buf) xturbo.Seq {
401+ p, seq := b.Request(43, 0, 0)
402+ if p == nil {
403+ return 0
404+ }
405+ return seq
406+}
407+
408+func QueryKeymap(b *xturbo.Buf) xturbo.Seq {
409+ p, seq := b.Request(44, 0, 0)
410+ if p == nil {
411+ return 0
412+ }
413+ return seq
414+}
415+
416+func CloseFont(b *xturbo.Buf, font Font) xturbo.Seq {
417+ p, seq := b.Request(46, 0, 4)
418+ if p == nil {
419+ return 0
420+ }
421+ binary.LittleEndian.PutUint32(p[0:], uint32(font))
422+ return seq
423+}
424+
425+func QueryFont(b *xturbo.Buf, font Fontable) xturbo.Seq {
426+ p, seq := b.Request(47, 0, 4)
427+ if p == nil {
428+ return 0
429+ }
430+ binary.LittleEndian.PutUint32(p[0:], uint32(font))
431+ return seq
432+}
433+
434+func GetFontPath(b *xturbo.Buf) xturbo.Seq {
435+ p, seq := b.Request(52, 0, 0)
436+ if p == nil {
437+ return 0
438+ }
439+ return seq
440+}
441+
442+func CreatePixmap(b *xturbo.Buf, depth uint8, pid Pixmap, drawable Drawable, width uint16, height uint16) xturbo.Seq {
443+ p, seq := b.Request(53, uint8(depth), 12)
444+ if p == nil {
445+ return 0
446+ }
447+ binary.LittleEndian.PutUint32(p[0:], uint32(pid))
448+ binary.LittleEndian.PutUint32(p[4:], uint32(drawable))
449+ binary.LittleEndian.PutUint16(p[8:], uint16(width))
450+ binary.LittleEndian.PutUint16(p[10:], uint16(height))
451+ return seq
452+}
453+
454+func FreePixmap(b *xturbo.Buf, pixmap Pixmap) xturbo.Seq {
455+ p, seq := b.Request(54, 0, 4)
456+ if p == nil {
457+ return 0
458+ }
459+ binary.LittleEndian.PutUint32(p[0:], uint32(pixmap))
460+ return seq
461+}
462+
463+func CopyGC(b *xturbo.Buf, srcGc Gcontext, dstGc Gcontext, valueMask Gc) xturbo.Seq {
464+ p, seq := b.Request(57, 0, 12)
465+ if p == nil {
466+ return 0
467+ }
468+ binary.LittleEndian.PutUint32(p[0:], uint32(srcGc))
469+ binary.LittleEndian.PutUint32(p[4:], uint32(dstGc))
470+ binary.LittleEndian.PutUint32(p[8:], uint32(valueMask))
471+ return seq
472+}
473+
474+func FreeGC(b *xturbo.Buf, gc Gcontext) xturbo.Seq {
475+ p, seq := b.Request(60, 0, 4)
476+ if p == nil {
477+ return 0
478+ }
479+ binary.LittleEndian.PutUint32(p[0:], uint32(gc))
480+ return seq
481+}
482+
483+func ClearArea(b *xturbo.Buf, exposures bool, window Window, x int16, y int16, width uint16, height uint16) xturbo.Seq {
484+ var data uint8
485+ if exposures {
486+ data = 1
487+ }
488+ p, seq := b.Request(61, data, 12)
489+ if p == nil {
490+ return 0
491+ }
492+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
493+ binary.LittleEndian.PutUint16(p[4:], uint16(x))
494+ binary.LittleEndian.PutUint16(p[6:], uint16(y))
495+ binary.LittleEndian.PutUint16(p[8:], uint16(width))
496+ binary.LittleEndian.PutUint16(p[10:], uint16(height))
497+ return seq
498+}
499+
500+func CopyArea(b *xturbo.Buf, srcDrawable Drawable, dstDrawable Drawable, gc Gcontext, srcX int16, srcY int16, dstX int16, dstY int16, width uint16, height uint16) xturbo.Seq {
501+ p, seq := b.Request(62, 0, 24)
502+ if p == nil {
503+ return 0
504+ }
505+ binary.LittleEndian.PutUint32(p[0:], uint32(srcDrawable))
506+ binary.LittleEndian.PutUint32(p[4:], uint32(dstDrawable))
507+ binary.LittleEndian.PutUint32(p[8:], uint32(gc))
508+ binary.LittleEndian.PutUint16(p[12:], uint16(srcX))
509+ binary.LittleEndian.PutUint16(p[14:], uint16(srcY))
510+ binary.LittleEndian.PutUint16(p[16:], uint16(dstX))
511+ binary.LittleEndian.PutUint16(p[18:], uint16(dstY))
512+ binary.LittleEndian.PutUint16(p[20:], uint16(width))
513+ binary.LittleEndian.PutUint16(p[22:], uint16(height))
514+ return seq
515+}
516+
517+func CopyPlane(b *xturbo.Buf, srcDrawable Drawable, dstDrawable Drawable, gc Gcontext, srcX int16, srcY int16, dstX int16, dstY int16, width uint16, height uint16, bitPlane uint32) xturbo.Seq {
518+ p, seq := b.Request(63, 0, 28)
519+ if p == nil {
520+ return 0
521+ }
522+ binary.LittleEndian.PutUint32(p[0:], uint32(srcDrawable))
523+ binary.LittleEndian.PutUint32(p[4:], uint32(dstDrawable))
524+ binary.LittleEndian.PutUint32(p[8:], uint32(gc))
525+ binary.LittleEndian.PutUint16(p[12:], uint16(srcX))
526+ binary.LittleEndian.PutUint16(p[14:], uint16(srcY))
527+ binary.LittleEndian.PutUint16(p[16:], uint16(dstX))
528+ binary.LittleEndian.PutUint16(p[18:], uint16(dstY))
529+ binary.LittleEndian.PutUint16(p[20:], uint16(width))
530+ binary.LittleEndian.PutUint16(p[22:], uint16(height))
531+ binary.LittleEndian.PutUint32(p[24:], uint32(bitPlane))
532+ return seq
533+}
534+
535+func GetImage(b *xturbo.Buf, format ImageFormat, drawable Drawable, x int16, y int16, width uint16, height uint16, planeMask uint32) xturbo.Seq {
536+ p, seq := b.Request(73, uint8(format), 16)
537+ if p == nil {
538+ return 0
539+ }
540+ binary.LittleEndian.PutUint32(p[0:], uint32(drawable))
541+ binary.LittleEndian.PutUint16(p[4:], uint16(x))
542+ binary.LittleEndian.PutUint16(p[6:], uint16(y))
543+ binary.LittleEndian.PutUint16(p[8:], uint16(width))
544+ binary.LittleEndian.PutUint16(p[10:], uint16(height))
545+ binary.LittleEndian.PutUint32(p[12:], uint32(planeMask))
546+ return seq
547+}
548+
549+func CreateColormap(b *xturbo.Buf, alloc ColormapAlloc, mid Colormap, window Window, visual Visualid) xturbo.Seq {
550+ p, seq := b.Request(78, uint8(alloc), 12)
551+ if p == nil {
552+ return 0
553+ }
554+ binary.LittleEndian.PutUint32(p[0:], uint32(mid))
555+ binary.LittleEndian.PutUint32(p[4:], uint32(window))
556+ binary.LittleEndian.PutUint32(p[8:], uint32(visual))
557+ return seq
558+}
559+
560+func FreeColormap(b *xturbo.Buf, cmap Colormap) xturbo.Seq {
561+ p, seq := b.Request(79, 0, 4)
562+ if p == nil {
563+ return 0
564+ }
565+ binary.LittleEndian.PutUint32(p[0:], uint32(cmap))
566+ return seq
567+}
568+
569+func CopyColormapAndFree(b *xturbo.Buf, mid Colormap, srcCmap Colormap) xturbo.Seq {
570+ p, seq := b.Request(80, 0, 8)
571+ if p == nil {
572+ return 0
573+ }
574+ binary.LittleEndian.PutUint32(p[0:], uint32(mid))
575+ binary.LittleEndian.PutUint32(p[4:], uint32(srcCmap))
576+ return seq
577+}
578+
579+func InstallColormap(b *xturbo.Buf, cmap Colormap) xturbo.Seq {
580+ p, seq := b.Request(81, 0, 4)
581+ if p == nil {
582+ return 0
583+ }
584+ binary.LittleEndian.PutUint32(p[0:], uint32(cmap))
585+ return seq
586+}
587+
588+func UninstallColormap(b *xturbo.Buf, cmap Colormap) xturbo.Seq {
589+ p, seq := b.Request(82, 0, 4)
590+ if p == nil {
591+ return 0
592+ }
593+ binary.LittleEndian.PutUint32(p[0:], uint32(cmap))
594+ return seq
595+}
596+
597+func ListInstalledColormaps(b *xturbo.Buf, window Window) xturbo.Seq {
598+ p, seq := b.Request(83, 0, 4)
599+ if p == nil {
600+ return 0
601+ }
602+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
603+ return seq
604+}
605+
606+func AllocColor(b *xturbo.Buf, cmap Colormap, red uint16, green uint16, blue uint16) xturbo.Seq {
607+ p, seq := b.Request(84, 0, 12)
608+ if p == nil {
609+ return 0
610+ }
611+ binary.LittleEndian.PutUint32(p[0:], uint32(cmap))
612+ binary.LittleEndian.PutUint16(p[4:], uint16(red))
613+ binary.LittleEndian.PutUint16(p[6:], uint16(green))
614+ binary.LittleEndian.PutUint16(p[8:], uint16(blue))
615+ return seq
616+}
617+
618+func AllocColorCells(b *xturbo.Buf, contiguous bool, cmap Colormap, colors uint16, planes uint16) xturbo.Seq {
619+ var data uint8
620+ if contiguous {
621+ data = 1
622+ }
623+ p, seq := b.Request(86, data, 8)
624+ if p == nil {
625+ return 0
626+ }
627+ binary.LittleEndian.PutUint32(p[0:], uint32(cmap))
628+ binary.LittleEndian.PutUint16(p[4:], uint16(colors))
629+ binary.LittleEndian.PutUint16(p[6:], uint16(planes))
630+ return seq
631+}
632+
633+func AllocColorPlanes(b *xturbo.Buf, contiguous bool, cmap Colormap, colors uint16, reds uint16, greens uint16, blues uint16) xturbo.Seq {
634+ var data uint8
635+ if contiguous {
636+ data = 1
637+ }
638+ p, seq := b.Request(87, data, 12)
639+ if p == nil {
640+ return 0
641+ }
642+ binary.LittleEndian.PutUint32(p[0:], uint32(cmap))
643+ binary.LittleEndian.PutUint16(p[4:], uint16(colors))
644+ binary.LittleEndian.PutUint16(p[6:], uint16(reds))
645+ binary.LittleEndian.PutUint16(p[8:], uint16(greens))
646+ binary.LittleEndian.PutUint16(p[10:], uint16(blues))
647+ return seq
648+}
649+
650+func CreateCursor(b *xturbo.Buf, cid Cursor, source Pixmap, mask Pixmap, foreRed uint16, foreGreen uint16, foreBlue uint16, backRed uint16, backGreen uint16, backBlue uint16, x uint16, y uint16) xturbo.Seq {
651+ p, seq := b.Request(93, 0, 28)
652+ if p == nil {
653+ return 0
654+ }
655+ binary.LittleEndian.PutUint32(p[0:], uint32(cid))
656+ binary.LittleEndian.PutUint32(p[4:], uint32(source))
657+ binary.LittleEndian.PutUint32(p[8:], uint32(mask))
658+ binary.LittleEndian.PutUint16(p[12:], uint16(foreRed))
659+ binary.LittleEndian.PutUint16(p[14:], uint16(foreGreen))
660+ binary.LittleEndian.PutUint16(p[16:], uint16(foreBlue))
661+ binary.LittleEndian.PutUint16(p[18:], uint16(backRed))
662+ binary.LittleEndian.PutUint16(p[20:], uint16(backGreen))
663+ binary.LittleEndian.PutUint16(p[22:], uint16(backBlue))
664+ binary.LittleEndian.PutUint16(p[24:], uint16(x))
665+ binary.LittleEndian.PutUint16(p[26:], uint16(y))
666+ return seq
667+}
668+
669+func CreateGlyphCursor(b *xturbo.Buf, cid Cursor, sourceFont Font, maskFont Font, sourceChar uint16, maskChar uint16, foreRed uint16, foreGreen uint16, foreBlue uint16, backRed uint16, backGreen uint16, backBlue uint16) xturbo.Seq {
670+ p, seq := b.Request(94, 0, 28)
671+ if p == nil {
672+ return 0
673+ }
674+ binary.LittleEndian.PutUint32(p[0:], uint32(cid))
675+ binary.LittleEndian.PutUint32(p[4:], uint32(sourceFont))
676+ binary.LittleEndian.PutUint32(p[8:], uint32(maskFont))
677+ binary.LittleEndian.PutUint16(p[12:], uint16(sourceChar))
678+ binary.LittleEndian.PutUint16(p[14:], uint16(maskChar))
679+ binary.LittleEndian.PutUint16(p[16:], uint16(foreRed))
680+ binary.LittleEndian.PutUint16(p[18:], uint16(foreGreen))
681+ binary.LittleEndian.PutUint16(p[20:], uint16(foreBlue))
682+ binary.LittleEndian.PutUint16(p[22:], uint16(backRed))
683+ binary.LittleEndian.PutUint16(p[24:], uint16(backGreen))
684+ binary.LittleEndian.PutUint16(p[26:], uint16(backBlue))
685+ return seq
686+}
687+
688+func FreeCursor(b *xturbo.Buf, cursor Cursor) xturbo.Seq {
689+ p, seq := b.Request(95, 0, 4)
690+ if p == nil {
691+ return 0
692+ }
693+ binary.LittleEndian.PutUint32(p[0:], uint32(cursor))
694+ return seq
695+}
696+
697+func RecolorCursor(b *xturbo.Buf, cursor Cursor, foreRed uint16, foreGreen uint16, foreBlue uint16, backRed uint16, backGreen uint16, backBlue uint16) xturbo.Seq {
698+ p, seq := b.Request(96, 0, 16)
699+ if p == nil {
700+ return 0
701+ }
702+ binary.LittleEndian.PutUint32(p[0:], uint32(cursor))
703+ binary.LittleEndian.PutUint16(p[4:], uint16(foreRed))
704+ binary.LittleEndian.PutUint16(p[6:], uint16(foreGreen))
705+ binary.LittleEndian.PutUint16(p[8:], uint16(foreBlue))
706+ binary.LittleEndian.PutUint16(p[10:], uint16(backRed))
707+ binary.LittleEndian.PutUint16(p[12:], uint16(backGreen))
708+ binary.LittleEndian.PutUint16(p[14:], uint16(backBlue))
709+ return seq
710+}
711+
712+func QueryBestSize(b *xturbo.Buf, class QueryShapeOf, drawable Drawable, width uint16, height uint16) xturbo.Seq {
713+ p, seq := b.Request(97, uint8(class), 8)
714+ if p == nil {
715+ return 0
716+ }
717+ binary.LittleEndian.PutUint32(p[0:], uint32(drawable))
718+ binary.LittleEndian.PutUint16(p[4:], uint16(width))
719+ binary.LittleEndian.PutUint16(p[6:], uint16(height))
720+ return seq
721+}
722+
723+func ListExtensions(b *xturbo.Buf) xturbo.Seq {
724+ p, seq := b.Request(99, 0, 0)
725+ if p == nil {
726+ return 0
727+ }
728+ return seq
729+}
730+
731+func GetKeyboardMapping(b *xturbo.Buf, firstKeycode Keycode, count uint8) xturbo.Seq {
732+ p, seq := b.Request(101, 0, 4)
733+ if p == nil {
734+ return 0
735+ }
736+ p[0:][0] = byte(firstKeycode)
737+ p[1:][0] = byte(count)
738+ return seq
739+}
740+
741+func GetKeyboardControl(b *xturbo.Buf) xturbo.Seq {
742+ p, seq := b.Request(103, 0, 0)
743+ if p == nil {
744+ return 0
745+ }
746+ return seq
747+}
748+
749+func Bell(b *xturbo.Buf, percent int8) xturbo.Seq {
750+ p, seq := b.Request(104, uint8(percent), 0)
751+ if p == nil {
752+ return 0
753+ }
754+ return seq
755+}
756+
757+func ChangePointerControl(b *xturbo.Buf, accelerationNumerator int16, accelerationDenominator int16, threshold int16, doAcceleration bool, doThreshold bool) xturbo.Seq {
758+ p, seq := b.Request(105, 0, 8)
759+ if p == nil {
760+ return 0
761+ }
762+ binary.LittleEndian.PutUint16(p[0:], uint16(accelerationNumerator))
763+ binary.LittleEndian.PutUint16(p[2:], uint16(accelerationDenominator))
764+ binary.LittleEndian.PutUint16(p[4:], uint16(threshold))
765+ if doAcceleration {
766+ p[6:][0] = 1
767+ } else {
768+ p[6:][0] = 0
769+ }
770+ if doThreshold {
771+ p[7:][0] = 1
772+ } else {
773+ p[7:][0] = 0
774+ }
775+ return seq
776+}
777+
778+func GetPointerControl(b *xturbo.Buf) xturbo.Seq {
779+ p, seq := b.Request(106, 0, 0)
780+ if p == nil {
781+ return 0
782+ }
783+ return seq
784+}
785+
786+func SetScreenSaver(b *xturbo.Buf, timeout int16, interval int16, preferBlanking Blanking, allowExposures Exposures) xturbo.Seq {
787+ p, seq := b.Request(107, 0, 8)
788+ if p == nil {
789+ return 0
790+ }
791+ binary.LittleEndian.PutUint16(p[0:], uint16(timeout))
792+ binary.LittleEndian.PutUint16(p[2:], uint16(interval))
793+ p[4:][0] = byte(preferBlanking)
794+ p[5:][0] = byte(allowExposures)
795+ return seq
796+}
797+
798+func GetScreenSaver(b *xturbo.Buf) xturbo.Seq {
799+ p, seq := b.Request(108, 0, 0)
800+ if p == nil {
801+ return 0
802+ }
803+ return seq
804+}
805+
806+func ListHosts(b *xturbo.Buf) xturbo.Seq {
807+ p, seq := b.Request(110, 0, 0)
808+ if p == nil {
809+ return 0
810+ }
811+ return seq
812+}
813+
814+func SetAccessControl(b *xturbo.Buf, mode AccessControl) xturbo.Seq {
815+ p, seq := b.Request(111, uint8(mode), 0)
816+ if p == nil {
817+ return 0
818+ }
819+ return seq
820+}
821+
822+func SetCloseDownMode(b *xturbo.Buf, mode CloseDown) xturbo.Seq {
823+ p, seq := b.Request(112, uint8(mode), 0)
824+ if p == nil {
825+ return 0
826+ }
827+ return seq
828+}
829+
830+func KillClient(b *xturbo.Buf, resource uint32) xturbo.Seq {
831+ p, seq := b.Request(113, 0, 4)
832+ if p == nil {
833+ return 0
834+ }
835+ binary.LittleEndian.PutUint32(p[0:], uint32(resource))
836+ return seq
837+}
838+
839+func ForceScreenSaver(b *xturbo.Buf, mode ScreenSaver) xturbo.Seq {
840+ p, seq := b.Request(115, uint8(mode), 0)
841+ if p == nil {
842+ return 0
843+ }
844+ return seq
845+}
846+
847+func GetPointerMapping(b *xturbo.Buf) xturbo.Seq {
848+ p, seq := b.Request(117, 0, 0)
849+ if p == nil {
850+ return 0
851+ }
852+ return seq
853+}
854+
855+func GetModifierMapping(b *xturbo.Buf) xturbo.Seq {
856+ p, seq := b.Request(119, 0, 0)
857+ if p == nil {
858+ return 0
859+ }
860+ return seq
861+}
862+
863+func NoOperation(b *xturbo.Buf) xturbo.Seq {
864+ p, seq := b.Request(127, 0, 0)
865+ if p == nil {
866+ return 0
867+ }
868+ return seq
869+}
@@ -0,0 +1,869 @@
1+// Code generated by xtgen; DO NOT EDIT.
2+package xproto
3+
4+import "encoding/binary"
5+import "bnema.dev/xturbo"
6+
7+func GetWindowAttributes(b *xturbo.Buf, window Window) xturbo.Seq {
8+ p, seq := b.Request(3, 0, 4)
9+ if p == nil {
10+ return 0
11+ }
12+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
13+ return seq
14+}
15+
16+func DestroyWindow(b *xturbo.Buf, window Window) xturbo.Seq {
17+ p, seq := b.Request(4, 0, 4)
18+ if p == nil {
19+ return 0
20+ }
21+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
22+ return seq
23+}
24+
25+func DestroySubwindows(b *xturbo.Buf, window Window) xturbo.Seq {
26+ p, seq := b.Request(5, 0, 4)
27+ if p == nil {
28+ return 0
29+ }
30+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
31+ return seq
32+}
33+
34+func ChangeSaveSet(b *xturbo.Buf, mode SetMode, window Window) xturbo.Seq {
35+ p, seq := b.Request(6, uint8(mode), 4)
36+ if p == nil {
37+ return 0
38+ }
39+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
40+ return seq
41+}
42+
43+func ReparentWindow(b *xturbo.Buf, window Window, parent Window, x int16, y int16) xturbo.Seq {
44+ p, seq := b.Request(7, 0, 12)
45+ if p == nil {
46+ return 0
47+ }
48+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
49+ binary.LittleEndian.PutUint32(p[4:], uint32(parent))
50+ binary.LittleEndian.PutUint16(p[8:], uint16(x))
51+ binary.LittleEndian.PutUint16(p[10:], uint16(y))
52+ return seq
53+}
54+
55+func MapWindow(b *xturbo.Buf, window Window) xturbo.Seq {
56+ p, seq := b.Request(8, 0, 4)
57+ if p == nil {
58+ return 0
59+ }
60+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
61+ return seq
62+}
63+
64+func MapSubwindows(b *xturbo.Buf, window Window) xturbo.Seq {
65+ p, seq := b.Request(9, 0, 4)
66+ if p == nil {
67+ return 0
68+ }
69+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
70+ return seq
71+}
72+
73+func UnmapWindow(b *xturbo.Buf, window Window) xturbo.Seq {
74+ p, seq := b.Request(10, 0, 4)
75+ if p == nil {
76+ return 0
77+ }
78+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
79+ return seq
80+}
81+
82+func UnmapSubwindows(b *xturbo.Buf, window Window) xturbo.Seq {
83+ p, seq := b.Request(11, 0, 4)
84+ if p == nil {
85+ return 0
86+ }
87+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
88+ return seq
89+}
90+
91+func CirculateWindow(b *xturbo.Buf, direction Circulate, window Window) xturbo.Seq {
92+ p, seq := b.Request(13, uint8(direction), 4)
93+ if p == nil {
94+ return 0
95+ }
96+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
97+ return seq
98+}
99+
100+func GetGeometry(b *xturbo.Buf, drawable Drawable) xturbo.Seq {
101+ p, seq := b.Request(14, 0, 4)
102+ if p == nil {
103+ return 0
104+ }
105+ binary.LittleEndian.PutUint32(p[0:], uint32(drawable))
106+ return seq
107+}
108+
109+func QueryTree(b *xturbo.Buf, window Window) xturbo.Seq {
110+ p, seq := b.Request(15, 0, 4)
111+ if p == nil {
112+ return 0
113+ }
114+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
115+ return seq
116+}
117+
118+func GetAtomName(b *xturbo.Buf, atom Atom) xturbo.Seq {
119+ p, seq := b.Request(17, 0, 4)
120+ if p == nil {
121+ return 0
122+ }
123+ binary.LittleEndian.PutUint32(p[0:], uint32(atom))
124+ return seq
125+}
126+
127+func DeleteProperty(b *xturbo.Buf, window Window, property Atom) xturbo.Seq {
128+ p, seq := b.Request(19, 0, 8)
129+ if p == nil {
130+ return 0
131+ }
132+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
133+ binary.LittleEndian.PutUint32(p[4:], uint32(property))
134+ return seq
135+}
136+
137+func GetProperty(b *xturbo.Buf, delete bool, window Window, property Atom, type_ Atom, longOffset uint32, longLength uint32) xturbo.Seq {
138+ var data uint8
139+ if delete {
140+ data = 1
141+ }
142+ p, seq := b.Request(20, data, 20)
143+ if p == nil {
144+ return 0
145+ }
146+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
147+ binary.LittleEndian.PutUint32(p[4:], uint32(property))
148+ binary.LittleEndian.PutUint32(p[8:], uint32(type_))
149+ binary.LittleEndian.PutUint32(p[12:], uint32(longOffset))
150+ binary.LittleEndian.PutUint32(p[16:], uint32(longLength))
151+ return seq
152+}
153+
154+func ListProperties(b *xturbo.Buf, window Window) xturbo.Seq {
155+ p, seq := b.Request(21, 0, 4)
156+ if p == nil {
157+ return 0
158+ }
159+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
160+ return seq
161+}
162+
163+func SetSelectionOwner(b *xturbo.Buf, owner Window, selection Atom, time Timestamp) xturbo.Seq {
164+ p, seq := b.Request(22, 0, 12)
165+ if p == nil {
166+ return 0
167+ }
168+ binary.LittleEndian.PutUint32(p[0:], uint32(owner))
169+ binary.LittleEndian.PutUint32(p[4:], uint32(selection))
170+ binary.LittleEndian.PutUint32(p[8:], uint32(time))
171+ return seq
172+}
173+
174+func GetSelectionOwner(b *xturbo.Buf, selection Atom) xturbo.Seq {
175+ p, seq := b.Request(23, 0, 4)
176+ if p == nil {
177+ return 0
178+ }
179+ binary.LittleEndian.PutUint32(p[0:], uint32(selection))
180+ return seq
181+}
182+
183+func ConvertSelection(b *xturbo.Buf, requestor Window, selection Atom, target Atom, property Atom, time Timestamp) xturbo.Seq {
184+ p, seq := b.Request(24, 0, 20)
185+ if p == nil {
186+ return 0
187+ }
188+ binary.LittleEndian.PutUint32(p[0:], uint32(requestor))
189+ binary.LittleEndian.PutUint32(p[4:], uint32(selection))
190+ binary.LittleEndian.PutUint32(p[8:], uint32(target))
191+ binary.LittleEndian.PutUint32(p[12:], uint32(property))
192+ binary.LittleEndian.PutUint32(p[16:], uint32(time))
193+ return seq
194+}
195+
196+func GrabPointer(b *xturbo.Buf, ownerEvents bool, grabWindow Window, eventMask EventMask, pointerMode GrabMode, keyboardMode GrabMode, confineTo Window, cursor Cursor, time Timestamp) xturbo.Seq {
197+ var data uint8
198+ if ownerEvents {
199+ data = 1
200+ }
201+ p, seq := b.Request(26, data, 20)
202+ if p == nil {
203+ return 0
204+ }
205+ binary.LittleEndian.PutUint32(p[0:], uint32(grabWindow))
206+ binary.LittleEndian.PutUint16(p[4:], uint16(eventMask))
207+ p[6:][0] = byte(pointerMode)
208+ p[7:][0] = byte(keyboardMode)
209+ binary.LittleEndian.PutUint32(p[8:], uint32(confineTo))
210+ binary.LittleEndian.PutUint32(p[12:], uint32(cursor))
211+ binary.LittleEndian.PutUint32(p[16:], uint32(time))
212+ return seq
213+}
214+
215+func UngrabPointer(b *xturbo.Buf, time Timestamp) xturbo.Seq {
216+ p, seq := b.Request(27, 0, 4)
217+ if p == nil {
218+ return 0
219+ }
220+ binary.LittleEndian.PutUint32(p[0:], uint32(time))
221+ return seq
222+}
223+
224+func GrabButton(b *xturbo.Buf, ownerEvents bool, grabWindow Window, eventMask EventMask, pointerMode GrabMode, keyboardMode GrabMode, confineTo Window, cursor Cursor, button ButtonIndex, modifiers ModMask) xturbo.Seq {
225+ var data uint8
226+ if ownerEvents {
227+ data = 1
228+ }
229+ p, seq := b.Request(28, data, 20)
230+ if p == nil {
231+ return 0
232+ }
233+ binary.LittleEndian.PutUint32(p[0:], uint32(grabWindow))
234+ binary.LittleEndian.PutUint16(p[4:], uint16(eventMask))
235+ p[6:][0] = byte(pointerMode)
236+ p[7:][0] = byte(keyboardMode)
237+ binary.LittleEndian.PutUint32(p[8:], uint32(confineTo))
238+ binary.LittleEndian.PutUint32(p[12:], uint32(cursor))
239+ p[16:][0] = byte(button)
240+ binary.LittleEndian.PutUint16(p[18:], uint16(modifiers))
241+ return seq
242+}
243+
244+func UngrabButton(b *xturbo.Buf, button ButtonIndex, grabWindow Window, modifiers ModMask) xturbo.Seq {
245+ p, seq := b.Request(29, uint8(button), 8)
246+ if p == nil {
247+ return 0
248+ }
249+ binary.LittleEndian.PutUint32(p[0:], uint32(grabWindow))
250+ binary.LittleEndian.PutUint16(p[4:], uint16(modifiers))
251+ return seq
252+}
253+
254+func ChangeActivePointerGrab(b *xturbo.Buf, cursor Cursor, time Timestamp, eventMask EventMask) xturbo.Seq {
255+ p, seq := b.Request(30, 0, 12)
256+ if p == nil {
257+ return 0
258+ }
259+ binary.LittleEndian.PutUint32(p[0:], uint32(cursor))
260+ binary.LittleEndian.PutUint32(p[4:], uint32(time))
261+ binary.LittleEndian.PutUint16(p[8:], uint16(eventMask))
262+ return seq
263+}
264+
265+func GrabKeyboard(b *xturbo.Buf, ownerEvents bool, grabWindow Window, time Timestamp, pointerMode GrabMode, keyboardMode GrabMode) xturbo.Seq {
266+ var data uint8
267+ if ownerEvents {
268+ data = 1
269+ }
270+ p, seq := b.Request(31, data, 12)
271+ if p == nil {
272+ return 0
273+ }
274+ binary.LittleEndian.PutUint32(p[0:], uint32(grabWindow))
275+ binary.LittleEndian.PutUint32(p[4:], uint32(time))
276+ p[8:][0] = byte(pointerMode)
277+ p[9:][0] = byte(keyboardMode)
278+ return seq
279+}
280+
281+func UngrabKeyboard(b *xturbo.Buf, time Timestamp) xturbo.Seq {
282+ p, seq := b.Request(32, 0, 4)
283+ if p == nil {
284+ return 0
285+ }
286+ binary.LittleEndian.PutUint32(p[0:], uint32(time))
287+ return seq
288+}
289+
290+func GrabKey(b *xturbo.Buf, ownerEvents bool, grabWindow Window, modifiers ModMask, key Keycode, pointerMode GrabMode, keyboardMode GrabMode) xturbo.Seq {
291+ var data uint8
292+ if ownerEvents {
293+ data = 1
294+ }
295+ p, seq := b.Request(33, data, 12)
296+ if p == nil {
297+ return 0
298+ }
299+ binary.LittleEndian.PutUint32(p[0:], uint32(grabWindow))
300+ binary.LittleEndian.PutUint16(p[4:], uint16(modifiers))
301+ p[6:][0] = byte(key)
302+ p[7:][0] = byte(pointerMode)
303+ p[8:][0] = byte(keyboardMode)
304+ return seq
305+}
306+
307+func UngrabKey(b *xturbo.Buf, key Keycode, grabWindow Window, modifiers ModMask) xturbo.Seq {
308+ p, seq := b.Request(34, uint8(key), 8)
309+ if p == nil {
310+ return 0
311+ }
312+ binary.LittleEndian.PutUint32(p[0:], uint32(grabWindow))
313+ binary.LittleEndian.PutUint16(p[4:], uint16(modifiers))
314+ return seq
315+}
316+
317+func AllowEvents(b *xturbo.Buf, mode Allow, time Timestamp) xturbo.Seq {
318+ p, seq := b.Request(35, uint8(mode), 4)
319+ if p == nil {
320+ return 0
321+ }
322+ binary.LittleEndian.PutUint32(p[0:], uint32(time))
323+ return seq
324+}
325+
326+func GrabServer(b *xturbo.Buf) xturbo.Seq {
327+ p, seq := b.Request(36, 0, 0)
328+ if p == nil {
329+ return 0
330+ }
331+ return seq
332+}
333+
334+func UngrabServer(b *xturbo.Buf) xturbo.Seq {
335+ p, seq := b.Request(37, 0, 0)
336+ if p == nil {
337+ return 0
338+ }
339+ return seq
340+}
341+
342+func QueryPointer(b *xturbo.Buf, window Window) xturbo.Seq {
343+ p, seq := b.Request(38, 0, 4)
344+ if p == nil {
345+ return 0
346+ }
347+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
348+ return seq
349+}
350+
351+func GetMotionEvents(b *xturbo.Buf, window Window, start Timestamp, stop Timestamp) xturbo.Seq {
352+ p, seq := b.Request(39, 0, 12)
353+ if p == nil {
354+ return 0
355+ }
356+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
357+ binary.LittleEndian.PutUint32(p[4:], uint32(start))
358+ binary.LittleEndian.PutUint32(p[8:], uint32(stop))
359+ return seq
360+}
361+
362+func TranslateCoordinates(b *xturbo.Buf, srcWindow Window, dstWindow Window, srcX int16, srcY int16) xturbo.Seq {
363+ p, seq := b.Request(40, 0, 12)
364+ if p == nil {
365+ return 0
366+ }
367+ binary.LittleEndian.PutUint32(p[0:], uint32(srcWindow))
368+ binary.LittleEndian.PutUint32(p[4:], uint32(dstWindow))
369+ binary.LittleEndian.PutUint16(p[8:], uint16(srcX))
370+ binary.LittleEndian.PutUint16(p[10:], uint16(srcY))
371+ return seq
372+}
373+
374+func WarpPointer(b *xturbo.Buf, srcWindow Window, dstWindow Window, srcX int16, srcY int16, srcWidth uint16, srcHeight uint16, dstX int16, dstY int16) xturbo.Seq {
375+ p, seq := b.Request(41, 0, 20)
376+ if p == nil {
377+ return 0
378+ }
379+ binary.LittleEndian.PutUint32(p[0:], uint32(srcWindow))
380+ binary.LittleEndian.PutUint32(p[4:], uint32(dstWindow))
381+ binary.LittleEndian.PutUint16(p[8:], uint16(srcX))
382+ binary.LittleEndian.PutUint16(p[10:], uint16(srcY))
383+ binary.LittleEndian.PutUint16(p[12:], uint16(srcWidth))
384+ binary.LittleEndian.PutUint16(p[14:], uint16(srcHeight))
385+ binary.LittleEndian.PutUint16(p[16:], uint16(dstX))
386+ binary.LittleEndian.PutUint16(p[18:], uint16(dstY))
387+ return seq
388+}
389+
390+func SetInputFocus(b *xturbo.Buf, revertTo InputFocus, focus Window, time Timestamp) xturbo.Seq {
391+ p, seq := b.Request(42, uint8(revertTo), 8)
392+ if p == nil {
393+ return 0
394+ }
395+ binary.LittleEndian.PutUint32(p[0:], uint32(focus))
396+ binary.LittleEndian.PutUint32(p[4:], uint32(time))
397+ return seq
398+}
399+
400+func GetInputFocus(b *xturbo.Buf) xturbo.Seq {
401+ p, seq := b.Request(43, 0, 0)
402+ if p == nil {
403+ return 0
404+ }
405+ return seq
406+}
407+
408+func QueryKeymap(b *xturbo.Buf) xturbo.Seq {
409+ p, seq := b.Request(44, 0, 0)
410+ if p == nil {
411+ return 0
412+ }
413+ return seq
414+}
415+
416+func CloseFont(b *xturbo.Buf, font Font) xturbo.Seq {
417+ p, seq := b.Request(46, 0, 4)
418+ if p == nil {
419+ return 0
420+ }
421+ binary.LittleEndian.PutUint32(p[0:], uint32(font))
422+ return seq
423+}
424+
425+func QueryFont(b *xturbo.Buf, font Fontable) xturbo.Seq {
426+ p, seq := b.Request(47, 0, 4)
427+ if p == nil {
428+ return 0
429+ }
430+ binary.LittleEndian.PutUint32(p[0:], uint32(font))
431+ return seq
432+}
433+
434+func GetFontPath(b *xturbo.Buf) xturbo.Seq {
435+ p, seq := b.Request(52, 0, 0)
436+ if p == nil {
437+ return 0
438+ }
439+ return seq
440+}
441+
442+func CreatePixmap(b *xturbo.Buf, depth uint8, pid Pixmap, drawable Drawable, width uint16, height uint16) xturbo.Seq {
443+ p, seq := b.Request(53, uint8(depth), 12)
444+ if p == nil {
445+ return 0
446+ }
447+ binary.LittleEndian.PutUint32(p[0:], uint32(pid))
448+ binary.LittleEndian.PutUint32(p[4:], uint32(drawable))
449+ binary.LittleEndian.PutUint16(p[8:], uint16(width))
450+ binary.LittleEndian.PutUint16(p[10:], uint16(height))
451+ return seq
452+}
453+
454+func FreePixmap(b *xturbo.Buf, pixmap Pixmap) xturbo.Seq {
455+ p, seq := b.Request(54, 0, 4)
456+ if p == nil {
457+ return 0
458+ }
459+ binary.LittleEndian.PutUint32(p[0:], uint32(pixmap))
460+ return seq
461+}
462+
463+func CopyGC(b *xturbo.Buf, srcGc Gcontext, dstGc Gcontext, valueMask Gc) xturbo.Seq {
464+ p, seq := b.Request(57, 0, 12)
465+ if p == nil {
466+ return 0
467+ }
468+ binary.LittleEndian.PutUint32(p[0:], uint32(srcGc))
469+ binary.LittleEndian.PutUint32(p[4:], uint32(dstGc))
470+ binary.LittleEndian.PutUint32(p[8:], uint32(valueMask))
471+ return seq
472+}
473+
474+func FreeGC(b *xturbo.Buf, gc Gcontext) xturbo.Seq {
475+ p, seq := b.Request(60, 0, 4)
476+ if p == nil {
477+ return 0
478+ }
479+ binary.LittleEndian.PutUint32(p[0:], uint32(gc))
480+ return seq
481+}
482+
483+func ClearArea(b *xturbo.Buf, exposures bool, window Window, x int16, y int16, width uint16, height uint16) xturbo.Seq {
484+ var data uint8
485+ if exposures {
486+ data = 1
487+ }
488+ p, seq := b.Request(61, data, 12)
489+ if p == nil {
490+ return 0
491+ }
492+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
493+ binary.LittleEndian.PutUint16(p[4:], uint16(x))
494+ binary.LittleEndian.PutUint16(p[6:], uint16(y))
495+ binary.LittleEndian.PutUint16(p[8:], uint16(width))
496+ binary.LittleEndian.PutUint16(p[10:], uint16(height))
497+ return seq
498+}
499+
500+func CopyArea(b *xturbo.Buf, srcDrawable Drawable, dstDrawable Drawable, gc Gcontext, srcX int16, srcY int16, dstX int16, dstY int16, width uint16, height uint16) xturbo.Seq {
501+ p, seq := b.Request(62, 0, 24)
502+ if p == nil {
503+ return 0
504+ }
505+ binary.LittleEndian.PutUint32(p[0:], uint32(srcDrawable))
506+ binary.LittleEndian.PutUint32(p[4:], uint32(dstDrawable))
507+ binary.LittleEndian.PutUint32(p[8:], uint32(gc))
508+ binary.LittleEndian.PutUint16(p[12:], uint16(srcX))
509+ binary.LittleEndian.PutUint16(p[14:], uint16(srcY))
510+ binary.LittleEndian.PutUint16(p[16:], uint16(dstX))
511+ binary.LittleEndian.PutUint16(p[18:], uint16(dstY))
512+ binary.LittleEndian.PutUint16(p[20:], uint16(width))
513+ binary.LittleEndian.PutUint16(p[22:], uint16(height))
514+ return seq
515+}
516+
517+func CopyPlane(b *xturbo.Buf, srcDrawable Drawable, dstDrawable Drawable, gc Gcontext, srcX int16, srcY int16, dstX int16, dstY int16, width uint16, height uint16, bitPlane uint32) xturbo.Seq {
518+ p, seq := b.Request(63, 0, 28)
519+ if p == nil {
520+ return 0
521+ }
522+ binary.LittleEndian.PutUint32(p[0:], uint32(srcDrawable))
523+ binary.LittleEndian.PutUint32(p[4:], uint32(dstDrawable))
524+ binary.LittleEndian.PutUint32(p[8:], uint32(gc))
525+ binary.LittleEndian.PutUint16(p[12:], uint16(srcX))
526+ binary.LittleEndian.PutUint16(p[14:], uint16(srcY))
527+ binary.LittleEndian.PutUint16(p[16:], uint16(dstX))
528+ binary.LittleEndian.PutUint16(p[18:], uint16(dstY))
529+ binary.LittleEndian.PutUint16(p[20:], uint16(width))
530+ binary.LittleEndian.PutUint16(p[22:], uint16(height))
531+ binary.LittleEndian.PutUint32(p[24:], uint32(bitPlane))
532+ return seq
533+}
534+
535+func GetImage(b *xturbo.Buf, format ImageFormat, drawable Drawable, x int16, y int16, width uint16, height uint16, planeMask uint32) xturbo.Seq {
536+ p, seq := b.Request(73, uint8(format), 16)
537+ if p == nil {
538+ return 0
539+ }
540+ binary.LittleEndian.PutUint32(p[0:], uint32(drawable))
541+ binary.LittleEndian.PutUint16(p[4:], uint16(x))
542+ binary.LittleEndian.PutUint16(p[6:], uint16(y))
543+ binary.LittleEndian.PutUint16(p[8:], uint16(width))
544+ binary.LittleEndian.PutUint16(p[10:], uint16(height))
545+ binary.LittleEndian.PutUint32(p[12:], uint32(planeMask))
546+ return seq
547+}
548+
549+func CreateColormap(b *xturbo.Buf, alloc ColormapAlloc, mid Colormap, window Window, visual Visualid) xturbo.Seq {
550+ p, seq := b.Request(78, uint8(alloc), 12)
551+ if p == nil {
552+ return 0
553+ }
554+ binary.LittleEndian.PutUint32(p[0:], uint32(mid))
555+ binary.LittleEndian.PutUint32(p[4:], uint32(window))
556+ binary.LittleEndian.PutUint32(p[8:], uint32(visual))
557+ return seq
558+}
559+
560+func FreeColormap(b *xturbo.Buf, cmap Colormap) xturbo.Seq {
561+ p, seq := b.Request(79, 0, 4)
562+ if p == nil {
563+ return 0
564+ }
565+ binary.LittleEndian.PutUint32(p[0:], uint32(cmap))
566+ return seq
567+}
568+
569+func CopyColormapAndFree(b *xturbo.Buf, mid Colormap, srcCmap Colormap) xturbo.Seq {
570+ p, seq := b.Request(80, 0, 8)
571+ if p == nil {
572+ return 0
573+ }
574+ binary.LittleEndian.PutUint32(p[0:], uint32(mid))
575+ binary.LittleEndian.PutUint32(p[4:], uint32(srcCmap))
576+ return seq
577+}
578+
579+func InstallColormap(b *xturbo.Buf, cmap Colormap) xturbo.Seq {
580+ p, seq := b.Request(81, 0, 4)
581+ if p == nil {
582+ return 0
583+ }
584+ binary.LittleEndian.PutUint32(p[0:], uint32(cmap))
585+ return seq
586+}
587+
588+func UninstallColormap(b *xturbo.Buf, cmap Colormap) xturbo.Seq {
589+ p, seq := b.Request(82, 0, 4)
590+ if p == nil {
591+ return 0
592+ }
593+ binary.LittleEndian.PutUint32(p[0:], uint32(cmap))
594+ return seq
595+}
596+
597+func ListInstalledColormaps(b *xturbo.Buf, window Window) xturbo.Seq {
598+ p, seq := b.Request(83, 0, 4)
599+ if p == nil {
600+ return 0
601+ }
602+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
603+ return seq
604+}
605+
606+func AllocColor(b *xturbo.Buf, cmap Colormap, red uint16, green uint16, blue uint16) xturbo.Seq {
607+ p, seq := b.Request(84, 0, 12)
608+ if p == nil {
609+ return 0
610+ }
611+ binary.LittleEndian.PutUint32(p[0:], uint32(cmap))
612+ binary.LittleEndian.PutUint16(p[4:], uint16(red))
613+ binary.LittleEndian.PutUint16(p[6:], uint16(green))
614+ binary.LittleEndian.PutUint16(p[8:], uint16(blue))
615+ return seq
616+}
617+
618+func AllocColorCells(b *xturbo.Buf, contiguous bool, cmap Colormap, colors uint16, planes uint16) xturbo.Seq {
619+ var data uint8
620+ if contiguous {
621+ data = 1
622+ }
623+ p, seq := b.Request(86, data, 8)
624+ if p == nil {
625+ return 0
626+ }
627+ binary.LittleEndian.PutUint32(p[0:], uint32(cmap))
628+ binary.LittleEndian.PutUint16(p[4:], uint16(colors))
629+ binary.LittleEndian.PutUint16(p[6:], uint16(planes))
630+ return seq
631+}
632+
633+func AllocColorPlanes(b *xturbo.Buf, contiguous bool, cmap Colormap, colors uint16, reds uint16, greens uint16, blues uint16) xturbo.Seq {
634+ var data uint8
635+ if contiguous {
636+ data = 1
637+ }
638+ p, seq := b.Request(87, data, 12)
639+ if p == nil {
640+ return 0
641+ }
642+ binary.LittleEndian.PutUint32(p[0:], uint32(cmap))
643+ binary.LittleEndian.PutUint16(p[4:], uint16(colors))
644+ binary.LittleEndian.PutUint16(p[6:], uint16(reds))
645+ binary.LittleEndian.PutUint16(p[8:], uint16(greens))
646+ binary.LittleEndian.PutUint16(p[10:], uint16(blues))
647+ return seq
648+}
649+
650+func CreateCursor(b *xturbo.Buf, cid Cursor, source Pixmap, mask Pixmap, foreRed uint16, foreGreen uint16, foreBlue uint16, backRed uint16, backGreen uint16, backBlue uint16, x uint16, y uint16) xturbo.Seq {
651+ p, seq := b.Request(93, 0, 28)
652+ if p == nil {
653+ return 0
654+ }
655+ binary.LittleEndian.PutUint32(p[0:], uint32(cid))
656+ binary.LittleEndian.PutUint32(p[4:], uint32(source))
657+ binary.LittleEndian.PutUint32(p[8:], uint32(mask))
658+ binary.LittleEndian.PutUint16(p[12:], uint16(foreRed))
659+ binary.LittleEndian.PutUint16(p[14:], uint16(foreGreen))
660+ binary.LittleEndian.PutUint16(p[16:], uint16(foreBlue))
661+ binary.LittleEndian.PutUint16(p[18:], uint16(backRed))
662+ binary.LittleEndian.PutUint16(p[20:], uint16(backGreen))
663+ binary.LittleEndian.PutUint16(p[22:], uint16(backBlue))
664+ binary.LittleEndian.PutUint16(p[24:], uint16(x))
665+ binary.LittleEndian.PutUint16(p[26:], uint16(y))
666+ return seq
667+}
668+
669+func CreateGlyphCursor(b *xturbo.Buf, cid Cursor, sourceFont Font, maskFont Font, sourceChar uint16, maskChar uint16, foreRed uint16, foreGreen uint16, foreBlue uint16, backRed uint16, backGreen uint16, backBlue uint16) xturbo.Seq {
670+ p, seq := b.Request(94, 0, 28)
671+ if p == nil {
672+ return 0
673+ }
674+ binary.LittleEndian.PutUint32(p[0:], uint32(cid))
675+ binary.LittleEndian.PutUint32(p[4:], uint32(sourceFont))
676+ binary.LittleEndian.PutUint32(p[8:], uint32(maskFont))
677+ binary.LittleEndian.PutUint16(p[12:], uint16(sourceChar))
678+ binary.LittleEndian.PutUint16(p[14:], uint16(maskChar))
679+ binary.LittleEndian.PutUint16(p[16:], uint16(foreRed))
680+ binary.LittleEndian.PutUint16(p[18:], uint16(foreGreen))
681+ binary.LittleEndian.PutUint16(p[20:], uint16(foreBlue))
682+ binary.LittleEndian.PutUint16(p[22:], uint16(backRed))
683+ binary.LittleEndian.PutUint16(p[24:], uint16(backGreen))
684+ binary.LittleEndian.PutUint16(p[26:], uint16(backBlue))
685+ return seq
686+}
687+
688+func FreeCursor(b *xturbo.Buf, cursor Cursor) xturbo.Seq {
689+ p, seq := b.Request(95, 0, 4)
690+ if p == nil {
691+ return 0
692+ }
693+ binary.LittleEndian.PutUint32(p[0:], uint32(cursor))
694+ return seq
695+}
696+
697+func RecolorCursor(b *xturbo.Buf, cursor Cursor, foreRed uint16, foreGreen uint16, foreBlue uint16, backRed uint16, backGreen uint16, backBlue uint16) xturbo.Seq {
698+ p, seq := b.Request(96, 0, 16)
699+ if p == nil {
700+ return 0
701+ }
702+ binary.LittleEndian.PutUint32(p[0:], uint32(cursor))
703+ binary.LittleEndian.PutUint16(p[4:], uint16(foreRed))
704+ binary.LittleEndian.PutUint16(p[6:], uint16(foreGreen))
705+ binary.LittleEndian.PutUint16(p[8:], uint16(foreBlue))
706+ binary.LittleEndian.PutUint16(p[10:], uint16(backRed))
707+ binary.LittleEndian.PutUint16(p[12:], uint16(backGreen))
708+ binary.LittleEndian.PutUint16(p[14:], uint16(backBlue))
709+ return seq
710+}
711+
712+func QueryBestSize(b *xturbo.Buf, class QueryShapeOf, drawable Drawable, width uint16, height uint16) xturbo.Seq {
713+ p, seq := b.Request(97, uint8(class), 8)
714+ if p == nil {
715+ return 0
716+ }
717+ binary.LittleEndian.PutUint32(p[0:], uint32(drawable))
718+ binary.LittleEndian.PutUint16(p[4:], uint16(width))
719+ binary.LittleEndian.PutUint16(p[6:], uint16(height))
720+ return seq
721+}
722+
723+func ListExtensions(b *xturbo.Buf) xturbo.Seq {
724+ p, seq := b.Request(99, 0, 0)
725+ if p == nil {
726+ return 0
727+ }
728+ return seq
729+}
730+
731+func GetKeyboardMapping(b *xturbo.Buf, firstKeycode Keycode, count uint8) xturbo.Seq {
732+ p, seq := b.Request(101, 0, 4)
733+ if p == nil {
734+ return 0
735+ }
736+ p[0:][0] = byte(firstKeycode)
737+ p[1:][0] = byte(count)
738+ return seq
739+}
740+
741+func GetKeyboardControl(b *xturbo.Buf) xturbo.Seq {
742+ p, seq := b.Request(103, 0, 0)
743+ if p == nil {
744+ return 0
745+ }
746+ return seq
747+}
748+
749+func Bell(b *xturbo.Buf, percent int8) xturbo.Seq {
750+ p, seq := b.Request(104, uint8(percent), 0)
751+ if p == nil {
752+ return 0
753+ }
754+ return seq
755+}
756+
757+func ChangePointerControl(b *xturbo.Buf, accelerationNumerator int16, accelerationDenominator int16, threshold int16, doAcceleration bool, doThreshold bool) xturbo.Seq {
758+ p, seq := b.Request(105, 0, 8)
759+ if p == nil {
760+ return 0
761+ }
762+ binary.LittleEndian.PutUint16(p[0:], uint16(accelerationNumerator))
763+ binary.LittleEndian.PutUint16(p[2:], uint16(accelerationDenominator))
764+ binary.LittleEndian.PutUint16(p[4:], uint16(threshold))
765+ if doAcceleration {
766+ p[6:][0] = 1
767+ } else {
768+ p[6:][0] = 0
769+ }
770+ if doThreshold {
771+ p[7:][0] = 1
772+ } else {
773+ p[7:][0] = 0
774+ }
775+ return seq
776+}
777+
778+func GetPointerControl(b *xturbo.Buf) xturbo.Seq {
779+ p, seq := b.Request(106, 0, 0)
780+ if p == nil {
781+ return 0
782+ }
783+ return seq
784+}
785+
786+func SetScreenSaver(b *xturbo.Buf, timeout int16, interval int16, preferBlanking Blanking, allowExposures Exposures) xturbo.Seq {
787+ p, seq := b.Request(107, 0, 8)
788+ if p == nil {
789+ return 0
790+ }
791+ binary.LittleEndian.PutUint16(p[0:], uint16(timeout))
792+ binary.LittleEndian.PutUint16(p[2:], uint16(interval))
793+ p[4:][0] = byte(preferBlanking)
794+ p[5:][0] = byte(allowExposures)
795+ return seq
796+}
797+
798+func GetScreenSaver(b *xturbo.Buf) xturbo.Seq {
799+ p, seq := b.Request(108, 0, 0)
800+ if p == nil {
801+ return 0
802+ }
803+ return seq
804+}
805+
806+func ListHosts(b *xturbo.Buf) xturbo.Seq {
807+ p, seq := b.Request(110, 0, 0)
808+ if p == nil {
809+ return 0
810+ }
811+ return seq
812+}
813+
814+func SetAccessControl(b *xturbo.Buf, mode AccessControl) xturbo.Seq {
815+ p, seq := b.Request(111, uint8(mode), 0)
816+ if p == nil {
817+ return 0
818+ }
819+ return seq
820+}
821+
822+func SetCloseDownMode(b *xturbo.Buf, mode CloseDown) xturbo.Seq {
823+ p, seq := b.Request(112, uint8(mode), 0)
824+ if p == nil {
825+ return 0
826+ }
827+ return seq
828+}
829+
830+func KillClient(b *xturbo.Buf, resource uint32) xturbo.Seq {
831+ p, seq := b.Request(113, 0, 4)
832+ if p == nil {
833+ return 0
834+ }
835+ binary.LittleEndian.PutUint32(p[0:], uint32(resource))
836+ return seq
837+}
838+
839+func ForceScreenSaver(b *xturbo.Buf, mode ScreenSaver) xturbo.Seq {
840+ p, seq := b.Request(115, uint8(mode), 0)
841+ if p == nil {
842+ return 0
843+ }
844+ return seq
845+}
846+
847+func GetPointerMapping(b *xturbo.Buf) xturbo.Seq {
848+ p, seq := b.Request(117, 0, 0)
849+ if p == nil {
850+ return 0
851+ }
852+ return seq
853+}
854+
855+func GetModifierMapping(b *xturbo.Buf) xturbo.Seq {
856+ p, seq := b.Request(119, 0, 0)
857+ if p == nil {
858+ return 0
859+ }
860+ return seq
861+}
862+
863+func NoOperation(b *xturbo.Buf) xturbo.Seq {
864+ p, seq := b.Request(127, 0, 0)
865+ if p == nil {
866+ return 0
867+ }
868+ return seq
869+}
A xproto/requests_test.go +24 -0
@@ -0,0 +1,24 @@
1+package xproto
2+
3+import (
4+ "bnema.dev/xturbo"
5+ "testing"
6+)
7+
8+func BenchmarkMapWindow(b *testing.B) {
9+ buf := xturbo.NewBuf(0)
10+ batch := 0
11+ b.ReportAllocs()
12+ b.ResetTimer()
13+ for i := 0; i < b.N; i++ {
14+ if batch == 60000 {
15+ b.StopTimer()
16+ buf = xturbo.NewBuf(0)
17+ batch = 0
18+ b.StartTimer()
19+ }
20+ buf.Reset()
21+ MapWindow(buf, 1)
22+ batch++
23+ }
24+}
@@ -0,0 +1,24 @@
1+package xproto
2+
3+import (
4+ "bnema.dev/xturbo"
5+ "testing"
6+)
7+
8+func BenchmarkMapWindow(b *testing.B) {
9+ buf := xturbo.NewBuf(0)
10+ batch := 0
11+ b.ReportAllocs()
12+ b.ResetTimer()
13+ for i := 0; i < b.N; i++ {
14+ if batch == 60000 {
15+ b.StopTimer()
16+ buf = xturbo.NewBuf(0)
17+ batch = 0
18+ b.StartTimer()
19+ }
20+ buf.Reset()
21+ MapWindow(buf, 1)
22+ batch++
23+ }
24+}
M xproto/types_test.go +9 -0
@@ -43,3 +43,12 @@ func TestAllocStructPut(t *testing.T) {
4343 t.Fatal(n)
4444 }
4545 }
46+
47+func BenchmarkRectanglePut(b *testing.B) {
48+ v := Rectangle{Width: 640, Height: 480}
49+ var p [8]byte
50+ b.ReportAllocs()
51+ for b.Loop() {
52+ v.Put(p[:])
53+ }
54+}
@@ -43,3 +43,12 @@ func TestAllocStructPut(t *testing.T) {
43 t.Fatal(n)43 t.Fatal(n)
44 }44 }
45 }45 }
46+
47+func BenchmarkRectanglePut(b *testing.B) {
48+ v := Rectangle{Width: 640, Height: 480}
49+ var p [8]byte
50+ b.ReportAllocs()
51+ for b.Loop() {
52+ v.Put(p[:])
53+ }
54+}

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
esc
close a dialog, leave a field

Branches 1

Tags 1

↑↓ moveenter openesc close