detached 017e663

feat(xtgen): encode typed mask-ordered request value lists

commit
017e6635f6cc1a21658524bfebefa7fb08826ce8
author
brice · · 2026-10-22 06:40 UTC
parent
582be88
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
checks
2/2
15 files · +1853 -14
M cmd/xtgen/requests.go +31 -11
@@ -16,30 +16,27 @@ type Request struct {
1616 Node *Node
1717 Derived map[string]string
1818 Lists []Field
19+ Values *ValueList
1920 }
2021
21-// resolveRequests lowers scalar and list requests. Value switches follow in T2.5.
22+// resolveRequests lowers scalar, list and mask-bitcase value-list requests.
2223 func resolveRequests(m *Module) ([]Request, error) {
2324 var out []Request
2425 for _, n := range m.Root.Children {
2526 if n.Kind != "request" {
2627 continue
2728 }
28- supported := true
29- for _, f := range n.Children {
30- if f.Kind == "switch" {
31- supported = false
32- }
33- }
34- if !supported {
35- continue
36- }
3729 name := goName(n.Attr["name"])
3830 if err := m.claim(name, n); err != nil {
3931 return nil, err
4032 }
4133 opcode, _ := strconv.Atoi(n.Attr["opcode"])
4234 r := Request{Name: name, Opcode: uint8(opcode), Node: n, Derived: map[string]string{}}
35+ var err error
36+ r.Values, err = resolveValues(m, n, name)
37+ if err != nil {
38+ return nil, err
39+ }
4340 refs := map[string]int{}
4441 var countRefs func(*Node)
4542 countRefs = func(x *Node) {
@@ -66,6 +63,10 @@ func resolveRequests(m *Module) ([]Request, error) {
6663 if n.Kind == "reply" || n.Kind == "doc" {
6764 continue
6865 }
66+ if n.Kind == "switch" {
67+ r.Params = append(r.Params, Field{Param: "v", GoType: "*" + name + "Values"})
68+ continue
69+ }
6970 f := Field{Name: goName(n.Attr["name"]), Param: paramName(n.Attr["name"]), Kind: n.Kind, Node: n, Off: off - 4}
7071 if n.Kind == "pad" {
7172 if n.Attr["align"] != "" {
@@ -117,7 +118,11 @@ func resolveRequests(m *Module) ([]Request, error) {
117118 r.Lists = append(r.Lists, f)
118119 r.Params = append(r.Params, f)
119120 } else if n.Kind == "field" && r.Derived[n.Attr["name"]] == "" {
120- r.Params = append(r.Params, f)
121+ if r.Values != nil && n == r.Values.Mask.Node {
122+ f.Param = "v.Mask"
123+ } else {
124+ r.Params = append(r.Params, f)
125+ }
121126 }
122127 if n.Kind == "exprfield" {
123128 f.Expr = n.Children[0]
@@ -155,6 +160,9 @@ func resolveRequests(m *Module) ([]Request, error) {
155160 }
156161 func requestDecl(m *Module, r Request) (string, error) {
157162 var b strings.Builder
163+ if r.Values != nil {
164+ b.WriteString(valuesDecl(r.Name, r.Values))
165+ }
158166 fmt.Fprintf(&b, "func %s(b *xturbo.Buf", r.Name)
159167 for _, p := range r.Params {
160168 fmt.Fprintf(&b, ", %s %s", p.Param, p.GoType)
@@ -222,6 +230,9 @@ func requestDecl(m *Module, r Request) (string, error) {
222230 b.WriteString("size=(size+3)&^3;")
223231 body = "size"
224232 }
233+ if r.Values != nil {
234+ body += "+4*bits.OnesCount32(uint32(v.Mask))"
235+ }
225236 major := fmt.Sprint(r.Opcode)
226237 data := "0"
227238 if m.ExtName != "" {
@@ -305,6 +316,15 @@ func requestDecl(m *Module, r Request) (string, error) {
305316 fmt.Fprintf(&b, "off+=%d;", f.Size)
306317 }
307318 }
319+ if r.Values != nil {
320+ fmt.Fprintf(&b, "off:=%d;", r.Fixed)
321+ for _, f := range r.Values.Fields {
322+ fmt.Fprintf(&b, "if v.Mask & %s != 0 {", f.Bit)
323+ b.WriteString(putScalar(f.Field.Type, "v."+f.Field.Name, "p[off:]"))
324+ b.WriteString("off+=4 };")
325+ }
326+ b.WriteString("_ = off;")
327+ }
308328 b.WriteString("return seq }\n")
309329 return b.String(), nil
310330 }
@@ -16,30 +16,27 @@ type Request struct {
16 Node *Node16 Node *Node
17 Derived map[string]string17 Derived map[string]string
18 Lists []Field18 Lists []Field
19+ Values *ValueList
19 }20 }
20 21
21-// resolveRequests lowers scalar and list requests. Value switches follow in T2.5.22+// resolveRequests lowers scalar, list and mask-bitcase value-list requests.
22 func resolveRequests(m *Module) ([]Request, error) {23 func resolveRequests(m *Module) ([]Request, error) {
23 var out []Request24 var out []Request
24 for _, n := range m.Root.Children {25 for _, n := range m.Root.Children {
25 if n.Kind != "request" {26 if n.Kind != "request" {
26 continue27 continue
27 }28 }
28- supported := true
29- for _, f := range n.Children {
30- if f.Kind == "switch" {
31- supported = false
32- }
33- }
34- if !supported {
35- continue
36- }
37 name := goName(n.Attr["name"])29 name := goName(n.Attr["name"])
38 if err := m.claim(name, n); err != nil {30 if err := m.claim(name, n); err != nil {
39 return nil, err31 return nil, err
40 }32 }
41 opcode, _ := strconv.Atoi(n.Attr["opcode"])33 opcode, _ := strconv.Atoi(n.Attr["opcode"])
42 r := Request{Name: name, Opcode: uint8(opcode), Node: n, Derived: map[string]string{}}34 r := Request{Name: name, Opcode: uint8(opcode), Node: n, Derived: map[string]string{}}
35+ var err error
36+ r.Values, err = resolveValues(m, n, name)
37+ if err != nil {
38+ return nil, err
39+ }
43 refs := map[string]int{}40 refs := map[string]int{}
44 var countRefs func(*Node)41 var countRefs func(*Node)
45 countRefs = func(x *Node) {42 countRefs = func(x *Node) {
@@ -66,6 +63,10 @@ func resolveRequests(m *Module) ([]Request, error) {
66 if n.Kind == "reply" || n.Kind == "doc" {63 if n.Kind == "reply" || n.Kind == "doc" {
67 continue64 continue
68 }65 }
66+ if n.Kind == "switch" {
67+ r.Params = append(r.Params, Field{Param: "v", GoType: "*" + name + "Values"})
68+ continue
69+ }
69 f := Field{Name: goName(n.Attr["name"]), Param: paramName(n.Attr["name"]), Kind: n.Kind, Node: n, Off: off - 4}70 f := Field{Name: goName(n.Attr["name"]), Param: paramName(n.Attr["name"]), Kind: n.Kind, Node: n, Off: off - 4}
70 if n.Kind == "pad" {71 if n.Kind == "pad" {
71 if n.Attr["align"] != "" {72 if n.Attr["align"] != "" {
@@ -117,7 +118,11 @@ func resolveRequests(m *Module) ([]Request, error) {
117 r.Lists = append(r.Lists, f)118 r.Lists = append(r.Lists, f)
118 r.Params = append(r.Params, f)119 r.Params = append(r.Params, f)
119 } else if n.Kind == "field" && r.Derived[n.Attr["name"]] == "" {120 } else if n.Kind == "field" && r.Derived[n.Attr["name"]] == "" {
120- r.Params = append(r.Params, f)121+ if r.Values != nil && n == r.Values.Mask.Node {
122+ f.Param = "v.Mask"
123+ } else {
124+ r.Params = append(r.Params, f)
125+ }
121 }126 }
122 if n.Kind == "exprfield" {127 if n.Kind == "exprfield" {
123 f.Expr = n.Children[0]128 f.Expr = n.Children[0]
@@ -155,6 +160,9 @@ func resolveRequests(m *Module) ([]Request, error) {
155 }160 }
156 func requestDecl(m *Module, r Request) (string, error) {161 func requestDecl(m *Module, r Request) (string, error) {
157 var b strings.Builder162 var b strings.Builder
163+ if r.Values != nil {
164+ b.WriteString(valuesDecl(r.Name, r.Values))
165+ }
158 fmt.Fprintf(&b, "func %s(b *xturbo.Buf", r.Name)166 fmt.Fprintf(&b, "func %s(b *xturbo.Buf", r.Name)
159 for _, p := range r.Params {167 for _, p := range r.Params {
160 fmt.Fprintf(&b, ", %s %s", p.Param, p.GoType)168 fmt.Fprintf(&b, ", %s %s", p.Param, p.GoType)
@@ -222,6 +230,9 @@ func requestDecl(m *Module, r Request) (string, error) {
222 b.WriteString("size=(size+3)&^3;")230 b.WriteString("size=(size+3)&^3;")
223 body = "size"231 body = "size"
224 }232 }
233+ if r.Values != nil {
234+ body += "+4*bits.OnesCount32(uint32(v.Mask))"
235+ }
225 major := fmt.Sprint(r.Opcode)236 major := fmt.Sprint(r.Opcode)
226 data := "0"237 data := "0"
227 if m.ExtName != "" {238 if m.ExtName != "" {
@@ -305,6 +316,15 @@ func requestDecl(m *Module, r Request) (string, error) {
305 fmt.Fprintf(&b, "off+=%d;", f.Size)316 fmt.Fprintf(&b, "off+=%d;", f.Size)
306 }317 }
307 }318 }
319+ if r.Values != nil {
320+ fmt.Fprintf(&b, "off:=%d;", r.Fixed)
321+ for _, f := range r.Values.Fields {
322+ fmt.Fprintf(&b, "if v.Mask & %s != 0 {", f.Bit)
323+ b.WriteString(putScalar(f.Field.Type, "v."+f.Field.Name, "p[off:]"))
324+ b.WriteString("off+=4 };")
325+ }
326+ b.WriteString("_ = off;")
327+ }
308 b.WriteString("return seq }\n")328 b.WriteString("return seq }\n")
309 return b.String(), nil329 return b.String(), nil
310 }330 }
A cmd/xtgen/values.go +136 -0
@@ -0,0 +1,136 @@
1+package main
2+
3+import (
4+ "fmt"
5+ "sort"
6+ "strings"
7+)
8+
9+type ValueField struct {
10+ Field Field
11+ Bit string
12+ Value int64
13+}
14+type ValueList struct {
15+ Mask Field
16+ Fields []ValueField
17+}
18+
19+func resolveValues(m *Module, req *Node, name string) (*ValueList, error) {
20+ var sw *Node
21+ for _, n := range req.Children {
22+ if n.Kind == "switch" {
23+ if sw != nil {
24+ return nil, n.fail("multiple value switches are unsupported")
25+ }
26+ sw = n
27+ }
28+ }
29+ if sw == nil {
30+ return nil, nil
31+ }
32+ if len(sw.Children) < 2 || sw.Children[0].Kind != "fieldref" {
33+ return nil, sw.fail("value switch requires a mask fieldref and bitcases")
34+ }
35+ var mask *Node
36+ seenSwitch := false
37+ for _, n := range req.Children {
38+ if n == sw {
39+ seenSwitch = true
40+ continue
41+ }
42+ if seenSwitch && n.Kind != "doc" && n.Kind != "reply" {
43+ return nil, n.fail("value switch must be trailing")
44+ }
45+ if n.Kind == "list" {
46+ return nil, n.fail("lists combined with value switches are unsupported")
47+ }
48+ if !seenSwitch && n.Kind == "field" && n.Attr["name"] == sw.Children[0].Text {
49+ mask = n
50+ }
51+ }
52+ if mask == nil || mask.Attr["mask"] == "" {
53+ return nil, sw.fail("value switch requires a preceding typed mask")
54+ }
55+ mt, err := lookup(m, mask.Attr["type"])
56+ if err != nil {
57+ return nil, mask.fail("%v", err)
58+ }
59+ e, owner := findEnum(m, mask.Attr["mask"])
60+ if e == nil {
61+ return nil, mask.fail("unknown mask %s", mask.Attr["mask"])
62+ }
63+ if mt.Size > 4 || !isScalar(mt) {
64+ return nil, mask.fail("value mask must fit in 32 bits")
65+ }
66+ v := &ValueList{Mask: Field{Node: mask, GoType: qualified(m, owner, e.Name)}}
67+ used := map[int64]bool{}
68+ names := map[string]bool{"Mask": true}
69+ for _, bc := range sw.Children[1:] {
70+ var members []*Node
71+ for _, c := range bc.Children {
72+ if c.Kind != "doc" {
73+ members = append(members, c)
74+ }
75+ }
76+ if bc.Kind != "bitcase" || len(members) != 2 || members[0].Kind != "enumref" || members[1].Kind != "field" {
77+ return nil, bc.fail("value switch requires one enumref and one 4-byte field per bitcase")
78+ }
79+ bit, n := members[0], members[1]
80+ be, bo := findEnum(m, bit.Attr["ref"])
81+ if be != e || bo != owner {
82+ return nil, bit.fail("bitcase enum must match value mask")
83+ }
84+ var value int64
85+ found := false
86+ for _, item := range e.Items {
87+ if item.Name == e.Name+goName(bit.Text) {
88+ value = item.Value
89+ found = true
90+ }
91+ }
92+ if !found || value <= 0 || value&(value-1) != 0 || uint64(value) >= uint64(1)<<(8*mt.Size) || used[value] {
93+ return nil, bit.fail("bitcase requires a unique mask bit")
94+ }
95+ used[value] = true
96+ typ, err := lookup(m, n.Attr["type"])
97+ if err != nil {
98+ return nil, n.fail("%v", err)
99+ }
100+ if typ.Size != 4 || !isScalar(typ) {
101+ return nil, n.fail("value-list bitcase requires a 4-byte scalar field")
102+ }
103+ f := Field{Name: goName(n.Attr["name"]), GoType: qualified(m, typ.Module, typ.GoType), Type: typ, Node: n}
104+ for _, attr := range []string{"enum", "mask"} {
105+ if ref := n.Attr[attr]; ref != "" {
106+ fe, fo := findEnum(m, ref)
107+ if fe == nil {
108+ return nil, n.fail("unknown enum %s", ref)
109+ }
110+ f.GoType = qualified(m, fo, fe.Name)
111+ }
112+ }
113+ if names[f.Name] {
114+ return nil, n.fail("value field name collision %s", f.Name)
115+ }
116+ names[f.Name] = true
117+ v.Fields = append(v.Fields, ValueField{Field: f, Bit: qualified(m, owner, e.Name+goName(bit.Text)), Value: value})
118+ }
119+ sort.Slice(v.Fields, func(i, j int) bool { return v.Fields[i].Value < v.Fields[j].Value })
120+ if err := m.claim(name+"Values", sw); err != nil {
121+ return nil, err
122+ }
123+ return v, nil
124+}
125+func valuesDecl(name string, v *ValueList) string {
126+ var b strings.Builder
127+ fmt.Fprintf(&b, "type %sValues struct { Mask %s;", name, v.Mask.GoType)
128+ for _, f := range v.Fields {
129+ fmt.Fprintf(&b, "%s %s;", f.Field.Name, f.Field.GoType)
130+ }
131+ b.WriteString("};\n")
132+ for _, f := range v.Fields {
133+ fmt.Fprintf(&b, "func(v *%sValues) Set%s(x %s) *%sValues { v.Mask |= %s; v.%s=x; return v };\n", name, f.Field.Name, f.Field.GoType, name, f.Bit, f.Field.Name)
134+ }
135+ return b.String()
136+}
@@ -0,0 +1,136 @@
1+package main
2+
3+import (
4+ "fmt"
5+ "sort"
6+ "strings"
7+)
8+
9+type ValueField struct {
10+ Field Field
11+ Bit string
12+ Value int64
13+}
14+type ValueList struct {
15+ Mask Field
16+ Fields []ValueField
17+}
18+
19+func resolveValues(m *Module, req *Node, name string) (*ValueList, error) {
20+ var sw *Node
21+ for _, n := range req.Children {
22+ if n.Kind == "switch" {
23+ if sw != nil {
24+ return nil, n.fail("multiple value switches are unsupported")
25+ }
26+ sw = n
27+ }
28+ }
29+ if sw == nil {
30+ return nil, nil
31+ }
32+ if len(sw.Children) < 2 || sw.Children[0].Kind != "fieldref" {
33+ return nil, sw.fail("value switch requires a mask fieldref and bitcases")
34+ }
35+ var mask *Node
36+ seenSwitch := false
37+ for _, n := range req.Children {
38+ if n == sw {
39+ seenSwitch = true
40+ continue
41+ }
42+ if seenSwitch && n.Kind != "doc" && n.Kind != "reply" {
43+ return nil, n.fail("value switch must be trailing")
44+ }
45+ if n.Kind == "list" {
46+ return nil, n.fail("lists combined with value switches are unsupported")
47+ }
48+ if !seenSwitch && n.Kind == "field" && n.Attr["name"] == sw.Children[0].Text {
49+ mask = n
50+ }
51+ }
52+ if mask == nil || mask.Attr["mask"] == "" {
53+ return nil, sw.fail("value switch requires a preceding typed mask")
54+ }
55+ mt, err := lookup(m, mask.Attr["type"])
56+ if err != nil {
57+ return nil, mask.fail("%v", err)
58+ }
59+ e, owner := findEnum(m, mask.Attr["mask"])
60+ if e == nil {
61+ return nil, mask.fail("unknown mask %s", mask.Attr["mask"])
62+ }
63+ if mt.Size > 4 || !isScalar(mt) {
64+ return nil, mask.fail("value mask must fit in 32 bits")
65+ }
66+ v := &ValueList{Mask: Field{Node: mask, GoType: qualified(m, owner, e.Name)}}
67+ used := map[int64]bool{}
68+ names := map[string]bool{"Mask": true}
69+ for _, bc := range sw.Children[1:] {
70+ var members []*Node
71+ for _, c := range bc.Children {
72+ if c.Kind != "doc" {
73+ members = append(members, c)
74+ }
75+ }
76+ if bc.Kind != "bitcase" || len(members) != 2 || members[0].Kind != "enumref" || members[1].Kind != "field" {
77+ return nil, bc.fail("value switch requires one enumref and one 4-byte field per bitcase")
78+ }
79+ bit, n := members[0], members[1]
80+ be, bo := findEnum(m, bit.Attr["ref"])
81+ if be != e || bo != owner {
82+ return nil, bit.fail("bitcase enum must match value mask")
83+ }
84+ var value int64
85+ found := false
86+ for _, item := range e.Items {
87+ if item.Name == e.Name+goName(bit.Text) {
88+ value = item.Value
89+ found = true
90+ }
91+ }
92+ if !found || value <= 0 || value&(value-1) != 0 || uint64(value) >= uint64(1)<<(8*mt.Size) || used[value] {
93+ return nil, bit.fail("bitcase requires a unique mask bit")
94+ }
95+ used[value] = true
96+ typ, err := lookup(m, n.Attr["type"])
97+ if err != nil {
98+ return nil, n.fail("%v", err)
99+ }
100+ if typ.Size != 4 || !isScalar(typ) {
101+ return nil, n.fail("value-list bitcase requires a 4-byte scalar field")
102+ }
103+ f := Field{Name: goName(n.Attr["name"]), GoType: qualified(m, typ.Module, typ.GoType), Type: typ, Node: n}
104+ for _, attr := range []string{"enum", "mask"} {
105+ if ref := n.Attr[attr]; ref != "" {
106+ fe, fo := findEnum(m, ref)
107+ if fe == nil {
108+ return nil, n.fail("unknown enum %s", ref)
109+ }
110+ f.GoType = qualified(m, fo, fe.Name)
111+ }
112+ }
113+ if names[f.Name] {
114+ return nil, n.fail("value field name collision %s", f.Name)
115+ }
116+ names[f.Name] = true
117+ v.Fields = append(v.Fields, ValueField{Field: f, Bit: qualified(m, owner, e.Name+goName(bit.Text)), Value: value})
118+ }
119+ sort.Slice(v.Fields, func(i, j int) bool { return v.Fields[i].Value < v.Fields[j].Value })
120+ if err := m.claim(name+"Values", sw); err != nil {
121+ return nil, err
122+ }
123+ return v, nil
124+}
125+func valuesDecl(name string, v *ValueList) string {
126+ var b strings.Builder
127+ fmt.Fprintf(&b, "type %sValues struct { Mask %s;", name, v.Mask.GoType)
128+ for _, f := range v.Fields {
129+ fmt.Fprintf(&b, "%s %s;", f.Field.Name, f.Field.GoType)
130+ }
131+ b.WriteString("};\n")
132+ for _, f := range v.Fields {
133+ fmt.Fprintf(&b, "func(v *%sValues) Set%s(x %s) *%sValues { v.Mask |= %s; v.%s=x; return v };\n", name, f.Field.Name, f.Field.GoType, name, f.Bit, f.Field.Name)
134+ }
135+ return b.String()
136+}
A cmd/xtgen/values_test.go +93 -0
@@ -0,0 +1,93 @@
1+package main
2+
3+import (
4+ "strings"
5+ "testing"
6+)
7+
8+func TestResolvePinnedValues(t *testing.T) {
9+ found := map[string]bool{}
10+ for _, m := range testModules(t) {
11+ rs, err := resolveRequests(m)
12+ if err != nil {
13+ t.Fatal(err)
14+ }
15+ for _, r := range rs {
16+ if r.Values != nil {
17+ found[m.Pkg+"/"+r.Name] = true
18+ if len(r.Values.Fields) == 0 {
19+ t.Fatal("empty values")
20+ }
21+ for i, f := range r.Values.Fields {
22+ if i > 0 && r.Values.Fields[i-1].Value >= f.Value {
23+ t.Fatal("not in bit order")
24+ }
25+ }
26+ for _, p := range r.Params {
27+ if p.Param == "valueMask" {
28+ t.Fatal("mask leaked into params")
29+ }
30+ }
31+ }
32+ }
33+ }
34+ for _, name := range []string{"xproto/CreateWindow", "xproto/ChangeWindowAttributes", "xproto/ConfigureWindow", "xproto/CreateGC", "xproto/ChangeGC", "xproto/ChangeKeyboardControl", "render/CreatePicture", "render/ChangePicture"} {
35+ if !found[name] {
36+ t.Error("missing", name)
37+ }
38+ }
39+ if len(found) != 8 {
40+ t.Fatal(found)
41+ }
42+}
43+
44+func TestResolveValueSwitches(t *testing.T) {
45+ prefix := `<xcb header="test"><enum name="Mask"><item name="Low"><bit>0</bit></item><item name="High"><bit>3</bit></item></enum><request name="Configure" opcode="1"><pad bytes="1"/><field name="value_mask" type="CARD32" mask="Mask"/>`
46+ high := `<bitcase><enumref ref="Mask">High</enumref><field name="high" type="BOOL32"/></bitcase>`
47+ low := `<bitcase><enumref ref="Mask">Low</enumref><field name="low" type="INT32"/></bitcase>`
48+ good := `<switch name="value_list"><fieldref>value_mask</fieldref>` + high + low + `</switch>`
49+ for _, tc := range []struct {
50+ name, body string
51+ valid bool
52+ }{
53+ {"sorted", good, true},
54+ {"expression", strings.Replace(good, "<fieldref>value_mask</fieldref>", "<popcount><fieldref>value_mask</fieldref></popcount>", 1), false},
55+ {"duplicate", strings.Replace(good, low, high, 1), false},
56+ {"unknown bit", strings.Replace(good, ">Low<", ">Missing<", 1), false},
57+ {"non scalar", strings.Replace(good, `type="INT32"`, `type="Pair"`, 1), false},
58+ {"trailing field", good + `<field name="extra" type="CARD32"/>`, false},
59+ } {
60+ t.Run(tc.name, func(t *testing.T) {
61+ xml := strings.Replace(prefix, `<request name=`, `<struct name="Pair"><field name="a" type="CARD32"/></struct><request name=`, 1) + tc.body + `</request></xcb>`
62+ n, err := parseXML("values.xml", strings.NewReader(xml))
63+ if err != nil {
64+ t.Fatal(err)
65+ }
66+ ms, err := resolveModules([]*Node{n})
67+ if err != nil {
68+ t.Fatal(err)
69+ }
70+ rs, err := resolveRequests(ms[0])
71+ if !tc.valid {
72+ if err == nil || !strings.Contains(err.Error(), "values.xml:1:") {
73+ t.Fatalf("got %v", err)
74+ }
75+ return
76+ }
77+ if err != nil {
78+ t.Fatal(err)
79+ }
80+ v := rs[0].Values
81+ if v.Fields[0].Field.Name != "Low" || v.Fields[1].Field.Name != "High" {
82+ t.Fatal("XML order used instead of bit order")
83+ }
84+ decl, err := requestDecl(ms[0], rs[0])
85+ if err != nil {
86+ t.Fatal(err)
87+ }
88+ if !strings.Contains(decl, "uint32(v.Low)") || !strings.Contains(decl, "if v.High") {
89+ t.Fatal(decl)
90+ }
91+ })
92+ }
93+}
@@ -0,0 +1,93 @@
1+package main
2+
3+import (
4+ "strings"
5+ "testing"
6+)
7+
8+func TestResolvePinnedValues(t *testing.T) {
9+ found := map[string]bool{}
10+ for _, m := range testModules(t) {
11+ rs, err := resolveRequests(m)
12+ if err != nil {
13+ t.Fatal(err)
14+ }
15+ for _, r := range rs {
16+ if r.Values != nil {
17+ found[m.Pkg+"/"+r.Name] = true
18+ if len(r.Values.Fields) == 0 {
19+ t.Fatal("empty values")
20+ }
21+ for i, f := range r.Values.Fields {
22+ if i > 0 && r.Values.Fields[i-1].Value >= f.Value {
23+ t.Fatal("not in bit order")
24+ }
25+ }
26+ for _, p := range r.Params {
27+ if p.Param == "valueMask" {
28+ t.Fatal("mask leaked into params")
29+ }
30+ }
31+ }
32+ }
33+ }
34+ for _, name := range []string{"xproto/CreateWindow", "xproto/ChangeWindowAttributes", "xproto/ConfigureWindow", "xproto/CreateGC", "xproto/ChangeGC", "xproto/ChangeKeyboardControl", "render/CreatePicture", "render/ChangePicture"} {
35+ if !found[name] {
36+ t.Error("missing", name)
37+ }
38+ }
39+ if len(found) != 8 {
40+ t.Fatal(found)
41+ }
42+}
43+
44+func TestResolveValueSwitches(t *testing.T) {
45+ prefix := `<xcb header="test"><enum name="Mask"><item name="Low"><bit>0</bit></item><item name="High"><bit>3</bit></item></enum><request name="Configure" opcode="1"><pad bytes="1"/><field name="value_mask" type="CARD32" mask="Mask"/>`
46+ high := `<bitcase><enumref ref="Mask">High</enumref><field name="high" type="BOOL32"/></bitcase>`
47+ low := `<bitcase><enumref ref="Mask">Low</enumref><field name="low" type="INT32"/></bitcase>`
48+ good := `<switch name="value_list"><fieldref>value_mask</fieldref>` + high + low + `</switch>`
49+ for _, tc := range []struct {
50+ name, body string
51+ valid bool
52+ }{
53+ {"sorted", good, true},
54+ {"expression", strings.Replace(good, "<fieldref>value_mask</fieldref>", "<popcount><fieldref>value_mask</fieldref></popcount>", 1), false},
55+ {"duplicate", strings.Replace(good, low, high, 1), false},
56+ {"unknown bit", strings.Replace(good, ">Low<", ">Missing<", 1), false},
57+ {"non scalar", strings.Replace(good, `type="INT32"`, `type="Pair"`, 1), false},
58+ {"trailing field", good + `<field name="extra" type="CARD32"/>`, false},
59+ } {
60+ t.Run(tc.name, func(t *testing.T) {
61+ xml := strings.Replace(prefix, `<request name=`, `<struct name="Pair"><field name="a" type="CARD32"/></struct><request name=`, 1) + tc.body + `</request></xcb>`
62+ n, err := parseXML("values.xml", strings.NewReader(xml))
63+ if err != nil {
64+ t.Fatal(err)
65+ }
66+ ms, err := resolveModules([]*Node{n})
67+ if err != nil {
68+ t.Fatal(err)
69+ }
70+ rs, err := resolveRequests(ms[0])
71+ if !tc.valid {
72+ if err == nil || !strings.Contains(err.Error(), "values.xml:1:") {
73+ t.Fatalf("got %v", err)
74+ }
75+ return
76+ }
77+ if err != nil {
78+ t.Fatal(err)
79+ }
80+ v := rs[0].Values
81+ if v.Fields[0].Field.Name != "Low" || v.Fields[1].Field.Name != "High" {
82+ t.Fatal("XML order used instead of bit order")
83+ }
84+ decl, err := requestDecl(ms[0], rs[0])
85+ if err != nil {
86+ t.Fatal(err)
87+ }
88+ if !strings.Contains(decl, "uint32(v.Low)") || !strings.Contains(decl, "if v.High") {
89+ t.Fatal(decl)
90+ }
91+ })
92+ }
93+}
M internal/xtest/README.md +9 -2
@@ -1,6 +1,6 @@
11 # Wire goldens
22
3-Refresh the T2.3 fixtures from the repository root:
3+Refresh the request fixtures from the repository root:
44
55 ```
66 PATH="$PATH:/usr/sbin" go test -tags xserver ./internal/xtest -update
@@ -15,10 +15,17 @@ The captured target is the root window; XFIXES's major opcode is negotiated.
1515 Tests read target/opcode from the fixture, not a hard-coded server assignment.
1616 No runtime Conn is needed at this phase.
1717
18-T2.4 should extend the independent encoder and capture cases for list requests.
1918 Replies, events and runtime integration belong to their subsequent tasks.
2019
2120 T2.4 adds InternAtom, ChangeProperty and XRes QueryClientIds. A GetProperty
2221 read-back validates the property contents. XRes's major opcode is negotiated;
2322 QueryVersion 1.2 precedes the ClientIdSpec-list query. The capture is independent
2423 of generated code, including counts, framing, and padding.
24+
25+T2.5 adds ConfigureWindow with empty, sparse and all-seven-bit masks,
26+CreateWindow, ChangeWindowAttributes and Render CreatePicture. The reference
27+encoder creates sibling windows, exercises signed coordinates and both BOOL32
28+values, and fences void requests with a successful reply (any preceding error
29+fails capture). RENDER's opcode and the root visual's picture format are queried
30+from Xvfb. Tests reuse only server-assigned resource/format IDs from fixtures;
31+mask bits, values and ordering remain independent expected inputs.
@@ -1,6 +1,6 @@
1 # Wire goldens1 # Wire goldens
2 2
3-Refresh the T2.3 fixtures from the repository root:3+Refresh the request fixtures from the repository root:
4 4
5 ```5 ```
6 PATH="$PATH:/usr/sbin" go test -tags xserver ./internal/xtest -update6 PATH="$PATH:/usr/sbin" go test -tags xserver ./internal/xtest -update
@@ -15,10 +15,17 @@ 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.15 Tests read target/opcode from the fixture, not a hard-coded server assignment.
16 No runtime Conn is needed at this phase.16 No runtime Conn is needed at this phase.
17 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.18 Replies, events and runtime integration belong to their subsequent tasks.
20 19
21 T2.4 adds InternAtom, ChangeProperty and XRes QueryClientIds. A GetProperty20 T2.4 adds InternAtom, ChangeProperty and XRes QueryClientIds. A GetProperty
22 read-back validates the property contents. XRes's major opcode is negotiated;21 read-back validates the property contents. XRes's major opcode is negotiated;
23 QueryVersion 1.2 precedes the ClientIdSpec-list query. The capture is independent22 QueryVersion 1.2 precedes the ClientIdSpec-list query. The capture is independent
24 of generated code, including counts, framing, and padding.23 of generated code, including counts, framing, and padding.
24+
25+T2.5 adds ConfigureWindow with empty, sparse and all-seven-bit masks,
26+CreateWindow, ChangeWindowAttributes and Render CreatePicture. The reference
27+encoder creates sibling windows, exercises signed coordinates and both BOOL32
28+values, and fences void requests with a successful reply (any preceding error
29+fails capture). RENDER's opcode and the root visual's picture format are queried
30+from Xvfb. Tests reuse only server-assigned resource/format IDs from fixtures;
31+mask bits, values and ordering remain independent expected inputs.
M internal/xtest/capture_test.go +104 -1
@@ -207,6 +207,95 @@ func TestCaptureRequests(t *testing.T) {
207207 if p := packet(); p[0] != 1 {
208208 t.Fatalf("QueryClientIds: %x", p)
209209 }
210+ // Value-list reference packets are assembled independently, including mask-bit
211+ // ordering. Two sibling windows allow all seven ConfigureWindow bits to be
212+ // exercised legally. A final reply fences all void requests and exposes errors.
213+ base := binary.LittleEndian.Uint32(setup[4:])
214+ child, sibling, picture := base|1, base|2, base|3
215+ create := func(id uint32, mask uint32, values ...uint32) {
216+ p := make([]byte, 32+4*len(values))
217+ p[0] = 1
218+ binary.LittleEndian.PutUint16(p[2:], uint16(len(p)/4))
219+ binary.LittleEndian.PutUint32(p[4:], id)
220+ binary.LittleEndian.PutUint32(p[8:], root)
221+ binary.LittleEndian.PutUint16(p[16:], 64)
222+ binary.LittleEndian.PutUint16(p[18:], 48)
223+ binary.LittleEndian.PutUint16(p[22:], 1) // InputOutput, inherited depth/visual
224+ binary.LittleEndian.PutUint32(p[28:], mask)
225+ for i, v := range values {
226+ binary.LittleEndian.PutUint32(p[32+4*i:], v)
227+ }
228+ write(p)
229+ }
230+ create(sibling, 0)
231+ create(child, 2|512|1024, 0x123456, 1, 0)
232+ change := make([]byte, 20)
233+ change[0], change[2] = 2, 5
234+ binary.LittleEndian.PutUint32(change[4:], child)
235+ binary.LittleEndian.PutUint32(change[8:], 512|1024)
236+ binary.LittleEndian.PutUint32(change[16:], 1) // false, true BOOL32 words
237+ write(change)
238+ configure := func(mask uint16, values ...uint32) {
239+ p := make([]byte, 12+4*len(values))
240+ p[0] = 12
241+ binary.LittleEndian.PutUint16(p[2:], uint16(len(p)/4))
242+ binary.LittleEndian.PutUint32(p[4:], child)
243+ binary.LittleEndian.PutUint16(p[8:], mask)
244+ for i, v := range values {
245+ binary.LittleEndian.PutUint32(p[12+4*i:], v)
246+ }
247+ write(p)
248+ }
249+ configure(0)
250+ configure(1|4|64, 0xfffffff9, 80, 0)
251+ configure(127, 0xfffffffd, 9, 96, 72, 2, sibling, 0)
252+ queryRender := []byte{98, 0, 4, 0, 6, 0, 0, 0, 'R', 'E', 'N', 'D', 'E', 'R', 0, 0}
253+ write(queryRender)
254+ renderExt := packet()
255+ if renderExt[0] != 1 || renderExt[8] != 1 {
256+ t.Fatalf("value requests/RENDER query: %x", renderExt)
257+ }
258+ renderMajor := renderExt[9]
259+ write([]byte{renderMajor, 1, 1, 0}) // QueryPictFormats
260+ formatsReply := packet()
261+ if formatsReply[0] != 1 {
262+ t.Fatalf("QueryPictFormats: %x", formatsReply)
263+ }
264+ // Match the root visual rather than guessing a server-assigned format ID.
265+ rootVisual := binary.LittleEndian.Uint32(setup[screenOff+32:])
266+ off := 32 + 28*int(binary.LittleEndian.Uint32(formatsReply[8:]))
267+ var format uint32
268+ for range binary.LittleEndian.Uint32(formatsReply[12:]) {
269+ depths := binary.LittleEndian.Uint32(formatsReply[off:])
270+ off += 8
271+ for range depths {
272+ visuals := binary.LittleEndian.Uint16(formatsReply[off+2:])
273+ off += 8
274+ for range visuals {
275+ if binary.LittleEndian.Uint32(formatsReply[off:]) == rootVisual {
276+ format = binary.LittleEndian.Uint32(formatsReply[off+4:])
277+ }
278+ off += 8
279+ }
280+ }
281+ }
282+ if format == 0 {
283+ t.Fatal("root visual has no Render format")
284+ }
285+ pic := make([]byte, 32)
286+ pic[0], pic[1], pic[2] = renderMajor, 4, 8
287+ binary.LittleEndian.PutUint32(pic[4:], picture)
288+ binary.LittleEndian.PutUint32(pic[8:], child)
289+ binary.LittleEndian.PutUint32(pic[12:], format)
290+ binary.LittleEndian.PutUint32(pic[16:], 1|16|32)
291+ binary.LittleEndian.PutUint32(pic[20:], 1) // RepeatNormal
292+ binary.LittleEndian.PutUint32(pic[24:], 0xfffffffb)
293+ binary.LittleEndian.PutUint32(pic[28:], 7)
294+ write(pic)
295+ write([]byte{43, 0, 1, 0}) // GetInputFocus fences CreatePicture
296+ if p := packet(); p[0] != 1 {
297+ t.Fatalf("CreatePicture rejected: %x", p)
298+ }
210299 // Closing the client drains the request direction; wait before inspecting tee.
211300 client.Close()
212301 select {
@@ -220,6 +309,7 @@ func TestCaptureRequests(t *testing.T) {
220309 stream := recorded.Bytes()
221310 requests := stream[12:]
222311 captured := map[string][]byte{}
312+ configIndex := 0
223313 for len(requests) > 0 {
224314 size := int(binary.LittleEndian.Uint16(requests[2:])) * 4
225315 if size < 4 || size > len(requests) {
@@ -227,6 +317,16 @@ func TestCaptureRequests(t *testing.T) {
227317 }
228318 p := requests[:size]
229319 switch p[0] {
320+ case 1:
321+ if binary.LittleEndian.Uint32(p[4:]) == child {
322+ captured["xproto/CreateWindow"] = p
323+ }
324+ case 2:
325+ captured["xproto/ChangeWindowAttributes"] = p
326+ case 12:
327+ names := []string{"ConfigureWindow", "ConfigureWindowSparse", "ConfigureWindowAll"}
328+ captured["xproto/"+names[configIndex]] = p
329+ configIndex++
230330 case 8:
231331 captured["xproto/MapWindow"] = p
232332 case 14:
@@ -236,6 +336,9 @@ func TestCaptureRequests(t *testing.T) {
236336 case 18:
237337 captured["xproto/ChangeProperty"] = p
238338 default:
339+ if p[0] == renderMajor && p[1] == 4 {
340+ captured["render/CreatePicture"] = p
341+ }
239342 if p[0] == resMajor && p[1] == 4 {
240343 captured["res/QueryClientIds"] = p
241344 }
@@ -245,7 +348,7 @@ func TestCaptureRequests(t *testing.T) {
245348 }
246349 requests = requests[size:]
247350 }
248- if len(captured) != 6 {
351+ if len(captured) != 12 {
249352 t.Fatal("missing captured requests")
250353 }
251354 for name, p := range captured {
@@ -207,6 +207,95 @@ func TestCaptureRequests(t *testing.T) {
207 if p := packet(); p[0] != 1 {207 if p := packet(); p[0] != 1 {
208 t.Fatalf("QueryClientIds: %x", p)208 t.Fatalf("QueryClientIds: %x", p)
209 }209 }
210+ // Value-list reference packets are assembled independently, including mask-bit
211+ // ordering. Two sibling windows allow all seven ConfigureWindow bits to be
212+ // exercised legally. A final reply fences all void requests and exposes errors.
213+ base := binary.LittleEndian.Uint32(setup[4:])
214+ child, sibling, picture := base|1, base|2, base|3
215+ create := func(id uint32, mask uint32, values ...uint32) {
216+ p := make([]byte, 32+4*len(values))
217+ p[0] = 1
218+ binary.LittleEndian.PutUint16(p[2:], uint16(len(p)/4))
219+ binary.LittleEndian.PutUint32(p[4:], id)
220+ binary.LittleEndian.PutUint32(p[8:], root)
221+ binary.LittleEndian.PutUint16(p[16:], 64)
222+ binary.LittleEndian.PutUint16(p[18:], 48)
223+ binary.LittleEndian.PutUint16(p[22:], 1) // InputOutput, inherited depth/visual
224+ binary.LittleEndian.PutUint32(p[28:], mask)
225+ for i, v := range values {
226+ binary.LittleEndian.PutUint32(p[32+4*i:], v)
227+ }
228+ write(p)
229+ }
230+ create(sibling, 0)
231+ create(child, 2|512|1024, 0x123456, 1, 0)
232+ change := make([]byte, 20)
233+ change[0], change[2] = 2, 5
234+ binary.LittleEndian.PutUint32(change[4:], child)
235+ binary.LittleEndian.PutUint32(change[8:], 512|1024)
236+ binary.LittleEndian.PutUint32(change[16:], 1) // false, true BOOL32 words
237+ write(change)
238+ configure := func(mask uint16, values ...uint32) {
239+ p := make([]byte, 12+4*len(values))
240+ p[0] = 12
241+ binary.LittleEndian.PutUint16(p[2:], uint16(len(p)/4))
242+ binary.LittleEndian.PutUint32(p[4:], child)
243+ binary.LittleEndian.PutUint16(p[8:], mask)
244+ for i, v := range values {
245+ binary.LittleEndian.PutUint32(p[12+4*i:], v)
246+ }
247+ write(p)
248+ }
249+ configure(0)
250+ configure(1|4|64, 0xfffffff9, 80, 0)
251+ configure(127, 0xfffffffd, 9, 96, 72, 2, sibling, 0)
252+ queryRender := []byte{98, 0, 4, 0, 6, 0, 0, 0, 'R', 'E', 'N', 'D', 'E', 'R', 0, 0}
253+ write(queryRender)
254+ renderExt := packet()
255+ if renderExt[0] != 1 || renderExt[8] != 1 {
256+ t.Fatalf("value requests/RENDER query: %x", renderExt)
257+ }
258+ renderMajor := renderExt[9]
259+ write([]byte{renderMajor, 1, 1, 0}) // QueryPictFormats
260+ formatsReply := packet()
261+ if formatsReply[0] != 1 {
262+ t.Fatalf("QueryPictFormats: %x", formatsReply)
263+ }
264+ // Match the root visual rather than guessing a server-assigned format ID.
265+ rootVisual := binary.LittleEndian.Uint32(setup[screenOff+32:])
266+ off := 32 + 28*int(binary.LittleEndian.Uint32(formatsReply[8:]))
267+ var format uint32
268+ for range binary.LittleEndian.Uint32(formatsReply[12:]) {
269+ depths := binary.LittleEndian.Uint32(formatsReply[off:])
270+ off += 8
271+ for range depths {
272+ visuals := binary.LittleEndian.Uint16(formatsReply[off+2:])
273+ off += 8
274+ for range visuals {
275+ if binary.LittleEndian.Uint32(formatsReply[off:]) == rootVisual {
276+ format = binary.LittleEndian.Uint32(formatsReply[off+4:])
277+ }
278+ off += 8
279+ }
280+ }
281+ }
282+ if format == 0 {
283+ t.Fatal("root visual has no Render format")
284+ }
285+ pic := make([]byte, 32)
286+ pic[0], pic[1], pic[2] = renderMajor, 4, 8
287+ binary.LittleEndian.PutUint32(pic[4:], picture)
288+ binary.LittleEndian.PutUint32(pic[8:], child)
289+ binary.LittleEndian.PutUint32(pic[12:], format)
290+ binary.LittleEndian.PutUint32(pic[16:], 1|16|32)
291+ binary.LittleEndian.PutUint32(pic[20:], 1) // RepeatNormal
292+ binary.LittleEndian.PutUint32(pic[24:], 0xfffffffb)
293+ binary.LittleEndian.PutUint32(pic[28:], 7)
294+ write(pic)
295+ write([]byte{43, 0, 1, 0}) // GetInputFocus fences CreatePicture
296+ if p := packet(); p[0] != 1 {
297+ t.Fatalf("CreatePicture rejected: %x", p)
298+ }
210 // Closing the client drains the request direction; wait before inspecting tee.299 // Closing the client drains the request direction; wait before inspecting tee.
211 client.Close()300 client.Close()
212 select {301 select {
@@ -220,6 +309,7 @@ func TestCaptureRequests(t *testing.T) {
220 stream := recorded.Bytes()309 stream := recorded.Bytes()
221 requests := stream[12:]310 requests := stream[12:]
222 captured := map[string][]byte{}311 captured := map[string][]byte{}
312+ configIndex := 0
223 for len(requests) > 0 {313 for len(requests) > 0 {
224 size := int(binary.LittleEndian.Uint16(requests[2:])) * 4314 size := int(binary.LittleEndian.Uint16(requests[2:])) * 4
225 if size < 4 || size > len(requests) {315 if size < 4 || size > len(requests) {
@@ -227,6 +317,16 @@ func TestCaptureRequests(t *testing.T) {
227 }317 }
228 p := requests[:size]318 p := requests[:size]
229 switch p[0] {319 switch p[0] {
320+ case 1:
321+ if binary.LittleEndian.Uint32(p[4:]) == child {
322+ captured["xproto/CreateWindow"] = p
323+ }
324+ case 2:
325+ captured["xproto/ChangeWindowAttributes"] = p
326+ case 12:
327+ names := []string{"ConfigureWindow", "ConfigureWindowSparse", "ConfigureWindowAll"}
328+ captured["xproto/"+names[configIndex]] = p
329+ configIndex++
230 case 8:330 case 8:
231 captured["xproto/MapWindow"] = p331 captured["xproto/MapWindow"] = p
232 case 14:332 case 14:
@@ -236,6 +336,9 @@ func TestCaptureRequests(t *testing.T) {
236 case 18:336 case 18:
237 captured["xproto/ChangeProperty"] = p337 captured["xproto/ChangeProperty"] = p
238 default:338 default:
339+ if p[0] == renderMajor && p[1] == 4 {
340+ captured["render/CreatePicture"] = p
341+ }
239 if p[0] == resMajor && p[1] == 4 {342 if p[0] == resMajor && p[1] == 4 {
240 captured["res/QueryClientIds"] = p343 captured["res/QueryClientIds"] = p
241 }344 }
@@ -245,7 +348,7 @@ func TestCaptureRequests(t *testing.T) {
245 }348 }
246 requests = requests[size:]349 requests = requests[size:]
247 }350 }
248- if len(captured) != 6 {351+ if len(captured) != 12 {
249 t.Fatal("missing captured requests")352 t.Fatal("missing captured requests")
250 }353 }
251 for name, p := range captured {354 for name, p := range captured {
M render/requests_generated.go +313 -0
@@ -3,6 +3,7 @@ package render
33
44 import "bnema.dev/xturbo/xproto"
55 import "encoding/binary"
6+import "math/bits"
67 import "bnema.dev/xturbo"
78
89 func QueryVersion(b *xturbo.Buf, clientMajorVersion uint32, clientMinorVersion uint32) xturbo.Seq {
@@ -59,6 +60,318 @@ func QueryPictIndexValues(b *xturbo.Buf, format Pictformat) xturbo.Seq {
5960 return seq
6061 }
6162
63+type CreatePictureValues struct {
64+ Mask Cp
65+ Repeat Repeat
66+ Alphamap Picture
67+ Alphaxorigin int32
68+ Alphayorigin int32
69+ Clipxorigin int32
70+ Clipyorigin int32
71+ Clipmask xproto.Pixmap
72+ Graphicsexposure uint32
73+ Subwindowmode xproto.SubwindowMode
74+ Polyedge PolyEdge
75+ Polymode PolyMode
76+ Dither xproto.Atom
77+ Componentalpha uint32
78+}
79+
80+func (v *CreatePictureValues) SetRepeat(x Repeat) *CreatePictureValues {
81+ v.Mask |= CpRepeat
82+ v.Repeat = x
83+ return v
84+}
85+func (v *CreatePictureValues) SetAlphamap(x Picture) *CreatePictureValues {
86+ v.Mask |= CpAlphaMap
87+ v.Alphamap = x
88+ return v
89+}
90+func (v *CreatePictureValues) SetAlphaxorigin(x int32) *CreatePictureValues {
91+ v.Mask |= CpAlphaXOrigin
92+ v.Alphaxorigin = x
93+ return v
94+}
95+func (v *CreatePictureValues) SetAlphayorigin(x int32) *CreatePictureValues {
96+ v.Mask |= CpAlphaYOrigin
97+ v.Alphayorigin = x
98+ return v
99+}
100+func (v *CreatePictureValues) SetClipxorigin(x int32) *CreatePictureValues {
101+ v.Mask |= CpClipXOrigin
102+ v.Clipxorigin = x
103+ return v
104+}
105+func (v *CreatePictureValues) SetClipyorigin(x int32) *CreatePictureValues {
106+ v.Mask |= CpClipYOrigin
107+ v.Clipyorigin = x
108+ return v
109+}
110+func (v *CreatePictureValues) SetClipmask(x xproto.Pixmap) *CreatePictureValues {
111+ v.Mask |= CpClipMask
112+ v.Clipmask = x
113+ return v
114+}
115+func (v *CreatePictureValues) SetGraphicsexposure(x uint32) *CreatePictureValues {
116+ v.Mask |= CpGraphicsExposure
117+ v.Graphicsexposure = x
118+ return v
119+}
120+func (v *CreatePictureValues) SetSubwindowmode(x xproto.SubwindowMode) *CreatePictureValues {
121+ v.Mask |= CpSubwindowMode
122+ v.Subwindowmode = x
123+ return v
124+}
125+func (v *CreatePictureValues) SetPolyedge(x PolyEdge) *CreatePictureValues {
126+ v.Mask |= CpPolyEdge
127+ v.Polyedge = x
128+ return v
129+}
130+func (v *CreatePictureValues) SetPolymode(x PolyMode) *CreatePictureValues {
131+ v.Mask |= CpPolyMode
132+ v.Polymode = x
133+ return v
134+}
135+func (v *CreatePictureValues) SetDither(x xproto.Atom) *CreatePictureValues {
136+ v.Mask |= CpDither
137+ v.Dither = x
138+ return v
139+}
140+func (v *CreatePictureValues) SetComponentalpha(x uint32) *CreatePictureValues {
141+ v.Mask |= CpComponentAlpha
142+ v.Componentalpha = x
143+ return v
144+}
145+func CreatePicture(b *xturbo.Buf, pid Picture, drawable xproto.Drawable, format Pictformat, v *CreatePictureValues) xturbo.Seq {
146+ if b.Ext == nil {
147+ b.Fail(xturbo.ErrExtMissing)
148+ return 0
149+ }
150+ major := b.Ext.Major(xturbo.ExtRender)
151+ if major == 0 {
152+ b.Fail(xturbo.ErrExtMissing)
153+ return 0
154+ }
155+ p, seq := b.Request(major, 4, 16+4*bits.OnesCount32(uint32(v.Mask)))
156+ if p == nil {
157+ return 0
158+ }
159+ binary.LittleEndian.PutUint32(p[0:], uint32(pid))
160+ binary.LittleEndian.PutUint32(p[4:], uint32(drawable))
161+ binary.LittleEndian.PutUint32(p[8:], uint32(format))
162+ binary.LittleEndian.PutUint32(p[12:], uint32(v.Mask))
163+ off := 16
164+ if v.Mask&CpRepeat != 0 {
165+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Repeat))
166+ off += 4
167+ }
168+ if v.Mask&CpAlphaMap != 0 {
169+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Alphamap))
170+ off += 4
171+ }
172+ if v.Mask&CpAlphaXOrigin != 0 {
173+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Alphaxorigin))
174+ off += 4
175+ }
176+ if v.Mask&CpAlphaYOrigin != 0 {
177+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Alphayorigin))
178+ off += 4
179+ }
180+ if v.Mask&CpClipXOrigin != 0 {
181+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Clipxorigin))
182+ off += 4
183+ }
184+ if v.Mask&CpClipYOrigin != 0 {
185+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Clipyorigin))
186+ off += 4
187+ }
188+ if v.Mask&CpClipMask != 0 {
189+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Clipmask))
190+ off += 4
191+ }
192+ if v.Mask&CpGraphicsExposure != 0 {
193+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Graphicsexposure))
194+ off += 4
195+ }
196+ if v.Mask&CpSubwindowMode != 0 {
197+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Subwindowmode))
198+ off += 4
199+ }
200+ if v.Mask&CpPolyEdge != 0 {
201+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Polyedge))
202+ off += 4
203+ }
204+ if v.Mask&CpPolyMode != 0 {
205+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Polymode))
206+ off += 4
207+ }
208+ if v.Mask&CpDither != 0 {
209+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Dither))
210+ off += 4
211+ }
212+ if v.Mask&CpComponentAlpha != 0 {
213+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Componentalpha))
214+ off += 4
215+ }
216+ _ = off
217+ return seq
218+}
219+
220+type ChangePictureValues struct {
221+ Mask Cp
222+ Repeat Repeat
223+ Alphamap Picture
224+ Alphaxorigin int32
225+ Alphayorigin int32
226+ Clipxorigin int32
227+ Clipyorigin int32
228+ Clipmask xproto.Pixmap
229+ Graphicsexposure uint32
230+ Subwindowmode xproto.SubwindowMode
231+ Polyedge PolyEdge
232+ Polymode PolyMode
233+ Dither xproto.Atom
234+ Componentalpha uint32
235+}
236+
237+func (v *ChangePictureValues) SetRepeat(x Repeat) *ChangePictureValues {
238+ v.Mask |= CpRepeat
239+ v.Repeat = x
240+ return v
241+}
242+func (v *ChangePictureValues) SetAlphamap(x Picture) *ChangePictureValues {
243+ v.Mask |= CpAlphaMap
244+ v.Alphamap = x
245+ return v
246+}
247+func (v *ChangePictureValues) SetAlphaxorigin(x int32) *ChangePictureValues {
248+ v.Mask |= CpAlphaXOrigin
249+ v.Alphaxorigin = x
250+ return v
251+}
252+func (v *ChangePictureValues) SetAlphayorigin(x int32) *ChangePictureValues {
253+ v.Mask |= CpAlphaYOrigin
254+ v.Alphayorigin = x
255+ return v
256+}
257+func (v *ChangePictureValues) SetClipxorigin(x int32) *ChangePictureValues {
258+ v.Mask |= CpClipXOrigin
259+ v.Clipxorigin = x
260+ return v
261+}
262+func (v *ChangePictureValues) SetClipyorigin(x int32) *ChangePictureValues {
263+ v.Mask |= CpClipYOrigin
264+ v.Clipyorigin = x
265+ return v
266+}
267+func (v *ChangePictureValues) SetClipmask(x xproto.Pixmap) *ChangePictureValues {
268+ v.Mask |= CpClipMask
269+ v.Clipmask = x
270+ return v
271+}
272+func (v *ChangePictureValues) SetGraphicsexposure(x uint32) *ChangePictureValues {
273+ v.Mask |= CpGraphicsExposure
274+ v.Graphicsexposure = x
275+ return v
276+}
277+func (v *ChangePictureValues) SetSubwindowmode(x xproto.SubwindowMode) *ChangePictureValues {
278+ v.Mask |= CpSubwindowMode
279+ v.Subwindowmode = x
280+ return v
281+}
282+func (v *ChangePictureValues) SetPolyedge(x PolyEdge) *ChangePictureValues {
283+ v.Mask |= CpPolyEdge
284+ v.Polyedge = x
285+ return v
286+}
287+func (v *ChangePictureValues) SetPolymode(x PolyMode) *ChangePictureValues {
288+ v.Mask |= CpPolyMode
289+ v.Polymode = x
290+ return v
291+}
292+func (v *ChangePictureValues) SetDither(x xproto.Atom) *ChangePictureValues {
293+ v.Mask |= CpDither
294+ v.Dither = x
295+ return v
296+}
297+func (v *ChangePictureValues) SetComponentalpha(x uint32) *ChangePictureValues {
298+ v.Mask |= CpComponentAlpha
299+ v.Componentalpha = x
300+ return v
301+}
302+func ChangePicture(b *xturbo.Buf, picture Picture, v *ChangePictureValues) xturbo.Seq {
303+ if b.Ext == nil {
304+ b.Fail(xturbo.ErrExtMissing)
305+ return 0
306+ }
307+ major := b.Ext.Major(xturbo.ExtRender)
308+ if major == 0 {
309+ b.Fail(xturbo.ErrExtMissing)
310+ return 0
311+ }
312+ p, seq := b.Request(major, 5, 8+4*bits.OnesCount32(uint32(v.Mask)))
313+ if p == nil {
314+ return 0
315+ }
316+ binary.LittleEndian.PutUint32(p[0:], uint32(picture))
317+ binary.LittleEndian.PutUint32(p[4:], uint32(v.Mask))
318+ off := 8
319+ if v.Mask&CpRepeat != 0 {
320+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Repeat))
321+ off += 4
322+ }
323+ if v.Mask&CpAlphaMap != 0 {
324+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Alphamap))
325+ off += 4
326+ }
327+ if v.Mask&CpAlphaXOrigin != 0 {
328+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Alphaxorigin))
329+ off += 4
330+ }
331+ if v.Mask&CpAlphaYOrigin != 0 {
332+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Alphayorigin))
333+ off += 4
334+ }
335+ if v.Mask&CpClipXOrigin != 0 {
336+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Clipxorigin))
337+ off += 4
338+ }
339+ if v.Mask&CpClipYOrigin != 0 {
340+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Clipyorigin))
341+ off += 4
342+ }
343+ if v.Mask&CpClipMask != 0 {
344+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Clipmask))
345+ off += 4
346+ }
347+ if v.Mask&CpGraphicsExposure != 0 {
348+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Graphicsexposure))
349+ off += 4
350+ }
351+ if v.Mask&CpSubwindowMode != 0 {
352+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Subwindowmode))
353+ off += 4
354+ }
355+ if v.Mask&CpPolyEdge != 0 {
356+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Polyedge))
357+ off += 4
358+ }
359+ if v.Mask&CpPolyMode != 0 {
360+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Polymode))
361+ off += 4
362+ }
363+ if v.Mask&CpDither != 0 {
364+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Dither))
365+ off += 4
366+ }
367+ if v.Mask&CpComponentAlpha != 0 {
368+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Componentalpha))
369+ off += 4
370+ }
371+ _ = off
372+ return seq
373+}
374+
62375 func SetPictureClipRectangles(b *xturbo.Buf, picture Picture, clipXOrigin int16, clipYOrigin int16, rectangles []xproto.Rectangle) xturbo.Seq {
63376 size := 0
64377 size += 4
@@ -3,6 +3,7 @@ package render
3 3
4 import "bnema.dev/xturbo/xproto"4 import "bnema.dev/xturbo/xproto"
5 import "encoding/binary"5 import "encoding/binary"
6+import "math/bits"
6 import "bnema.dev/xturbo"7 import "bnema.dev/xturbo"
7 8
8 func QueryVersion(b *xturbo.Buf, clientMajorVersion uint32, clientMinorVersion uint32) xturbo.Seq {9 func QueryVersion(b *xturbo.Buf, clientMajorVersion uint32, clientMinorVersion uint32) xturbo.Seq {
@@ -59,6 +60,318 @@ func QueryPictIndexValues(b *xturbo.Buf, format Pictformat) xturbo.Seq {
59 return seq60 return seq
60 }61 }
61 62
63+type CreatePictureValues struct {
64+ Mask Cp
65+ Repeat Repeat
66+ Alphamap Picture
67+ Alphaxorigin int32
68+ Alphayorigin int32
69+ Clipxorigin int32
70+ Clipyorigin int32
71+ Clipmask xproto.Pixmap
72+ Graphicsexposure uint32
73+ Subwindowmode xproto.SubwindowMode
74+ Polyedge PolyEdge
75+ Polymode PolyMode
76+ Dither xproto.Atom
77+ Componentalpha uint32
78+}
79+
80+func (v *CreatePictureValues) SetRepeat(x Repeat) *CreatePictureValues {
81+ v.Mask |= CpRepeat
82+ v.Repeat = x
83+ return v
84+}
85+func (v *CreatePictureValues) SetAlphamap(x Picture) *CreatePictureValues {
86+ v.Mask |= CpAlphaMap
87+ v.Alphamap = x
88+ return v
89+}
90+func (v *CreatePictureValues) SetAlphaxorigin(x int32) *CreatePictureValues {
91+ v.Mask |= CpAlphaXOrigin
92+ v.Alphaxorigin = x
93+ return v
94+}
95+func (v *CreatePictureValues) SetAlphayorigin(x int32) *CreatePictureValues {
96+ v.Mask |= CpAlphaYOrigin
97+ v.Alphayorigin = x
98+ return v
99+}
100+func (v *CreatePictureValues) SetClipxorigin(x int32) *CreatePictureValues {
101+ v.Mask |= CpClipXOrigin
102+ v.Clipxorigin = x
103+ return v
104+}
105+func (v *CreatePictureValues) SetClipyorigin(x int32) *CreatePictureValues {
106+ v.Mask |= CpClipYOrigin
107+ v.Clipyorigin = x
108+ return v
109+}
110+func (v *CreatePictureValues) SetClipmask(x xproto.Pixmap) *CreatePictureValues {
111+ v.Mask |= CpClipMask
112+ v.Clipmask = x
113+ return v
114+}
115+func (v *CreatePictureValues) SetGraphicsexposure(x uint32) *CreatePictureValues {
116+ v.Mask |= CpGraphicsExposure
117+ v.Graphicsexposure = x
118+ return v
119+}
120+func (v *CreatePictureValues) SetSubwindowmode(x xproto.SubwindowMode) *CreatePictureValues {
121+ v.Mask |= CpSubwindowMode
122+ v.Subwindowmode = x
123+ return v
124+}
125+func (v *CreatePictureValues) SetPolyedge(x PolyEdge) *CreatePictureValues {
126+ v.Mask |= CpPolyEdge
127+ v.Polyedge = x
128+ return v
129+}
130+func (v *CreatePictureValues) SetPolymode(x PolyMode) *CreatePictureValues {
131+ v.Mask |= CpPolyMode
132+ v.Polymode = x
133+ return v
134+}
135+func (v *CreatePictureValues) SetDither(x xproto.Atom) *CreatePictureValues {
136+ v.Mask |= CpDither
137+ v.Dither = x
138+ return v
139+}
140+func (v *CreatePictureValues) SetComponentalpha(x uint32) *CreatePictureValues {
141+ v.Mask |= CpComponentAlpha
142+ v.Componentalpha = x
143+ return v
144+}
145+func CreatePicture(b *xturbo.Buf, pid Picture, drawable xproto.Drawable, format Pictformat, v *CreatePictureValues) xturbo.Seq {
146+ if b.Ext == nil {
147+ b.Fail(xturbo.ErrExtMissing)
148+ return 0
149+ }
150+ major := b.Ext.Major(xturbo.ExtRender)
151+ if major == 0 {
152+ b.Fail(xturbo.ErrExtMissing)
153+ return 0
154+ }
155+ p, seq := b.Request(major, 4, 16+4*bits.OnesCount32(uint32(v.Mask)))
156+ if p == nil {
157+ return 0
158+ }
159+ binary.LittleEndian.PutUint32(p[0:], uint32(pid))
160+ binary.LittleEndian.PutUint32(p[4:], uint32(drawable))
161+ binary.LittleEndian.PutUint32(p[8:], uint32(format))
162+ binary.LittleEndian.PutUint32(p[12:], uint32(v.Mask))
163+ off := 16
164+ if v.Mask&CpRepeat != 0 {
165+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Repeat))
166+ off += 4
167+ }
168+ if v.Mask&CpAlphaMap != 0 {
169+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Alphamap))
170+ off += 4
171+ }
172+ if v.Mask&CpAlphaXOrigin != 0 {
173+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Alphaxorigin))
174+ off += 4
175+ }
176+ if v.Mask&CpAlphaYOrigin != 0 {
177+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Alphayorigin))
178+ off += 4
179+ }
180+ if v.Mask&CpClipXOrigin != 0 {
181+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Clipxorigin))
182+ off += 4
183+ }
184+ if v.Mask&CpClipYOrigin != 0 {
185+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Clipyorigin))
186+ off += 4
187+ }
188+ if v.Mask&CpClipMask != 0 {
189+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Clipmask))
190+ off += 4
191+ }
192+ if v.Mask&CpGraphicsExposure != 0 {
193+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Graphicsexposure))
194+ off += 4
195+ }
196+ if v.Mask&CpSubwindowMode != 0 {
197+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Subwindowmode))
198+ off += 4
199+ }
200+ if v.Mask&CpPolyEdge != 0 {
201+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Polyedge))
202+ off += 4
203+ }
204+ if v.Mask&CpPolyMode != 0 {
205+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Polymode))
206+ off += 4
207+ }
208+ if v.Mask&CpDither != 0 {
209+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Dither))
210+ off += 4
211+ }
212+ if v.Mask&CpComponentAlpha != 0 {
213+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Componentalpha))
214+ off += 4
215+ }
216+ _ = off
217+ return seq
218+}
219+
220+type ChangePictureValues struct {
221+ Mask Cp
222+ Repeat Repeat
223+ Alphamap Picture
224+ Alphaxorigin int32
225+ Alphayorigin int32
226+ Clipxorigin int32
227+ Clipyorigin int32
228+ Clipmask xproto.Pixmap
229+ Graphicsexposure uint32
230+ Subwindowmode xproto.SubwindowMode
231+ Polyedge PolyEdge
232+ Polymode PolyMode
233+ Dither xproto.Atom
234+ Componentalpha uint32
235+}
236+
237+func (v *ChangePictureValues) SetRepeat(x Repeat) *ChangePictureValues {
238+ v.Mask |= CpRepeat
239+ v.Repeat = x
240+ return v
241+}
242+func (v *ChangePictureValues) SetAlphamap(x Picture) *ChangePictureValues {
243+ v.Mask |= CpAlphaMap
244+ v.Alphamap = x
245+ return v
246+}
247+func (v *ChangePictureValues) SetAlphaxorigin(x int32) *ChangePictureValues {
248+ v.Mask |= CpAlphaXOrigin
249+ v.Alphaxorigin = x
250+ return v
251+}
252+func (v *ChangePictureValues) SetAlphayorigin(x int32) *ChangePictureValues {
253+ v.Mask |= CpAlphaYOrigin
254+ v.Alphayorigin = x
255+ return v
256+}
257+func (v *ChangePictureValues) SetClipxorigin(x int32) *ChangePictureValues {
258+ v.Mask |= CpClipXOrigin
259+ v.Clipxorigin = x
260+ return v
261+}
262+func (v *ChangePictureValues) SetClipyorigin(x int32) *ChangePictureValues {
263+ v.Mask |= CpClipYOrigin
264+ v.Clipyorigin = x
265+ return v
266+}
267+func (v *ChangePictureValues) SetClipmask(x xproto.Pixmap) *ChangePictureValues {
268+ v.Mask |= CpClipMask
269+ v.Clipmask = x
270+ return v
271+}
272+func (v *ChangePictureValues) SetGraphicsexposure(x uint32) *ChangePictureValues {
273+ v.Mask |= CpGraphicsExposure
274+ v.Graphicsexposure = x
275+ return v
276+}
277+func (v *ChangePictureValues) SetSubwindowmode(x xproto.SubwindowMode) *ChangePictureValues {
278+ v.Mask |= CpSubwindowMode
279+ v.Subwindowmode = x
280+ return v
281+}
282+func (v *ChangePictureValues) SetPolyedge(x PolyEdge) *ChangePictureValues {
283+ v.Mask |= CpPolyEdge
284+ v.Polyedge = x
285+ return v
286+}
287+func (v *ChangePictureValues) SetPolymode(x PolyMode) *ChangePictureValues {
288+ v.Mask |= CpPolyMode
289+ v.Polymode = x
290+ return v
291+}
292+func (v *ChangePictureValues) SetDither(x xproto.Atom) *ChangePictureValues {
293+ v.Mask |= CpDither
294+ v.Dither = x
295+ return v
296+}
297+func (v *ChangePictureValues) SetComponentalpha(x uint32) *ChangePictureValues {
298+ v.Mask |= CpComponentAlpha
299+ v.Componentalpha = x
300+ return v
301+}
302+func ChangePicture(b *xturbo.Buf, picture Picture, v *ChangePictureValues) xturbo.Seq {
303+ if b.Ext == nil {
304+ b.Fail(xturbo.ErrExtMissing)
305+ return 0
306+ }
307+ major := b.Ext.Major(xturbo.ExtRender)
308+ if major == 0 {
309+ b.Fail(xturbo.ErrExtMissing)
310+ return 0
311+ }
312+ p, seq := b.Request(major, 5, 8+4*bits.OnesCount32(uint32(v.Mask)))
313+ if p == nil {
314+ return 0
315+ }
316+ binary.LittleEndian.PutUint32(p[0:], uint32(picture))
317+ binary.LittleEndian.PutUint32(p[4:], uint32(v.Mask))
318+ off := 8
319+ if v.Mask&CpRepeat != 0 {
320+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Repeat))
321+ off += 4
322+ }
323+ if v.Mask&CpAlphaMap != 0 {
324+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Alphamap))
325+ off += 4
326+ }
327+ if v.Mask&CpAlphaXOrigin != 0 {
328+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Alphaxorigin))
329+ off += 4
330+ }
331+ if v.Mask&CpAlphaYOrigin != 0 {
332+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Alphayorigin))
333+ off += 4
334+ }
335+ if v.Mask&CpClipXOrigin != 0 {
336+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Clipxorigin))
337+ off += 4
338+ }
339+ if v.Mask&CpClipYOrigin != 0 {
340+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Clipyorigin))
341+ off += 4
342+ }
343+ if v.Mask&CpClipMask != 0 {
344+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Clipmask))
345+ off += 4
346+ }
347+ if v.Mask&CpGraphicsExposure != 0 {
348+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Graphicsexposure))
349+ off += 4
350+ }
351+ if v.Mask&CpSubwindowMode != 0 {
352+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Subwindowmode))
353+ off += 4
354+ }
355+ if v.Mask&CpPolyEdge != 0 {
356+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Polyedge))
357+ off += 4
358+ }
359+ if v.Mask&CpPolyMode != 0 {
360+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Polymode))
361+ off += 4
362+ }
363+ if v.Mask&CpDither != 0 {
364+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Dither))
365+ off += 4
366+ }
367+ if v.Mask&CpComponentAlpha != 0 {
368+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Componentalpha))
369+ off += 4
370+ }
371+ _ = off
372+ return seq
373+}
374+
62 func SetPictureClipRectangles(b *xturbo.Buf, picture Picture, clipXOrigin int16, clipYOrigin int16, rectangles []xproto.Rectangle) xturbo.Seq {375 func SetPictureClipRectangles(b *xturbo.Buf, picture Picture, clipXOrigin int16, clipYOrigin int16, rectangles []xproto.Rectangle) xturbo.Seq {
63 size := 0376 size := 0
64 size += 4377 size += 4
A testdata/golden/render/CreatePicture.req.hex +3 -0
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+8b0408000300200001002000290000003100000001000000fbffffff07000000
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+8b0408000300200001002000290000003100000001000000fbffffff07000000
A testdata/golden/xproto/ChangeWindowAttributes.req.hex +3 -0
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+0200050001002000000600000000000001000000
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+0200050001002000000600000000000001000000
A testdata/golden/xproto/ConfigureWindow.req.hex +3 -0
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+0c0003000100200000000000
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+0c0003000100200000000000
A testdata/golden/xproto/ConfigureWindowAll.req.hex +3 -0
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+0c000a00010020007f000000fdffffff090000006000000048000000020000000200200000000000
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+0c000a00010020007f000000fdffffff090000006000000048000000020000000200200000000000
A testdata/golden/xproto/ConfigureWindowSparse.req.hex +3 -0
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+0c0006000100200045000000f9ffffff5000000000000000
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+0c0006000100200045000000f9ffffff5000000000000000
A testdata/golden/xproto/CreateWindow.req.hex +3 -0
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+01000b00010020009f0300000000000040003000000001000000000002060000563412000100000000000000
@@ -0,0 +1,3 @@
1+# source: Xvfb via raw socketpair tee; independent reference encoder; server accepted
2+# xtrace fallback: local xtrace is glibc's execution tracer, not X11 xtrace
3+01000b00010020009f0300000000000040003000000001000000000002060000563412000100000000000000
A values_test.go +103 -0
@@ -0,0 +1,103 @@
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/render"
11+ "bnema.dev/xturbo/xproto"
12+)
13+
14+func TestValueRequestGoldens(t *testing.T) {
15+ for _, name := range []string{"xproto/ConfigureWindow", "xproto/ConfigureWindowSparse", "xproto/ConfigureWindowAll", "xproto/CreateWindow", "xproto/ChangeWindowAttributes", "render/CreatePicture"} {
16+ t.Run(name, func(t *testing.T) {
17+ want, err := xtest.LoadHex("testdata/golden/" + name + ".req.hex")
18+ if err != nil {
19+ t.Fatal(err)
20+ }
21+ u32 := func(off int) uint32 { return binary.LittleEndian.Uint32(want[off:]) }
22+ b := xturbo.NewBuf(0)
23+ var seq xturbo.Seq
24+ switch name {
25+ case "xproto/ConfigureWindow":
26+ seq = xproto.ConfigureWindow(b, xproto.Window(u32(4)), &xproto.ConfigureWindowValues{})
27+ case "xproto/ConfigureWindowSparse":
28+ var v xproto.ConfigureWindowValues
29+ if v.SetStackMode(xproto.StackModeAbove).SetWidth(80).SetX(-7) != &v {
30+ t.Fatal("setter chaining")
31+ }
32+ seq = xproto.ConfigureWindow(b, xproto.Window(u32(4)), &v)
33+ case "xproto/ConfigureWindowAll":
34+ var v xproto.ConfigureWindowValues
35+ v.SetStackMode(xproto.StackModeAbove).SetSibling(xproto.Window(u32(32))).SetBorderWidth(2).SetHeight(72).SetWidth(96).SetY(9).SetX(-3)
36+ seq = xproto.ConfigureWindow(b, xproto.Window(u32(4)), &v)
37+ case "xproto/CreateWindow":
38+ var v xproto.CreateWindowValues
39+ v.SetSaveUnder(false).SetOverrideRedirect(true).SetBackgroundPixel(0x123456)
40+ seq = xproto.CreateWindow(b, 0, xproto.Window(u32(4)), xproto.Window(u32(8)), 0, 0, 64, 48, 0, xproto.WindowClassInputOutput, 0, &v)
41+ case "xproto/ChangeWindowAttributes":
42+ var v xproto.ChangeWindowAttributesValues
43+ v.SetSaveUnder(true).SetOverrideRedirect(false)
44+ seq = xproto.ChangeWindowAttributes(b, xproto.Window(u32(4)), &v)
45+ case "render/CreatePicture":
46+ var ext xturbo.ExtTable
47+ ext.Set(xturbo.ExtRender, want[0], 0, 0)
48+ b.Ext = &ext
49+ var v render.CreatePictureValues
50+ v.SetClipyorigin(7).SetClipxorigin(-5).SetRepeat(render.RepeatNormal)
51+ seq = render.CreatePicture(b, render.Picture(u32(4)), xproto.Drawable(u32(8)), render.Pictformat(u32(12)), &v)
52+ }
53+ if seq != 1 || b.Err() != nil {
54+ t.Fatalf("seq=%d err=%v", seq, b.Err())
55+ }
56+ if !bytes.Equal(b.Bytes(), want) {
57+ t.Fatalf("got %x want %x", b.Bytes(), want)
58+ }
59+ })
60+ }
61+}
62+
63+func TestAllocValueRequests(t *testing.T) {
64+ b := xturbo.NewBuf(0)
65+ var ext xturbo.ExtTable
66+ ext.Set(xturbo.ExtRender, 139, 0, 0)
67+ b.Ext = &ext
68+ var v xproto.ConfigureWindowValues
69+ v.SetX(-1).SetY(-2).SetWidth(800).SetHeight(600).SetBorderWidth(1).SetSibling(2).SetStackMode(xproto.StackModeAbove)
70+ var create xproto.CreateWindowValues
71+ create.SetOverrideRedirect(true).SetSaveUnder(false)
72+ var change xproto.ChangeWindowAttributesValues
73+ change.SetOverrideRedirect(false).SetSaveUnder(true)
74+ var pic render.CreatePictureValues
75+ pic.SetRepeat(render.RepeatNormal).SetClipxorigin(-1)
76+ if n := testing.AllocsPerRun(1000, func() {
77+ b.Reset()
78+ xproto.ConfigureWindow(b, 1, &v)
79+ xproto.CreateWindow(b, 0, 1, 2, 0, 0, 80, 60, 0, xproto.WindowClassInputOutput, 0, &create)
80+ xproto.ChangeWindowAttributes(b, 1, &change)
81+ render.CreatePicture(b, 1, 1, 1, &pic)
82+ }); n != 0 {
83+ t.Fatal(n)
84+ }
85+ if b.Err() != nil {
86+ t.Fatal(b.Err())
87+ }
88+}
89+
90+func TestValueRequestFailures(t *testing.T) {
91+ b := xturbo.NewBuf(0)
92+ b.Fail(xturbo.ErrBadLength)
93+ if xproto.ConfigureWindow(b, 1, &xproto.ConfigureWindowValues{}) != 0 || b.Len() != 0 || b.Err() != xturbo.ErrBadLength {
94+ t.Fatal("sticky error")
95+ }
96+ for _, ext := range []*xturbo.ExtTable{nil, {}} {
97+ b := xturbo.NewBuf(0)
98+ b.Ext = ext
99+ if render.CreatePicture(b, 1, 1, 1, &render.CreatePictureValues{}) != 0 || b.Err() != xturbo.ErrExtMissing || b.Len() != 0 {
100+ t.Fatal("missing extension")
101+ }
102+ }
103+}
@@ -0,0 +1,103 @@
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/render"
11+ "bnema.dev/xturbo/xproto"
12+)
13+
14+func TestValueRequestGoldens(t *testing.T) {
15+ for _, name := range []string{"xproto/ConfigureWindow", "xproto/ConfigureWindowSparse", "xproto/ConfigureWindowAll", "xproto/CreateWindow", "xproto/ChangeWindowAttributes", "render/CreatePicture"} {
16+ t.Run(name, func(t *testing.T) {
17+ want, err := xtest.LoadHex("testdata/golden/" + name + ".req.hex")
18+ if err != nil {
19+ t.Fatal(err)
20+ }
21+ u32 := func(off int) uint32 { return binary.LittleEndian.Uint32(want[off:]) }
22+ b := xturbo.NewBuf(0)
23+ var seq xturbo.Seq
24+ switch name {
25+ case "xproto/ConfigureWindow":
26+ seq = xproto.ConfigureWindow(b, xproto.Window(u32(4)), &xproto.ConfigureWindowValues{})
27+ case "xproto/ConfigureWindowSparse":
28+ var v xproto.ConfigureWindowValues
29+ if v.SetStackMode(xproto.StackModeAbove).SetWidth(80).SetX(-7) != &v {
30+ t.Fatal("setter chaining")
31+ }
32+ seq = xproto.ConfigureWindow(b, xproto.Window(u32(4)), &v)
33+ case "xproto/ConfigureWindowAll":
34+ var v xproto.ConfigureWindowValues
35+ v.SetStackMode(xproto.StackModeAbove).SetSibling(xproto.Window(u32(32))).SetBorderWidth(2).SetHeight(72).SetWidth(96).SetY(9).SetX(-3)
36+ seq = xproto.ConfigureWindow(b, xproto.Window(u32(4)), &v)
37+ case "xproto/CreateWindow":
38+ var v xproto.CreateWindowValues
39+ v.SetSaveUnder(false).SetOverrideRedirect(true).SetBackgroundPixel(0x123456)
40+ seq = xproto.CreateWindow(b, 0, xproto.Window(u32(4)), xproto.Window(u32(8)), 0, 0, 64, 48, 0, xproto.WindowClassInputOutput, 0, &v)
41+ case "xproto/ChangeWindowAttributes":
42+ var v xproto.ChangeWindowAttributesValues
43+ v.SetSaveUnder(true).SetOverrideRedirect(false)
44+ seq = xproto.ChangeWindowAttributes(b, xproto.Window(u32(4)), &v)
45+ case "render/CreatePicture":
46+ var ext xturbo.ExtTable
47+ ext.Set(xturbo.ExtRender, want[0], 0, 0)
48+ b.Ext = &ext
49+ var v render.CreatePictureValues
50+ v.SetClipyorigin(7).SetClipxorigin(-5).SetRepeat(render.RepeatNormal)
51+ seq = render.CreatePicture(b, render.Picture(u32(4)), xproto.Drawable(u32(8)), render.Pictformat(u32(12)), &v)
52+ }
53+ if seq != 1 || b.Err() != nil {
54+ t.Fatalf("seq=%d err=%v", seq, b.Err())
55+ }
56+ if !bytes.Equal(b.Bytes(), want) {
57+ t.Fatalf("got %x want %x", b.Bytes(), want)
58+ }
59+ })
60+ }
61+}
62+
63+func TestAllocValueRequests(t *testing.T) {
64+ b := xturbo.NewBuf(0)
65+ var ext xturbo.ExtTable
66+ ext.Set(xturbo.ExtRender, 139, 0, 0)
67+ b.Ext = &ext
68+ var v xproto.ConfigureWindowValues
69+ v.SetX(-1).SetY(-2).SetWidth(800).SetHeight(600).SetBorderWidth(1).SetSibling(2).SetStackMode(xproto.StackModeAbove)
70+ var create xproto.CreateWindowValues
71+ create.SetOverrideRedirect(true).SetSaveUnder(false)
72+ var change xproto.ChangeWindowAttributesValues
73+ change.SetOverrideRedirect(false).SetSaveUnder(true)
74+ var pic render.CreatePictureValues
75+ pic.SetRepeat(render.RepeatNormal).SetClipxorigin(-1)
76+ if n := testing.AllocsPerRun(1000, func() {
77+ b.Reset()
78+ xproto.ConfigureWindow(b, 1, &v)
79+ xproto.CreateWindow(b, 0, 1, 2, 0, 0, 80, 60, 0, xproto.WindowClassInputOutput, 0, &create)
80+ xproto.ChangeWindowAttributes(b, 1, &change)
81+ render.CreatePicture(b, 1, 1, 1, &pic)
82+ }); n != 0 {
83+ t.Fatal(n)
84+ }
85+ if b.Err() != nil {
86+ t.Fatal(b.Err())
87+ }
88+}
89+
90+func TestValueRequestFailures(t *testing.T) {
91+ b := xturbo.NewBuf(0)
92+ b.Fail(xturbo.ErrBadLength)
93+ if xproto.ConfigureWindow(b, 1, &xproto.ConfigureWindowValues{}) != 0 || b.Len() != 0 || b.Err() != xturbo.ErrBadLength {
94+ t.Fatal("sticky error")
95+ }
96+ for _, ext := range []*xturbo.ExtTable{nil, {}} {
97+ b := xturbo.NewBuf(0)
98+ b.Ext = ext
99+ if render.CreatePicture(b, 1, 1, 1, &render.CreatePictureValues{}) != 0 || b.Err() != xturbo.ErrExtMissing || b.Len() != 0 {
100+ t.Fatal("missing extension")
101+ }
102+ }
103+}
M xproto/requests_generated.go +1023 -0
@@ -2,8 +2,365 @@
22 package xproto
33
44 import "encoding/binary"
5+import "math/bits"
56 import "bnema.dev/xturbo"
67
8+type CreateWindowValues struct {
9+ Mask Cw
10+ BackgroundPixmap Pixmap
11+ BackgroundPixel uint32
12+ BorderPixmap Pixmap
13+ BorderPixel uint32
14+ BitGravity Gravity
15+ WinGravity Gravity
16+ BackingStore BackingStore
17+ BackingPlanes uint32
18+ BackingPixel uint32
19+ OverrideRedirect bool
20+ SaveUnder bool
21+ EventMask EventMask
22+ DoNotPropogateMask EventMask
23+ Colormap Colormap
24+ Cursor Cursor
25+}
26+
27+func (v *CreateWindowValues) SetBackgroundPixmap(x Pixmap) *CreateWindowValues {
28+ v.Mask |= CwBackPixmap
29+ v.BackgroundPixmap = x
30+ return v
31+}
32+func (v *CreateWindowValues) SetBackgroundPixel(x uint32) *CreateWindowValues {
33+ v.Mask |= CwBackPixel
34+ v.BackgroundPixel = x
35+ return v
36+}
37+func (v *CreateWindowValues) SetBorderPixmap(x Pixmap) *CreateWindowValues {
38+ v.Mask |= CwBorderPixmap
39+ v.BorderPixmap = x
40+ return v
41+}
42+func (v *CreateWindowValues) SetBorderPixel(x uint32) *CreateWindowValues {
43+ v.Mask |= CwBorderPixel
44+ v.BorderPixel = x
45+ return v
46+}
47+func (v *CreateWindowValues) SetBitGravity(x Gravity) *CreateWindowValues {
48+ v.Mask |= CwBitGravity
49+ v.BitGravity = x
50+ return v
51+}
52+func (v *CreateWindowValues) SetWinGravity(x Gravity) *CreateWindowValues {
53+ v.Mask |= CwWinGravity
54+ v.WinGravity = x
55+ return v
56+}
57+func (v *CreateWindowValues) SetBackingStore(x BackingStore) *CreateWindowValues {
58+ v.Mask |= CwBackingStore
59+ v.BackingStore = x
60+ return v
61+}
62+func (v *CreateWindowValues) SetBackingPlanes(x uint32) *CreateWindowValues {
63+ v.Mask |= CwBackingPlanes
64+ v.BackingPlanes = x
65+ return v
66+}
67+func (v *CreateWindowValues) SetBackingPixel(x uint32) *CreateWindowValues {
68+ v.Mask |= CwBackingPixel
69+ v.BackingPixel = x
70+ return v
71+}
72+func (v *CreateWindowValues) SetOverrideRedirect(x bool) *CreateWindowValues {
73+ v.Mask |= CwOverrideRedirect
74+ v.OverrideRedirect = x
75+ return v
76+}
77+func (v *CreateWindowValues) SetSaveUnder(x bool) *CreateWindowValues {
78+ v.Mask |= CwSaveUnder
79+ v.SaveUnder = x
80+ return v
81+}
82+func (v *CreateWindowValues) SetEventMask(x EventMask) *CreateWindowValues {
83+ v.Mask |= CwEventMask
84+ v.EventMask = x
85+ return v
86+}
87+func (v *CreateWindowValues) SetDoNotPropogateMask(x EventMask) *CreateWindowValues {
88+ v.Mask |= CwDontPropagate
89+ v.DoNotPropogateMask = x
90+ return v
91+}
92+func (v *CreateWindowValues) SetColormap(x Colormap) *CreateWindowValues {
93+ v.Mask |= CwColormap
94+ v.Colormap = x
95+ return v
96+}
97+func (v *CreateWindowValues) SetCursor(x Cursor) *CreateWindowValues {
98+ v.Mask |= CwCursor
99+ v.Cursor = x
100+ return v
101+}
102+func CreateWindow(b *xturbo.Buf, depth uint8, wid Window, parent Window, x int16, y int16, width uint16, height uint16, borderWidth uint16, class WindowClass, visual Visualid, v *CreateWindowValues) xturbo.Seq {
103+ p, seq := b.Request(1, uint8(int(depth)), 28+4*bits.OnesCount32(uint32(v.Mask)))
104+ if p == nil {
105+ return 0
106+ }
107+ binary.LittleEndian.PutUint32(p[0:], uint32(wid))
108+ binary.LittleEndian.PutUint32(p[4:], uint32(parent))
109+ binary.LittleEndian.PutUint16(p[8:], uint16(x))
110+ binary.LittleEndian.PutUint16(p[10:], uint16(y))
111+ binary.LittleEndian.PutUint16(p[12:], uint16(width))
112+ binary.LittleEndian.PutUint16(p[14:], uint16(height))
113+ binary.LittleEndian.PutUint16(p[16:], uint16(borderWidth))
114+ binary.LittleEndian.PutUint16(p[18:], uint16(class))
115+ binary.LittleEndian.PutUint32(p[20:], uint32(visual))
116+ binary.LittleEndian.PutUint32(p[24:], uint32(v.Mask))
117+ off := 28
118+ if v.Mask&CwBackPixmap != 0 {
119+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BackgroundPixmap))
120+ off += 4
121+ }
122+ if v.Mask&CwBackPixel != 0 {
123+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BackgroundPixel))
124+ off += 4
125+ }
126+ if v.Mask&CwBorderPixmap != 0 {
127+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BorderPixmap))
128+ off += 4
129+ }
130+ if v.Mask&CwBorderPixel != 0 {
131+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BorderPixel))
132+ off += 4
133+ }
134+ if v.Mask&CwBitGravity != 0 {
135+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BitGravity))
136+ off += 4
137+ }
138+ if v.Mask&CwWinGravity != 0 {
139+ binary.LittleEndian.PutUint32(p[off:], uint32(v.WinGravity))
140+ off += 4
141+ }
142+ if v.Mask&CwBackingStore != 0 {
143+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BackingStore))
144+ off += 4
145+ }
146+ if v.Mask&CwBackingPlanes != 0 {
147+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BackingPlanes))
148+ off += 4
149+ }
150+ if v.Mask&CwBackingPixel != 0 {
151+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BackingPixel))
152+ off += 4
153+ }
154+ if v.Mask&CwOverrideRedirect != 0 {
155+ if v.OverrideRedirect {
156+ binary.LittleEndian.PutUint32(p[off:], 1)
157+ } else {
158+ binary.LittleEndian.PutUint32(p[off:], 0)
159+ }
160+ off += 4
161+ }
162+ if v.Mask&CwSaveUnder != 0 {
163+ if v.SaveUnder {
164+ binary.LittleEndian.PutUint32(p[off:], 1)
165+ } else {
166+ binary.LittleEndian.PutUint32(p[off:], 0)
167+ }
168+ off += 4
169+ }
170+ if v.Mask&CwEventMask != 0 {
171+ binary.LittleEndian.PutUint32(p[off:], uint32(v.EventMask))
172+ off += 4
173+ }
174+ if v.Mask&CwDontPropagate != 0 {
175+ binary.LittleEndian.PutUint32(p[off:], uint32(v.DoNotPropogateMask))
176+ off += 4
177+ }
178+ if v.Mask&CwColormap != 0 {
179+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Colormap))
180+ off += 4
181+ }
182+ if v.Mask&CwCursor != 0 {
183+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Cursor))
184+ off += 4
185+ }
186+ _ = off
187+ return seq
188+}
189+
190+type ChangeWindowAttributesValues struct {
191+ Mask Cw
192+ BackgroundPixmap Pixmap
193+ BackgroundPixel uint32
194+ BorderPixmap Pixmap
195+ BorderPixel uint32
196+ BitGravity Gravity
197+ WinGravity Gravity
198+ BackingStore BackingStore
199+ BackingPlanes uint32
200+ BackingPixel uint32
201+ OverrideRedirect bool
202+ SaveUnder bool
203+ EventMask EventMask
204+ DoNotPropogateMask EventMask
205+ Colormap Colormap
206+ Cursor Cursor
207+}
208+
209+func (v *ChangeWindowAttributesValues) SetBackgroundPixmap(x Pixmap) *ChangeWindowAttributesValues {
210+ v.Mask |= CwBackPixmap
211+ v.BackgroundPixmap = x
212+ return v
213+}
214+func (v *ChangeWindowAttributesValues) SetBackgroundPixel(x uint32) *ChangeWindowAttributesValues {
215+ v.Mask |= CwBackPixel
216+ v.BackgroundPixel = x
217+ return v
218+}
219+func (v *ChangeWindowAttributesValues) SetBorderPixmap(x Pixmap) *ChangeWindowAttributesValues {
220+ v.Mask |= CwBorderPixmap
221+ v.BorderPixmap = x
222+ return v
223+}
224+func (v *ChangeWindowAttributesValues) SetBorderPixel(x uint32) *ChangeWindowAttributesValues {
225+ v.Mask |= CwBorderPixel
226+ v.BorderPixel = x
227+ return v
228+}
229+func (v *ChangeWindowAttributesValues) SetBitGravity(x Gravity) *ChangeWindowAttributesValues {
230+ v.Mask |= CwBitGravity
231+ v.BitGravity = x
232+ return v
233+}
234+func (v *ChangeWindowAttributesValues) SetWinGravity(x Gravity) *ChangeWindowAttributesValues {
235+ v.Mask |= CwWinGravity
236+ v.WinGravity = x
237+ return v
238+}
239+func (v *ChangeWindowAttributesValues) SetBackingStore(x BackingStore) *ChangeWindowAttributesValues {
240+ v.Mask |= CwBackingStore
241+ v.BackingStore = x
242+ return v
243+}
244+func (v *ChangeWindowAttributesValues) SetBackingPlanes(x uint32) *ChangeWindowAttributesValues {
245+ v.Mask |= CwBackingPlanes
246+ v.BackingPlanes = x
247+ return v
248+}
249+func (v *ChangeWindowAttributesValues) SetBackingPixel(x uint32) *ChangeWindowAttributesValues {
250+ v.Mask |= CwBackingPixel
251+ v.BackingPixel = x
252+ return v
253+}
254+func (v *ChangeWindowAttributesValues) SetOverrideRedirect(x bool) *ChangeWindowAttributesValues {
255+ v.Mask |= CwOverrideRedirect
256+ v.OverrideRedirect = x
257+ return v
258+}
259+func (v *ChangeWindowAttributesValues) SetSaveUnder(x bool) *ChangeWindowAttributesValues {
260+ v.Mask |= CwSaveUnder
261+ v.SaveUnder = x
262+ return v
263+}
264+func (v *ChangeWindowAttributesValues) SetEventMask(x EventMask) *ChangeWindowAttributesValues {
265+ v.Mask |= CwEventMask
266+ v.EventMask = x
267+ return v
268+}
269+func (v *ChangeWindowAttributesValues) SetDoNotPropogateMask(x EventMask) *ChangeWindowAttributesValues {
270+ v.Mask |= CwDontPropagate
271+ v.DoNotPropogateMask = x
272+ return v
273+}
274+func (v *ChangeWindowAttributesValues) SetColormap(x Colormap) *ChangeWindowAttributesValues {
275+ v.Mask |= CwColormap
276+ v.Colormap = x
277+ return v
278+}
279+func (v *ChangeWindowAttributesValues) SetCursor(x Cursor) *ChangeWindowAttributesValues {
280+ v.Mask |= CwCursor
281+ v.Cursor = x
282+ return v
283+}
284+func ChangeWindowAttributes(b *xturbo.Buf, window Window, v *ChangeWindowAttributesValues) xturbo.Seq {
285+ p, seq := b.Request(2, 0, 8+4*bits.OnesCount32(uint32(v.Mask)))
286+ if p == nil {
287+ return 0
288+ }
289+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
290+ binary.LittleEndian.PutUint32(p[4:], uint32(v.Mask))
291+ off := 8
292+ if v.Mask&CwBackPixmap != 0 {
293+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BackgroundPixmap))
294+ off += 4
295+ }
296+ if v.Mask&CwBackPixel != 0 {
297+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BackgroundPixel))
298+ off += 4
299+ }
300+ if v.Mask&CwBorderPixmap != 0 {
301+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BorderPixmap))
302+ off += 4
303+ }
304+ if v.Mask&CwBorderPixel != 0 {
305+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BorderPixel))
306+ off += 4
307+ }
308+ if v.Mask&CwBitGravity != 0 {
309+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BitGravity))
310+ off += 4
311+ }
312+ if v.Mask&CwWinGravity != 0 {
313+ binary.LittleEndian.PutUint32(p[off:], uint32(v.WinGravity))
314+ off += 4
315+ }
316+ if v.Mask&CwBackingStore != 0 {
317+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BackingStore))
318+ off += 4
319+ }
320+ if v.Mask&CwBackingPlanes != 0 {
321+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BackingPlanes))
322+ off += 4
323+ }
324+ if v.Mask&CwBackingPixel != 0 {
325+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BackingPixel))
326+ off += 4
327+ }
328+ if v.Mask&CwOverrideRedirect != 0 {
329+ if v.OverrideRedirect {
330+ binary.LittleEndian.PutUint32(p[off:], 1)
331+ } else {
332+ binary.LittleEndian.PutUint32(p[off:], 0)
333+ }
334+ off += 4
335+ }
336+ if v.Mask&CwSaveUnder != 0 {
337+ if v.SaveUnder {
338+ binary.LittleEndian.PutUint32(p[off:], 1)
339+ } else {
340+ binary.LittleEndian.PutUint32(p[off:], 0)
341+ }
342+ off += 4
343+ }
344+ if v.Mask&CwEventMask != 0 {
345+ binary.LittleEndian.PutUint32(p[off:], uint32(v.EventMask))
346+ off += 4
347+ }
348+ if v.Mask&CwDontPropagate != 0 {
349+ binary.LittleEndian.PutUint32(p[off:], uint32(v.DoNotPropogateMask))
350+ off += 4
351+ }
352+ if v.Mask&CwColormap != 0 {
353+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Colormap))
354+ off += 4
355+ }
356+ if v.Mask&CwCursor != 0 {
357+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Cursor))
358+ off += 4
359+ }
360+ _ = off
361+ return seq
362+}
363+
7364 func GetWindowAttributes(b *xturbo.Buf, window Window) xturbo.Seq {
8365 p, seq := b.Request(3, 0, 4)
9366 if p == nil {
@@ -88,6 +445,92 @@ func UnmapSubwindows(b *xturbo.Buf, window Window) xturbo.Seq {
88445 return seq
89446 }
90447
448+type ConfigureWindowValues struct {
449+ Mask ConfigWindow
450+ X int32
451+ Y int32
452+ Width uint32
453+ Height uint32
454+ BorderWidth uint32
455+ Sibling Window
456+ StackMode StackMode
457+}
458+
459+func (v *ConfigureWindowValues) SetX(x int32) *ConfigureWindowValues {
460+ v.Mask |= ConfigWindowX
461+ v.X = x
462+ return v
463+}
464+func (v *ConfigureWindowValues) SetY(x int32) *ConfigureWindowValues {
465+ v.Mask |= ConfigWindowY
466+ v.Y = x
467+ return v
468+}
469+func (v *ConfigureWindowValues) SetWidth(x uint32) *ConfigureWindowValues {
470+ v.Mask |= ConfigWindowWidth
471+ v.Width = x
472+ return v
473+}
474+func (v *ConfigureWindowValues) SetHeight(x uint32) *ConfigureWindowValues {
475+ v.Mask |= ConfigWindowHeight
476+ v.Height = x
477+ return v
478+}
479+func (v *ConfigureWindowValues) SetBorderWidth(x uint32) *ConfigureWindowValues {
480+ v.Mask |= ConfigWindowBorderWidth
481+ v.BorderWidth = x
482+ return v
483+}
484+func (v *ConfigureWindowValues) SetSibling(x Window) *ConfigureWindowValues {
485+ v.Mask |= ConfigWindowSibling
486+ v.Sibling = x
487+ return v
488+}
489+func (v *ConfigureWindowValues) SetStackMode(x StackMode) *ConfigureWindowValues {
490+ v.Mask |= ConfigWindowStackMode
491+ v.StackMode = x
492+ return v
493+}
494+func ConfigureWindow(b *xturbo.Buf, window Window, v *ConfigureWindowValues) xturbo.Seq {
495+ p, seq := b.Request(12, 0, 8+4*bits.OnesCount32(uint32(v.Mask)))
496+ if p == nil {
497+ return 0
498+ }
499+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
500+ binary.LittleEndian.PutUint16(p[4:], uint16(v.Mask))
501+ off := 8
502+ if v.Mask&ConfigWindowX != 0 {
503+ binary.LittleEndian.PutUint32(p[off:], uint32(v.X))
504+ off += 4
505+ }
506+ if v.Mask&ConfigWindowY != 0 {
507+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Y))
508+ off += 4
509+ }
510+ if v.Mask&ConfigWindowWidth != 0 {
511+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Width))
512+ off += 4
513+ }
514+ if v.Mask&ConfigWindowHeight != 0 {
515+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Height))
516+ off += 4
517+ }
518+ if v.Mask&ConfigWindowBorderWidth != 0 {
519+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BorderWidth))
520+ off += 4
521+ }
522+ if v.Mask&ConfigWindowSibling != 0 {
523+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Sibling))
524+ off += 4
525+ }
526+ if v.Mask&ConfigWindowStackMode != 0 {
527+ binary.LittleEndian.PutUint32(p[off:], uint32(v.StackMode))
528+ off += 4
529+ }
530+ _ = off
531+ return seq
532+}
533+
91534 func CirculateWindow(b *xturbo.Buf, direction Circulate, window Window) xturbo.Seq {
92535 p, seq := b.Request(13, uint8(int(direction)), 4)
93536 if p == nil {
@@ -673,6 +1116,491 @@ func FreePixmap(b *xturbo.Buf, pixmap Pixmap) xturbo.Seq {
6731116 return seq
6741117 }
6751118
1119+type CreateGCValues struct {
1120+ Mask Gc
1121+ Function Gx
1122+ PlaneMask uint32
1123+ Foreground uint32
1124+ Background uint32
1125+ LineWidth uint32
1126+ LineStyle LineStyle
1127+ CapStyle CapStyle
1128+ JoinStyle JoinStyle
1129+ FillStyle FillStyle
1130+ FillRule FillRule
1131+ Tile Pixmap
1132+ Stipple Pixmap
1133+ TileStippleXOrigin int32
1134+ TileStippleYOrigin int32
1135+ Font Font
1136+ SubwindowMode SubwindowMode
1137+ GraphicsExposures bool
1138+ ClipXOrigin int32
1139+ ClipYOrigin int32
1140+ ClipMask Pixmap
1141+ DashOffset uint32
1142+ Dashes uint32
1143+ ArcMode ArcMode
1144+}
1145+
1146+func (v *CreateGCValues) SetFunction(x Gx) *CreateGCValues {
1147+ v.Mask |= GcFunction
1148+ v.Function = x
1149+ return v
1150+}
1151+func (v *CreateGCValues) SetPlaneMask(x uint32) *CreateGCValues {
1152+ v.Mask |= GcPlaneMask
1153+ v.PlaneMask = x
1154+ return v
1155+}
1156+func (v *CreateGCValues) SetForeground(x uint32) *CreateGCValues {
1157+ v.Mask |= GcForeground
1158+ v.Foreground = x
1159+ return v
1160+}
1161+func (v *CreateGCValues) SetBackground(x uint32) *CreateGCValues {
1162+ v.Mask |= GcBackground
1163+ v.Background = x
1164+ return v
1165+}
1166+func (v *CreateGCValues) SetLineWidth(x uint32) *CreateGCValues {
1167+ v.Mask |= GcLineWidth
1168+ v.LineWidth = x
1169+ return v
1170+}
1171+func (v *CreateGCValues) SetLineStyle(x LineStyle) *CreateGCValues {
1172+ v.Mask |= GcLineStyle
1173+ v.LineStyle = x
1174+ return v
1175+}
1176+func (v *CreateGCValues) SetCapStyle(x CapStyle) *CreateGCValues {
1177+ v.Mask |= GcCapStyle
1178+ v.CapStyle = x
1179+ return v
1180+}
1181+func (v *CreateGCValues) SetJoinStyle(x JoinStyle) *CreateGCValues {
1182+ v.Mask |= GcJoinStyle
1183+ v.JoinStyle = x
1184+ return v
1185+}
1186+func (v *CreateGCValues) SetFillStyle(x FillStyle) *CreateGCValues {
1187+ v.Mask |= GcFillStyle
1188+ v.FillStyle = x
1189+ return v
1190+}
1191+func (v *CreateGCValues) SetFillRule(x FillRule) *CreateGCValues {
1192+ v.Mask |= GcFillRule
1193+ v.FillRule = x
1194+ return v
1195+}
1196+func (v *CreateGCValues) SetTile(x Pixmap) *CreateGCValues { v.Mask |= GcTile; v.Tile = x; return v }
1197+func (v *CreateGCValues) SetStipple(x Pixmap) *CreateGCValues {
1198+ v.Mask |= GcStipple
1199+ v.Stipple = x
1200+ return v
1201+}
1202+func (v *CreateGCValues) SetTileStippleXOrigin(x int32) *CreateGCValues {
1203+ v.Mask |= GcTileStippleOriginX
1204+ v.TileStippleXOrigin = x
1205+ return v
1206+}
1207+func (v *CreateGCValues) SetTileStippleYOrigin(x int32) *CreateGCValues {
1208+ v.Mask |= GcTileStippleOriginY
1209+ v.TileStippleYOrigin = x
1210+ return v
1211+}
1212+func (v *CreateGCValues) SetFont(x Font) *CreateGCValues { v.Mask |= GcFont; v.Font = x; return v }
1213+func (v *CreateGCValues) SetSubwindowMode(x SubwindowMode) *CreateGCValues {
1214+ v.Mask |= GcSubwindowMode
1215+ v.SubwindowMode = x
1216+ return v
1217+}
1218+func (v *CreateGCValues) SetGraphicsExposures(x bool) *CreateGCValues {
1219+ v.Mask |= GcGraphicsExposures
1220+ v.GraphicsExposures = x
1221+ return v
1222+}
1223+func (v *CreateGCValues) SetClipXOrigin(x int32) *CreateGCValues {
1224+ v.Mask |= GcClipOriginX
1225+ v.ClipXOrigin = x
1226+ return v
1227+}
1228+func (v *CreateGCValues) SetClipYOrigin(x int32) *CreateGCValues {
1229+ v.Mask |= GcClipOriginY
1230+ v.ClipYOrigin = x
1231+ return v
1232+}
1233+func (v *CreateGCValues) SetClipMask(x Pixmap) *CreateGCValues {
1234+ v.Mask |= GcClipMask
1235+ v.ClipMask = x
1236+ return v
1237+}
1238+func (v *CreateGCValues) SetDashOffset(x uint32) *CreateGCValues {
1239+ v.Mask |= GcDashOffset
1240+ v.DashOffset = x
1241+ return v
1242+}
1243+func (v *CreateGCValues) SetDashes(x uint32) *CreateGCValues {
1244+ v.Mask |= GcDashList
1245+ v.Dashes = x
1246+ return v
1247+}
1248+func (v *CreateGCValues) SetArcMode(x ArcMode) *CreateGCValues {
1249+ v.Mask |= GcArcMode
1250+ v.ArcMode = x
1251+ return v
1252+}
1253+func CreateGC(b *xturbo.Buf, cid Gcontext, drawable Drawable, v *CreateGCValues) xturbo.Seq {
1254+ p, seq := b.Request(55, 0, 12+4*bits.OnesCount32(uint32(v.Mask)))
1255+ if p == nil {
1256+ return 0
1257+ }
1258+ binary.LittleEndian.PutUint32(p[0:], uint32(cid))
1259+ binary.LittleEndian.PutUint32(p[4:], uint32(drawable))
1260+ binary.LittleEndian.PutUint32(p[8:], uint32(v.Mask))
1261+ off := 12
1262+ if v.Mask&GcFunction != 0 {
1263+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Function))
1264+ off += 4
1265+ }
1266+ if v.Mask&GcPlaneMask != 0 {
1267+ binary.LittleEndian.PutUint32(p[off:], uint32(v.PlaneMask))
1268+ off += 4
1269+ }
1270+ if v.Mask&GcForeground != 0 {
1271+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Foreground))
1272+ off += 4
1273+ }
1274+ if v.Mask&GcBackground != 0 {
1275+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Background))
1276+ off += 4
1277+ }
1278+ if v.Mask&GcLineWidth != 0 {
1279+ binary.LittleEndian.PutUint32(p[off:], uint32(v.LineWidth))
1280+ off += 4
1281+ }
1282+ if v.Mask&GcLineStyle != 0 {
1283+ binary.LittleEndian.PutUint32(p[off:], uint32(v.LineStyle))
1284+ off += 4
1285+ }
1286+ if v.Mask&GcCapStyle != 0 {
1287+ binary.LittleEndian.PutUint32(p[off:], uint32(v.CapStyle))
1288+ off += 4
1289+ }
1290+ if v.Mask&GcJoinStyle != 0 {
1291+ binary.LittleEndian.PutUint32(p[off:], uint32(v.JoinStyle))
1292+ off += 4
1293+ }
1294+ if v.Mask&GcFillStyle != 0 {
1295+ binary.LittleEndian.PutUint32(p[off:], uint32(v.FillStyle))
1296+ off += 4
1297+ }
1298+ if v.Mask&GcFillRule != 0 {
1299+ binary.LittleEndian.PutUint32(p[off:], uint32(v.FillRule))
1300+ off += 4
1301+ }
1302+ if v.Mask&GcTile != 0 {
1303+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Tile))
1304+ off += 4
1305+ }
1306+ if v.Mask&GcStipple != 0 {
1307+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Stipple))
1308+ off += 4
1309+ }
1310+ if v.Mask&GcTileStippleOriginX != 0 {
1311+ binary.LittleEndian.PutUint32(p[off:], uint32(v.TileStippleXOrigin))
1312+ off += 4
1313+ }
1314+ if v.Mask&GcTileStippleOriginY != 0 {
1315+ binary.LittleEndian.PutUint32(p[off:], uint32(v.TileStippleYOrigin))
1316+ off += 4
1317+ }
1318+ if v.Mask&GcFont != 0 {
1319+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Font))
1320+ off += 4
1321+ }
1322+ if v.Mask&GcSubwindowMode != 0 {
1323+ binary.LittleEndian.PutUint32(p[off:], uint32(v.SubwindowMode))
1324+ off += 4
1325+ }
1326+ if v.Mask&GcGraphicsExposures != 0 {
1327+ if v.GraphicsExposures {
1328+ binary.LittleEndian.PutUint32(p[off:], 1)
1329+ } else {
1330+ binary.LittleEndian.PutUint32(p[off:], 0)
1331+ }
1332+ off += 4
1333+ }
1334+ if v.Mask&GcClipOriginX != 0 {
1335+ binary.LittleEndian.PutUint32(p[off:], uint32(v.ClipXOrigin))
1336+ off += 4
1337+ }
1338+ if v.Mask&GcClipOriginY != 0 {
1339+ binary.LittleEndian.PutUint32(p[off:], uint32(v.ClipYOrigin))
1340+ off += 4
1341+ }
1342+ if v.Mask&GcClipMask != 0 {
1343+ binary.LittleEndian.PutUint32(p[off:], uint32(v.ClipMask))
1344+ off += 4
1345+ }
1346+ if v.Mask&GcDashOffset != 0 {
1347+ binary.LittleEndian.PutUint32(p[off:], uint32(v.DashOffset))
1348+ off += 4
1349+ }
1350+ if v.Mask&GcDashList != 0 {
1351+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Dashes))
1352+ off += 4
1353+ }
1354+ if v.Mask&GcArcMode != 0 {
1355+ binary.LittleEndian.PutUint32(p[off:], uint32(v.ArcMode))
1356+ off += 4
1357+ }
1358+ _ = off
1359+ return seq
1360+}
1361+
1362+type ChangeGCValues struct {
1363+ Mask Gc
1364+ Function Gx
1365+ PlaneMask uint32
1366+ Foreground uint32
1367+ Background uint32
1368+ LineWidth uint32
1369+ LineStyle LineStyle
1370+ CapStyle CapStyle
1371+ JoinStyle JoinStyle
1372+ FillStyle FillStyle
1373+ FillRule FillRule
1374+ Tile Pixmap
1375+ Stipple Pixmap
1376+ TileStippleXOrigin int32
1377+ TileStippleYOrigin int32
1378+ Font Font
1379+ SubwindowMode SubwindowMode
1380+ GraphicsExposures bool
1381+ ClipXOrigin int32
1382+ ClipYOrigin int32
1383+ ClipMask Pixmap
1384+ DashOffset uint32
1385+ Dashes uint32
1386+ ArcMode ArcMode
1387+}
1388+
1389+func (v *ChangeGCValues) SetFunction(x Gx) *ChangeGCValues {
1390+ v.Mask |= GcFunction
1391+ v.Function = x
1392+ return v
1393+}
1394+func (v *ChangeGCValues) SetPlaneMask(x uint32) *ChangeGCValues {
1395+ v.Mask |= GcPlaneMask
1396+ v.PlaneMask = x
1397+ return v
1398+}
1399+func (v *ChangeGCValues) SetForeground(x uint32) *ChangeGCValues {
1400+ v.Mask |= GcForeground
1401+ v.Foreground = x
1402+ return v
1403+}
1404+func (v *ChangeGCValues) SetBackground(x uint32) *ChangeGCValues {
1405+ v.Mask |= GcBackground
1406+ v.Background = x
1407+ return v
1408+}
1409+func (v *ChangeGCValues) SetLineWidth(x uint32) *ChangeGCValues {
1410+ v.Mask |= GcLineWidth
1411+ v.LineWidth = x
1412+ return v
1413+}
1414+func (v *ChangeGCValues) SetLineStyle(x LineStyle) *ChangeGCValues {
1415+ v.Mask |= GcLineStyle
1416+ v.LineStyle = x
1417+ return v
1418+}
1419+func (v *ChangeGCValues) SetCapStyle(x CapStyle) *ChangeGCValues {
1420+ v.Mask |= GcCapStyle
1421+ v.CapStyle = x
1422+ return v
1423+}
1424+func (v *ChangeGCValues) SetJoinStyle(x JoinStyle) *ChangeGCValues {
1425+ v.Mask |= GcJoinStyle
1426+ v.JoinStyle = x
1427+ return v
1428+}
1429+func (v *ChangeGCValues) SetFillStyle(x FillStyle) *ChangeGCValues {
1430+ v.Mask |= GcFillStyle
1431+ v.FillStyle = x
1432+ return v
1433+}
1434+func (v *ChangeGCValues) SetFillRule(x FillRule) *ChangeGCValues {
1435+ v.Mask |= GcFillRule
1436+ v.FillRule = x
1437+ return v
1438+}
1439+func (v *ChangeGCValues) SetTile(x Pixmap) *ChangeGCValues { v.Mask |= GcTile; v.Tile = x; return v }
1440+func (v *ChangeGCValues) SetStipple(x Pixmap) *ChangeGCValues {
1441+ v.Mask |= GcStipple
1442+ v.Stipple = x
1443+ return v
1444+}
1445+func (v *ChangeGCValues) SetTileStippleXOrigin(x int32) *ChangeGCValues {
1446+ v.Mask |= GcTileStippleOriginX
1447+ v.TileStippleXOrigin = x
1448+ return v
1449+}
1450+func (v *ChangeGCValues) SetTileStippleYOrigin(x int32) *ChangeGCValues {
1451+ v.Mask |= GcTileStippleOriginY
1452+ v.TileStippleYOrigin = x
1453+ return v
1454+}
1455+func (v *ChangeGCValues) SetFont(x Font) *ChangeGCValues { v.Mask |= GcFont; v.Font = x; return v }
1456+func (v *ChangeGCValues) SetSubwindowMode(x SubwindowMode) *ChangeGCValues {
1457+ v.Mask |= GcSubwindowMode
1458+ v.SubwindowMode = x
1459+ return v
1460+}
1461+func (v *ChangeGCValues) SetGraphicsExposures(x bool) *ChangeGCValues {
1462+ v.Mask |= GcGraphicsExposures
1463+ v.GraphicsExposures = x
1464+ return v
1465+}
1466+func (v *ChangeGCValues) SetClipXOrigin(x int32) *ChangeGCValues {
1467+ v.Mask |= GcClipOriginX
1468+ v.ClipXOrigin = x
1469+ return v
1470+}
1471+func (v *ChangeGCValues) SetClipYOrigin(x int32) *ChangeGCValues {
1472+ v.Mask |= GcClipOriginY
1473+ v.ClipYOrigin = x
1474+ return v
1475+}
1476+func (v *ChangeGCValues) SetClipMask(x Pixmap) *ChangeGCValues {
1477+ v.Mask |= GcClipMask
1478+ v.ClipMask = x
1479+ return v
1480+}
1481+func (v *ChangeGCValues) SetDashOffset(x uint32) *ChangeGCValues {
1482+ v.Mask |= GcDashOffset
1483+ v.DashOffset = x
1484+ return v
1485+}
1486+func (v *ChangeGCValues) SetDashes(x uint32) *ChangeGCValues {
1487+ v.Mask |= GcDashList
1488+ v.Dashes = x
1489+ return v
1490+}
1491+func (v *ChangeGCValues) SetArcMode(x ArcMode) *ChangeGCValues {
1492+ v.Mask |= GcArcMode
1493+ v.ArcMode = x
1494+ return v
1495+}
1496+func ChangeGC(b *xturbo.Buf, gc Gcontext, v *ChangeGCValues) xturbo.Seq {
1497+ p, seq := b.Request(56, 0, 8+4*bits.OnesCount32(uint32(v.Mask)))
1498+ if p == nil {
1499+ return 0
1500+ }
1501+ binary.LittleEndian.PutUint32(p[0:], uint32(gc))
1502+ binary.LittleEndian.PutUint32(p[4:], uint32(v.Mask))
1503+ off := 8
1504+ if v.Mask&GcFunction != 0 {
1505+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Function))
1506+ off += 4
1507+ }
1508+ if v.Mask&GcPlaneMask != 0 {
1509+ binary.LittleEndian.PutUint32(p[off:], uint32(v.PlaneMask))
1510+ off += 4
1511+ }
1512+ if v.Mask&GcForeground != 0 {
1513+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Foreground))
1514+ off += 4
1515+ }
1516+ if v.Mask&GcBackground != 0 {
1517+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Background))
1518+ off += 4
1519+ }
1520+ if v.Mask&GcLineWidth != 0 {
1521+ binary.LittleEndian.PutUint32(p[off:], uint32(v.LineWidth))
1522+ off += 4
1523+ }
1524+ if v.Mask&GcLineStyle != 0 {
1525+ binary.LittleEndian.PutUint32(p[off:], uint32(v.LineStyle))
1526+ off += 4
1527+ }
1528+ if v.Mask&GcCapStyle != 0 {
1529+ binary.LittleEndian.PutUint32(p[off:], uint32(v.CapStyle))
1530+ off += 4
1531+ }
1532+ if v.Mask&GcJoinStyle != 0 {
1533+ binary.LittleEndian.PutUint32(p[off:], uint32(v.JoinStyle))
1534+ off += 4
1535+ }
1536+ if v.Mask&GcFillStyle != 0 {
1537+ binary.LittleEndian.PutUint32(p[off:], uint32(v.FillStyle))
1538+ off += 4
1539+ }
1540+ if v.Mask&GcFillRule != 0 {
1541+ binary.LittleEndian.PutUint32(p[off:], uint32(v.FillRule))
1542+ off += 4
1543+ }
1544+ if v.Mask&GcTile != 0 {
1545+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Tile))
1546+ off += 4
1547+ }
1548+ if v.Mask&GcStipple != 0 {
1549+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Stipple))
1550+ off += 4
1551+ }
1552+ if v.Mask&GcTileStippleOriginX != 0 {
1553+ binary.LittleEndian.PutUint32(p[off:], uint32(v.TileStippleXOrigin))
1554+ off += 4
1555+ }
1556+ if v.Mask&GcTileStippleOriginY != 0 {
1557+ binary.LittleEndian.PutUint32(p[off:], uint32(v.TileStippleYOrigin))
1558+ off += 4
1559+ }
1560+ if v.Mask&GcFont != 0 {
1561+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Font))
1562+ off += 4
1563+ }
1564+ if v.Mask&GcSubwindowMode != 0 {
1565+ binary.LittleEndian.PutUint32(p[off:], uint32(v.SubwindowMode))
1566+ off += 4
1567+ }
1568+ if v.Mask&GcGraphicsExposures != 0 {
1569+ if v.GraphicsExposures {
1570+ binary.LittleEndian.PutUint32(p[off:], 1)
1571+ } else {
1572+ binary.LittleEndian.PutUint32(p[off:], 0)
1573+ }
1574+ off += 4
1575+ }
1576+ if v.Mask&GcClipOriginX != 0 {
1577+ binary.LittleEndian.PutUint32(p[off:], uint32(v.ClipXOrigin))
1578+ off += 4
1579+ }
1580+ if v.Mask&GcClipOriginY != 0 {
1581+ binary.LittleEndian.PutUint32(p[off:], uint32(v.ClipYOrigin))
1582+ off += 4
1583+ }
1584+ if v.Mask&GcClipMask != 0 {
1585+ binary.LittleEndian.PutUint32(p[off:], uint32(v.ClipMask))
1586+ off += 4
1587+ }
1588+ if v.Mask&GcDashOffset != 0 {
1589+ binary.LittleEndian.PutUint32(p[off:], uint32(v.DashOffset))
1590+ off += 4
1591+ }
1592+ if v.Mask&GcDashList != 0 {
1593+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Dashes))
1594+ off += 4
1595+ }
1596+ if v.Mask&GcArcMode != 0 {
1597+ binary.LittleEndian.PutUint32(p[off:], uint32(v.ArcMode))
1598+ off += 4
1599+ }
1600+ _ = off
1601+ return seq
1602+}
1603+
6761604 func CopyGC(b *xturbo.Buf, srcGc Gcontext, dstGc Gcontext, valueMask Gc) xturbo.Seq {
6771605 p, seq := b.Request(57, 0, 12)
6781606 if p == nil {
@@ -1533,6 +2461,101 @@ func GetKeyboardMapping(b *xturbo.Buf, firstKeycode Keycode, count uint8) xturbo
15332461 return seq
15342462 }
15352463
2464+type ChangeKeyboardControlValues struct {
2465+ Mask Kb
2466+ KeyClickPercent int32
2467+ BellPercent int32
2468+ BellPitch int32
2469+ BellDuration int32
2470+ Led uint32
2471+ LedMode LedMode
2472+ Key Keycode32
2473+ AutoRepeatMode AutoRepeatMode
2474+}
2475+
2476+func (v *ChangeKeyboardControlValues) SetKeyClickPercent(x int32) *ChangeKeyboardControlValues {
2477+ v.Mask |= KbKeyClickPercent
2478+ v.KeyClickPercent = x
2479+ return v
2480+}
2481+func (v *ChangeKeyboardControlValues) SetBellPercent(x int32) *ChangeKeyboardControlValues {
2482+ v.Mask |= KbBellPercent
2483+ v.BellPercent = x
2484+ return v
2485+}
2486+func (v *ChangeKeyboardControlValues) SetBellPitch(x int32) *ChangeKeyboardControlValues {
2487+ v.Mask |= KbBellPitch
2488+ v.BellPitch = x
2489+ return v
2490+}
2491+func (v *ChangeKeyboardControlValues) SetBellDuration(x int32) *ChangeKeyboardControlValues {
2492+ v.Mask |= KbBellDuration
2493+ v.BellDuration = x
2494+ return v
2495+}
2496+func (v *ChangeKeyboardControlValues) SetLed(x uint32) *ChangeKeyboardControlValues {
2497+ v.Mask |= KbLed
2498+ v.Led = x
2499+ return v
2500+}
2501+func (v *ChangeKeyboardControlValues) SetLedMode(x LedMode) *ChangeKeyboardControlValues {
2502+ v.Mask |= KbLedMode
2503+ v.LedMode = x
2504+ return v
2505+}
2506+func (v *ChangeKeyboardControlValues) SetKey(x Keycode32) *ChangeKeyboardControlValues {
2507+ v.Mask |= KbKey
2508+ v.Key = x
2509+ return v
2510+}
2511+func (v *ChangeKeyboardControlValues) SetAutoRepeatMode(x AutoRepeatMode) *ChangeKeyboardControlValues {
2512+ v.Mask |= KbAutoRepeatMode
2513+ v.AutoRepeatMode = x
2514+ return v
2515+}
2516+func ChangeKeyboardControl(b *xturbo.Buf, v *ChangeKeyboardControlValues) xturbo.Seq {
2517+ p, seq := b.Request(102, 0, 4+4*bits.OnesCount32(uint32(v.Mask)))
2518+ if p == nil {
2519+ return 0
2520+ }
2521+ binary.LittleEndian.PutUint32(p[0:], uint32(v.Mask))
2522+ off := 4
2523+ if v.Mask&KbKeyClickPercent != 0 {
2524+ binary.LittleEndian.PutUint32(p[off:], uint32(v.KeyClickPercent))
2525+ off += 4
2526+ }
2527+ if v.Mask&KbBellPercent != 0 {
2528+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BellPercent))
2529+ off += 4
2530+ }
2531+ if v.Mask&KbBellPitch != 0 {
2532+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BellPitch))
2533+ off += 4
2534+ }
2535+ if v.Mask&KbBellDuration != 0 {
2536+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BellDuration))
2537+ off += 4
2538+ }
2539+ if v.Mask&KbLed != 0 {
2540+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Led))
2541+ off += 4
2542+ }
2543+ if v.Mask&KbLedMode != 0 {
2544+ binary.LittleEndian.PutUint32(p[off:], uint32(v.LedMode))
2545+ off += 4
2546+ }
2547+ if v.Mask&KbKey != 0 {
2548+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Key))
2549+ off += 4
2550+ }
2551+ if v.Mask&KbAutoRepeatMode != 0 {
2552+ binary.LittleEndian.PutUint32(p[off:], uint32(v.AutoRepeatMode))
2553+ off += 4
2554+ }
2555+ _ = off
2556+ return seq
2557+}
2558+
15362559 func GetKeyboardControl(b *xturbo.Buf) xturbo.Seq {
15372560 p, seq := b.Request(103, 0, 0)
15382561 if p == nil {
@@ -2,8 +2,365 @@
2 package xproto2 package xproto
3 3
4 import "encoding/binary"4 import "encoding/binary"
5+import "math/bits"
5 import "bnema.dev/xturbo"6 import "bnema.dev/xturbo"
6 7
8+type CreateWindowValues struct {
9+ Mask Cw
10+ BackgroundPixmap Pixmap
11+ BackgroundPixel uint32
12+ BorderPixmap Pixmap
13+ BorderPixel uint32
14+ BitGravity Gravity
15+ WinGravity Gravity
16+ BackingStore BackingStore
17+ BackingPlanes uint32
18+ BackingPixel uint32
19+ OverrideRedirect bool
20+ SaveUnder bool
21+ EventMask EventMask
22+ DoNotPropogateMask EventMask
23+ Colormap Colormap
24+ Cursor Cursor
25+}
26+
27+func (v *CreateWindowValues) SetBackgroundPixmap(x Pixmap) *CreateWindowValues {
28+ v.Mask |= CwBackPixmap
29+ v.BackgroundPixmap = x
30+ return v
31+}
32+func (v *CreateWindowValues) SetBackgroundPixel(x uint32) *CreateWindowValues {
33+ v.Mask |= CwBackPixel
34+ v.BackgroundPixel = x
35+ return v
36+}
37+func (v *CreateWindowValues) SetBorderPixmap(x Pixmap) *CreateWindowValues {
38+ v.Mask |= CwBorderPixmap
39+ v.BorderPixmap = x
40+ return v
41+}
42+func (v *CreateWindowValues) SetBorderPixel(x uint32) *CreateWindowValues {
43+ v.Mask |= CwBorderPixel
44+ v.BorderPixel = x
45+ return v
46+}
47+func (v *CreateWindowValues) SetBitGravity(x Gravity) *CreateWindowValues {
48+ v.Mask |= CwBitGravity
49+ v.BitGravity = x
50+ return v
51+}
52+func (v *CreateWindowValues) SetWinGravity(x Gravity) *CreateWindowValues {
53+ v.Mask |= CwWinGravity
54+ v.WinGravity = x
55+ return v
56+}
57+func (v *CreateWindowValues) SetBackingStore(x BackingStore) *CreateWindowValues {
58+ v.Mask |= CwBackingStore
59+ v.BackingStore = x
60+ return v
61+}
62+func (v *CreateWindowValues) SetBackingPlanes(x uint32) *CreateWindowValues {
63+ v.Mask |= CwBackingPlanes
64+ v.BackingPlanes = x
65+ return v
66+}
67+func (v *CreateWindowValues) SetBackingPixel(x uint32) *CreateWindowValues {
68+ v.Mask |= CwBackingPixel
69+ v.BackingPixel = x
70+ return v
71+}
72+func (v *CreateWindowValues) SetOverrideRedirect(x bool) *CreateWindowValues {
73+ v.Mask |= CwOverrideRedirect
74+ v.OverrideRedirect = x
75+ return v
76+}
77+func (v *CreateWindowValues) SetSaveUnder(x bool) *CreateWindowValues {
78+ v.Mask |= CwSaveUnder
79+ v.SaveUnder = x
80+ return v
81+}
82+func (v *CreateWindowValues) SetEventMask(x EventMask) *CreateWindowValues {
83+ v.Mask |= CwEventMask
84+ v.EventMask = x
85+ return v
86+}
87+func (v *CreateWindowValues) SetDoNotPropogateMask(x EventMask) *CreateWindowValues {
88+ v.Mask |= CwDontPropagate
89+ v.DoNotPropogateMask = x
90+ return v
91+}
92+func (v *CreateWindowValues) SetColormap(x Colormap) *CreateWindowValues {
93+ v.Mask |= CwColormap
94+ v.Colormap = x
95+ return v
96+}
97+func (v *CreateWindowValues) SetCursor(x Cursor) *CreateWindowValues {
98+ v.Mask |= CwCursor
99+ v.Cursor = x
100+ return v
101+}
102+func CreateWindow(b *xturbo.Buf, depth uint8, wid Window, parent Window, x int16, y int16, width uint16, height uint16, borderWidth uint16, class WindowClass, visual Visualid, v *CreateWindowValues) xturbo.Seq {
103+ p, seq := b.Request(1, uint8(int(depth)), 28+4*bits.OnesCount32(uint32(v.Mask)))
104+ if p == nil {
105+ return 0
106+ }
107+ binary.LittleEndian.PutUint32(p[0:], uint32(wid))
108+ binary.LittleEndian.PutUint32(p[4:], uint32(parent))
109+ binary.LittleEndian.PutUint16(p[8:], uint16(x))
110+ binary.LittleEndian.PutUint16(p[10:], uint16(y))
111+ binary.LittleEndian.PutUint16(p[12:], uint16(width))
112+ binary.LittleEndian.PutUint16(p[14:], uint16(height))
113+ binary.LittleEndian.PutUint16(p[16:], uint16(borderWidth))
114+ binary.LittleEndian.PutUint16(p[18:], uint16(class))
115+ binary.LittleEndian.PutUint32(p[20:], uint32(visual))
116+ binary.LittleEndian.PutUint32(p[24:], uint32(v.Mask))
117+ off := 28
118+ if v.Mask&CwBackPixmap != 0 {
119+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BackgroundPixmap))
120+ off += 4
121+ }
122+ if v.Mask&CwBackPixel != 0 {
123+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BackgroundPixel))
124+ off += 4
125+ }
126+ if v.Mask&CwBorderPixmap != 0 {
127+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BorderPixmap))
128+ off += 4
129+ }
130+ if v.Mask&CwBorderPixel != 0 {
131+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BorderPixel))
132+ off += 4
133+ }
134+ if v.Mask&CwBitGravity != 0 {
135+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BitGravity))
136+ off += 4
137+ }
138+ if v.Mask&CwWinGravity != 0 {
139+ binary.LittleEndian.PutUint32(p[off:], uint32(v.WinGravity))
140+ off += 4
141+ }
142+ if v.Mask&CwBackingStore != 0 {
143+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BackingStore))
144+ off += 4
145+ }
146+ if v.Mask&CwBackingPlanes != 0 {
147+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BackingPlanes))
148+ off += 4
149+ }
150+ if v.Mask&CwBackingPixel != 0 {
151+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BackingPixel))
152+ off += 4
153+ }
154+ if v.Mask&CwOverrideRedirect != 0 {
155+ if v.OverrideRedirect {
156+ binary.LittleEndian.PutUint32(p[off:], 1)
157+ } else {
158+ binary.LittleEndian.PutUint32(p[off:], 0)
159+ }
160+ off += 4
161+ }
162+ if v.Mask&CwSaveUnder != 0 {
163+ if v.SaveUnder {
164+ binary.LittleEndian.PutUint32(p[off:], 1)
165+ } else {
166+ binary.LittleEndian.PutUint32(p[off:], 0)
167+ }
168+ off += 4
169+ }
170+ if v.Mask&CwEventMask != 0 {
171+ binary.LittleEndian.PutUint32(p[off:], uint32(v.EventMask))
172+ off += 4
173+ }
174+ if v.Mask&CwDontPropagate != 0 {
175+ binary.LittleEndian.PutUint32(p[off:], uint32(v.DoNotPropogateMask))
176+ off += 4
177+ }
178+ if v.Mask&CwColormap != 0 {
179+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Colormap))
180+ off += 4
181+ }
182+ if v.Mask&CwCursor != 0 {
183+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Cursor))
184+ off += 4
185+ }
186+ _ = off
187+ return seq
188+}
189+
190+type ChangeWindowAttributesValues struct {
191+ Mask Cw
192+ BackgroundPixmap Pixmap
193+ BackgroundPixel uint32
194+ BorderPixmap Pixmap
195+ BorderPixel uint32
196+ BitGravity Gravity
197+ WinGravity Gravity
198+ BackingStore BackingStore
199+ BackingPlanes uint32
200+ BackingPixel uint32
201+ OverrideRedirect bool
202+ SaveUnder bool
203+ EventMask EventMask
204+ DoNotPropogateMask EventMask
205+ Colormap Colormap
206+ Cursor Cursor
207+}
208+
209+func (v *ChangeWindowAttributesValues) SetBackgroundPixmap(x Pixmap) *ChangeWindowAttributesValues {
210+ v.Mask |= CwBackPixmap
211+ v.BackgroundPixmap = x
212+ return v
213+}
214+func (v *ChangeWindowAttributesValues) SetBackgroundPixel(x uint32) *ChangeWindowAttributesValues {
215+ v.Mask |= CwBackPixel
216+ v.BackgroundPixel = x
217+ return v
218+}
219+func (v *ChangeWindowAttributesValues) SetBorderPixmap(x Pixmap) *ChangeWindowAttributesValues {
220+ v.Mask |= CwBorderPixmap
221+ v.BorderPixmap = x
222+ return v
223+}
224+func (v *ChangeWindowAttributesValues) SetBorderPixel(x uint32) *ChangeWindowAttributesValues {
225+ v.Mask |= CwBorderPixel
226+ v.BorderPixel = x
227+ return v
228+}
229+func (v *ChangeWindowAttributesValues) SetBitGravity(x Gravity) *ChangeWindowAttributesValues {
230+ v.Mask |= CwBitGravity
231+ v.BitGravity = x
232+ return v
233+}
234+func (v *ChangeWindowAttributesValues) SetWinGravity(x Gravity) *ChangeWindowAttributesValues {
235+ v.Mask |= CwWinGravity
236+ v.WinGravity = x
237+ return v
238+}
239+func (v *ChangeWindowAttributesValues) SetBackingStore(x BackingStore) *ChangeWindowAttributesValues {
240+ v.Mask |= CwBackingStore
241+ v.BackingStore = x
242+ return v
243+}
244+func (v *ChangeWindowAttributesValues) SetBackingPlanes(x uint32) *ChangeWindowAttributesValues {
245+ v.Mask |= CwBackingPlanes
246+ v.BackingPlanes = x
247+ return v
248+}
249+func (v *ChangeWindowAttributesValues) SetBackingPixel(x uint32) *ChangeWindowAttributesValues {
250+ v.Mask |= CwBackingPixel
251+ v.BackingPixel = x
252+ return v
253+}
254+func (v *ChangeWindowAttributesValues) SetOverrideRedirect(x bool) *ChangeWindowAttributesValues {
255+ v.Mask |= CwOverrideRedirect
256+ v.OverrideRedirect = x
257+ return v
258+}
259+func (v *ChangeWindowAttributesValues) SetSaveUnder(x bool) *ChangeWindowAttributesValues {
260+ v.Mask |= CwSaveUnder
261+ v.SaveUnder = x
262+ return v
263+}
264+func (v *ChangeWindowAttributesValues) SetEventMask(x EventMask) *ChangeWindowAttributesValues {
265+ v.Mask |= CwEventMask
266+ v.EventMask = x
267+ return v
268+}
269+func (v *ChangeWindowAttributesValues) SetDoNotPropogateMask(x EventMask) *ChangeWindowAttributesValues {
270+ v.Mask |= CwDontPropagate
271+ v.DoNotPropogateMask = x
272+ return v
273+}
274+func (v *ChangeWindowAttributesValues) SetColormap(x Colormap) *ChangeWindowAttributesValues {
275+ v.Mask |= CwColormap
276+ v.Colormap = x
277+ return v
278+}
279+func (v *ChangeWindowAttributesValues) SetCursor(x Cursor) *ChangeWindowAttributesValues {
280+ v.Mask |= CwCursor
281+ v.Cursor = x
282+ return v
283+}
284+func ChangeWindowAttributes(b *xturbo.Buf, window Window, v *ChangeWindowAttributesValues) xturbo.Seq {
285+ p, seq := b.Request(2, 0, 8+4*bits.OnesCount32(uint32(v.Mask)))
286+ if p == nil {
287+ return 0
288+ }
289+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
290+ binary.LittleEndian.PutUint32(p[4:], uint32(v.Mask))
291+ off := 8
292+ if v.Mask&CwBackPixmap != 0 {
293+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BackgroundPixmap))
294+ off += 4
295+ }
296+ if v.Mask&CwBackPixel != 0 {
297+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BackgroundPixel))
298+ off += 4
299+ }
300+ if v.Mask&CwBorderPixmap != 0 {
301+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BorderPixmap))
302+ off += 4
303+ }
304+ if v.Mask&CwBorderPixel != 0 {
305+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BorderPixel))
306+ off += 4
307+ }
308+ if v.Mask&CwBitGravity != 0 {
309+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BitGravity))
310+ off += 4
311+ }
312+ if v.Mask&CwWinGravity != 0 {
313+ binary.LittleEndian.PutUint32(p[off:], uint32(v.WinGravity))
314+ off += 4
315+ }
316+ if v.Mask&CwBackingStore != 0 {
317+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BackingStore))
318+ off += 4
319+ }
320+ if v.Mask&CwBackingPlanes != 0 {
321+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BackingPlanes))
322+ off += 4
323+ }
324+ if v.Mask&CwBackingPixel != 0 {
325+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BackingPixel))
326+ off += 4
327+ }
328+ if v.Mask&CwOverrideRedirect != 0 {
329+ if v.OverrideRedirect {
330+ binary.LittleEndian.PutUint32(p[off:], 1)
331+ } else {
332+ binary.LittleEndian.PutUint32(p[off:], 0)
333+ }
334+ off += 4
335+ }
336+ if v.Mask&CwSaveUnder != 0 {
337+ if v.SaveUnder {
338+ binary.LittleEndian.PutUint32(p[off:], 1)
339+ } else {
340+ binary.LittleEndian.PutUint32(p[off:], 0)
341+ }
342+ off += 4
343+ }
344+ if v.Mask&CwEventMask != 0 {
345+ binary.LittleEndian.PutUint32(p[off:], uint32(v.EventMask))
346+ off += 4
347+ }
348+ if v.Mask&CwDontPropagate != 0 {
349+ binary.LittleEndian.PutUint32(p[off:], uint32(v.DoNotPropogateMask))
350+ off += 4
351+ }
352+ if v.Mask&CwColormap != 0 {
353+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Colormap))
354+ off += 4
355+ }
356+ if v.Mask&CwCursor != 0 {
357+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Cursor))
358+ off += 4
359+ }
360+ _ = off
361+ return seq
362+}
363+
7 func GetWindowAttributes(b *xturbo.Buf, window Window) xturbo.Seq {364 func GetWindowAttributes(b *xturbo.Buf, window Window) xturbo.Seq {
8 p, seq := b.Request(3, 0, 4)365 p, seq := b.Request(3, 0, 4)
9 if p == nil {366 if p == nil {
@@ -88,6 +445,92 @@ func UnmapSubwindows(b *xturbo.Buf, window Window) xturbo.Seq {
88 return seq445 return seq
89 }446 }
90 447
448+type ConfigureWindowValues struct {
449+ Mask ConfigWindow
450+ X int32
451+ Y int32
452+ Width uint32
453+ Height uint32
454+ BorderWidth uint32
455+ Sibling Window
456+ StackMode StackMode
457+}
458+
459+func (v *ConfigureWindowValues) SetX(x int32) *ConfigureWindowValues {
460+ v.Mask |= ConfigWindowX
461+ v.X = x
462+ return v
463+}
464+func (v *ConfigureWindowValues) SetY(x int32) *ConfigureWindowValues {
465+ v.Mask |= ConfigWindowY
466+ v.Y = x
467+ return v
468+}
469+func (v *ConfigureWindowValues) SetWidth(x uint32) *ConfigureWindowValues {
470+ v.Mask |= ConfigWindowWidth
471+ v.Width = x
472+ return v
473+}
474+func (v *ConfigureWindowValues) SetHeight(x uint32) *ConfigureWindowValues {
475+ v.Mask |= ConfigWindowHeight
476+ v.Height = x
477+ return v
478+}
479+func (v *ConfigureWindowValues) SetBorderWidth(x uint32) *ConfigureWindowValues {
480+ v.Mask |= ConfigWindowBorderWidth
481+ v.BorderWidth = x
482+ return v
483+}
484+func (v *ConfigureWindowValues) SetSibling(x Window) *ConfigureWindowValues {
485+ v.Mask |= ConfigWindowSibling
486+ v.Sibling = x
487+ return v
488+}
489+func (v *ConfigureWindowValues) SetStackMode(x StackMode) *ConfigureWindowValues {
490+ v.Mask |= ConfigWindowStackMode
491+ v.StackMode = x
492+ return v
493+}
494+func ConfigureWindow(b *xturbo.Buf, window Window, v *ConfigureWindowValues) xturbo.Seq {
495+ p, seq := b.Request(12, 0, 8+4*bits.OnesCount32(uint32(v.Mask)))
496+ if p == nil {
497+ return 0
498+ }
499+ binary.LittleEndian.PutUint32(p[0:], uint32(window))
500+ binary.LittleEndian.PutUint16(p[4:], uint16(v.Mask))
501+ off := 8
502+ if v.Mask&ConfigWindowX != 0 {
503+ binary.LittleEndian.PutUint32(p[off:], uint32(v.X))
504+ off += 4
505+ }
506+ if v.Mask&ConfigWindowY != 0 {
507+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Y))
508+ off += 4
509+ }
510+ if v.Mask&ConfigWindowWidth != 0 {
511+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Width))
512+ off += 4
513+ }
514+ if v.Mask&ConfigWindowHeight != 0 {
515+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Height))
516+ off += 4
517+ }
518+ if v.Mask&ConfigWindowBorderWidth != 0 {
519+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BorderWidth))
520+ off += 4
521+ }
522+ if v.Mask&ConfigWindowSibling != 0 {
523+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Sibling))
524+ off += 4
525+ }
526+ if v.Mask&ConfigWindowStackMode != 0 {
527+ binary.LittleEndian.PutUint32(p[off:], uint32(v.StackMode))
528+ off += 4
529+ }
530+ _ = off
531+ return seq
532+}
533+
91 func CirculateWindow(b *xturbo.Buf, direction Circulate, window Window) xturbo.Seq {534 func CirculateWindow(b *xturbo.Buf, direction Circulate, window Window) xturbo.Seq {
92 p, seq := b.Request(13, uint8(int(direction)), 4)535 p, seq := b.Request(13, uint8(int(direction)), 4)
93 if p == nil {536 if p == nil {
@@ -673,6 +1116,491 @@ func FreePixmap(b *xturbo.Buf, pixmap Pixmap) xturbo.Seq {
673 return seq1116 return seq
674 }1117 }
675 1118
1119+type CreateGCValues struct {
1120+ Mask Gc
1121+ Function Gx
1122+ PlaneMask uint32
1123+ Foreground uint32
1124+ Background uint32
1125+ LineWidth uint32
1126+ LineStyle LineStyle
1127+ CapStyle CapStyle
1128+ JoinStyle JoinStyle
1129+ FillStyle FillStyle
1130+ FillRule FillRule
1131+ Tile Pixmap
1132+ Stipple Pixmap
1133+ TileStippleXOrigin int32
1134+ TileStippleYOrigin int32
1135+ Font Font
1136+ SubwindowMode SubwindowMode
1137+ GraphicsExposures bool
1138+ ClipXOrigin int32
1139+ ClipYOrigin int32
1140+ ClipMask Pixmap
1141+ DashOffset uint32
1142+ Dashes uint32
1143+ ArcMode ArcMode
1144+}
1145+
1146+func (v *CreateGCValues) SetFunction(x Gx) *CreateGCValues {
1147+ v.Mask |= GcFunction
1148+ v.Function = x
1149+ return v
1150+}
1151+func (v *CreateGCValues) SetPlaneMask(x uint32) *CreateGCValues {
1152+ v.Mask |= GcPlaneMask
1153+ v.PlaneMask = x
1154+ return v
1155+}
1156+func (v *CreateGCValues) SetForeground(x uint32) *CreateGCValues {
1157+ v.Mask |= GcForeground
1158+ v.Foreground = x
1159+ return v
1160+}
1161+func (v *CreateGCValues) SetBackground(x uint32) *CreateGCValues {
1162+ v.Mask |= GcBackground
1163+ v.Background = x
1164+ return v
1165+}
1166+func (v *CreateGCValues) SetLineWidth(x uint32) *CreateGCValues {
1167+ v.Mask |= GcLineWidth
1168+ v.LineWidth = x
1169+ return v
1170+}
1171+func (v *CreateGCValues) SetLineStyle(x LineStyle) *CreateGCValues {
1172+ v.Mask |= GcLineStyle
1173+ v.LineStyle = x
1174+ return v
1175+}
1176+func (v *CreateGCValues) SetCapStyle(x CapStyle) *CreateGCValues {
1177+ v.Mask |= GcCapStyle
1178+ v.CapStyle = x
1179+ return v
1180+}
1181+func (v *CreateGCValues) SetJoinStyle(x JoinStyle) *CreateGCValues {
1182+ v.Mask |= GcJoinStyle
1183+ v.JoinStyle = x
1184+ return v
1185+}
1186+func (v *CreateGCValues) SetFillStyle(x FillStyle) *CreateGCValues {
1187+ v.Mask |= GcFillStyle
1188+ v.FillStyle = x
1189+ return v
1190+}
1191+func (v *CreateGCValues) SetFillRule(x FillRule) *CreateGCValues {
1192+ v.Mask |= GcFillRule
1193+ v.FillRule = x
1194+ return v
1195+}
1196+func (v *CreateGCValues) SetTile(x Pixmap) *CreateGCValues { v.Mask |= GcTile; v.Tile = x; return v }
1197+func (v *CreateGCValues) SetStipple(x Pixmap) *CreateGCValues {
1198+ v.Mask |= GcStipple
1199+ v.Stipple = x
1200+ return v
1201+}
1202+func (v *CreateGCValues) SetTileStippleXOrigin(x int32) *CreateGCValues {
1203+ v.Mask |= GcTileStippleOriginX
1204+ v.TileStippleXOrigin = x
1205+ return v
1206+}
1207+func (v *CreateGCValues) SetTileStippleYOrigin(x int32) *CreateGCValues {
1208+ v.Mask |= GcTileStippleOriginY
1209+ v.TileStippleYOrigin = x
1210+ return v
1211+}
1212+func (v *CreateGCValues) SetFont(x Font) *CreateGCValues { v.Mask |= GcFont; v.Font = x; return v }
1213+func (v *CreateGCValues) SetSubwindowMode(x SubwindowMode) *CreateGCValues {
1214+ v.Mask |= GcSubwindowMode
1215+ v.SubwindowMode = x
1216+ return v
1217+}
1218+func (v *CreateGCValues) SetGraphicsExposures(x bool) *CreateGCValues {
1219+ v.Mask |= GcGraphicsExposures
1220+ v.GraphicsExposures = x
1221+ return v
1222+}
1223+func (v *CreateGCValues) SetClipXOrigin(x int32) *CreateGCValues {
1224+ v.Mask |= GcClipOriginX
1225+ v.ClipXOrigin = x
1226+ return v
1227+}
1228+func (v *CreateGCValues) SetClipYOrigin(x int32) *CreateGCValues {
1229+ v.Mask |= GcClipOriginY
1230+ v.ClipYOrigin = x
1231+ return v
1232+}
1233+func (v *CreateGCValues) SetClipMask(x Pixmap) *CreateGCValues {
1234+ v.Mask |= GcClipMask
1235+ v.ClipMask = x
1236+ return v
1237+}
1238+func (v *CreateGCValues) SetDashOffset(x uint32) *CreateGCValues {
1239+ v.Mask |= GcDashOffset
1240+ v.DashOffset = x
1241+ return v
1242+}
1243+func (v *CreateGCValues) SetDashes(x uint32) *CreateGCValues {
1244+ v.Mask |= GcDashList
1245+ v.Dashes = x
1246+ return v
1247+}
1248+func (v *CreateGCValues) SetArcMode(x ArcMode) *CreateGCValues {
1249+ v.Mask |= GcArcMode
1250+ v.ArcMode = x
1251+ return v
1252+}
1253+func CreateGC(b *xturbo.Buf, cid Gcontext, drawable Drawable, v *CreateGCValues) xturbo.Seq {
1254+ p, seq := b.Request(55, 0, 12+4*bits.OnesCount32(uint32(v.Mask)))
1255+ if p == nil {
1256+ return 0
1257+ }
1258+ binary.LittleEndian.PutUint32(p[0:], uint32(cid))
1259+ binary.LittleEndian.PutUint32(p[4:], uint32(drawable))
1260+ binary.LittleEndian.PutUint32(p[8:], uint32(v.Mask))
1261+ off := 12
1262+ if v.Mask&GcFunction != 0 {
1263+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Function))
1264+ off += 4
1265+ }
1266+ if v.Mask&GcPlaneMask != 0 {
1267+ binary.LittleEndian.PutUint32(p[off:], uint32(v.PlaneMask))
1268+ off += 4
1269+ }
1270+ if v.Mask&GcForeground != 0 {
1271+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Foreground))
1272+ off += 4
1273+ }
1274+ if v.Mask&GcBackground != 0 {
1275+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Background))
1276+ off += 4
1277+ }
1278+ if v.Mask&GcLineWidth != 0 {
1279+ binary.LittleEndian.PutUint32(p[off:], uint32(v.LineWidth))
1280+ off += 4
1281+ }
1282+ if v.Mask&GcLineStyle != 0 {
1283+ binary.LittleEndian.PutUint32(p[off:], uint32(v.LineStyle))
1284+ off += 4
1285+ }
1286+ if v.Mask&GcCapStyle != 0 {
1287+ binary.LittleEndian.PutUint32(p[off:], uint32(v.CapStyle))
1288+ off += 4
1289+ }
1290+ if v.Mask&GcJoinStyle != 0 {
1291+ binary.LittleEndian.PutUint32(p[off:], uint32(v.JoinStyle))
1292+ off += 4
1293+ }
1294+ if v.Mask&GcFillStyle != 0 {
1295+ binary.LittleEndian.PutUint32(p[off:], uint32(v.FillStyle))
1296+ off += 4
1297+ }
1298+ if v.Mask&GcFillRule != 0 {
1299+ binary.LittleEndian.PutUint32(p[off:], uint32(v.FillRule))
1300+ off += 4
1301+ }
1302+ if v.Mask&GcTile != 0 {
1303+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Tile))
1304+ off += 4
1305+ }
1306+ if v.Mask&GcStipple != 0 {
1307+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Stipple))
1308+ off += 4
1309+ }
1310+ if v.Mask&GcTileStippleOriginX != 0 {
1311+ binary.LittleEndian.PutUint32(p[off:], uint32(v.TileStippleXOrigin))
1312+ off += 4
1313+ }
1314+ if v.Mask&GcTileStippleOriginY != 0 {
1315+ binary.LittleEndian.PutUint32(p[off:], uint32(v.TileStippleYOrigin))
1316+ off += 4
1317+ }
1318+ if v.Mask&GcFont != 0 {
1319+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Font))
1320+ off += 4
1321+ }
1322+ if v.Mask&GcSubwindowMode != 0 {
1323+ binary.LittleEndian.PutUint32(p[off:], uint32(v.SubwindowMode))
1324+ off += 4
1325+ }
1326+ if v.Mask&GcGraphicsExposures != 0 {
1327+ if v.GraphicsExposures {
1328+ binary.LittleEndian.PutUint32(p[off:], 1)
1329+ } else {
1330+ binary.LittleEndian.PutUint32(p[off:], 0)
1331+ }
1332+ off += 4
1333+ }
1334+ if v.Mask&GcClipOriginX != 0 {
1335+ binary.LittleEndian.PutUint32(p[off:], uint32(v.ClipXOrigin))
1336+ off += 4
1337+ }
1338+ if v.Mask&GcClipOriginY != 0 {
1339+ binary.LittleEndian.PutUint32(p[off:], uint32(v.ClipYOrigin))
1340+ off += 4
1341+ }
1342+ if v.Mask&GcClipMask != 0 {
1343+ binary.LittleEndian.PutUint32(p[off:], uint32(v.ClipMask))
1344+ off += 4
1345+ }
1346+ if v.Mask&GcDashOffset != 0 {
1347+ binary.LittleEndian.PutUint32(p[off:], uint32(v.DashOffset))
1348+ off += 4
1349+ }
1350+ if v.Mask&GcDashList != 0 {
1351+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Dashes))
1352+ off += 4
1353+ }
1354+ if v.Mask&GcArcMode != 0 {
1355+ binary.LittleEndian.PutUint32(p[off:], uint32(v.ArcMode))
1356+ off += 4
1357+ }
1358+ _ = off
1359+ return seq
1360+}
1361+
1362+type ChangeGCValues struct {
1363+ Mask Gc
1364+ Function Gx
1365+ PlaneMask uint32
1366+ Foreground uint32
1367+ Background uint32
1368+ LineWidth uint32
1369+ LineStyle LineStyle
1370+ CapStyle CapStyle
1371+ JoinStyle JoinStyle
1372+ FillStyle FillStyle
1373+ FillRule FillRule
1374+ Tile Pixmap
1375+ Stipple Pixmap
1376+ TileStippleXOrigin int32
1377+ TileStippleYOrigin int32
1378+ Font Font
1379+ SubwindowMode SubwindowMode
1380+ GraphicsExposures bool
1381+ ClipXOrigin int32
1382+ ClipYOrigin int32
1383+ ClipMask Pixmap
1384+ DashOffset uint32
1385+ Dashes uint32
1386+ ArcMode ArcMode
1387+}
1388+
1389+func (v *ChangeGCValues) SetFunction(x Gx) *ChangeGCValues {
1390+ v.Mask |= GcFunction
1391+ v.Function = x
1392+ return v
1393+}
1394+func (v *ChangeGCValues) SetPlaneMask(x uint32) *ChangeGCValues {
1395+ v.Mask |= GcPlaneMask
1396+ v.PlaneMask = x
1397+ return v
1398+}
1399+func (v *ChangeGCValues) SetForeground(x uint32) *ChangeGCValues {
1400+ v.Mask |= GcForeground
1401+ v.Foreground = x
1402+ return v
1403+}
1404+func (v *ChangeGCValues) SetBackground(x uint32) *ChangeGCValues {
1405+ v.Mask |= GcBackground
1406+ v.Background = x
1407+ return v
1408+}
1409+func (v *ChangeGCValues) SetLineWidth(x uint32) *ChangeGCValues {
1410+ v.Mask |= GcLineWidth
1411+ v.LineWidth = x
1412+ return v
1413+}
1414+func (v *ChangeGCValues) SetLineStyle(x LineStyle) *ChangeGCValues {
1415+ v.Mask |= GcLineStyle
1416+ v.LineStyle = x
1417+ return v
1418+}
1419+func (v *ChangeGCValues) SetCapStyle(x CapStyle) *ChangeGCValues {
1420+ v.Mask |= GcCapStyle
1421+ v.CapStyle = x
1422+ return v
1423+}
1424+func (v *ChangeGCValues) SetJoinStyle(x JoinStyle) *ChangeGCValues {
1425+ v.Mask |= GcJoinStyle
1426+ v.JoinStyle = x
1427+ return v
1428+}
1429+func (v *ChangeGCValues) SetFillStyle(x FillStyle) *ChangeGCValues {
1430+ v.Mask |= GcFillStyle
1431+ v.FillStyle = x
1432+ return v
1433+}
1434+func (v *ChangeGCValues) SetFillRule(x FillRule) *ChangeGCValues {
1435+ v.Mask |= GcFillRule
1436+ v.FillRule = x
1437+ return v
1438+}
1439+func (v *ChangeGCValues) SetTile(x Pixmap) *ChangeGCValues { v.Mask |= GcTile; v.Tile = x; return v }
1440+func (v *ChangeGCValues) SetStipple(x Pixmap) *ChangeGCValues {
1441+ v.Mask |= GcStipple
1442+ v.Stipple = x
1443+ return v
1444+}
1445+func (v *ChangeGCValues) SetTileStippleXOrigin(x int32) *ChangeGCValues {
1446+ v.Mask |= GcTileStippleOriginX
1447+ v.TileStippleXOrigin = x
1448+ return v
1449+}
1450+func (v *ChangeGCValues) SetTileStippleYOrigin(x int32) *ChangeGCValues {
1451+ v.Mask |= GcTileStippleOriginY
1452+ v.TileStippleYOrigin = x
1453+ return v
1454+}
1455+func (v *ChangeGCValues) SetFont(x Font) *ChangeGCValues { v.Mask |= GcFont; v.Font = x; return v }
1456+func (v *ChangeGCValues) SetSubwindowMode(x SubwindowMode) *ChangeGCValues {
1457+ v.Mask |= GcSubwindowMode
1458+ v.SubwindowMode = x
1459+ return v
1460+}
1461+func (v *ChangeGCValues) SetGraphicsExposures(x bool) *ChangeGCValues {
1462+ v.Mask |= GcGraphicsExposures
1463+ v.GraphicsExposures = x
1464+ return v
1465+}
1466+func (v *ChangeGCValues) SetClipXOrigin(x int32) *ChangeGCValues {
1467+ v.Mask |= GcClipOriginX
1468+ v.ClipXOrigin = x
1469+ return v
1470+}
1471+func (v *ChangeGCValues) SetClipYOrigin(x int32) *ChangeGCValues {
1472+ v.Mask |= GcClipOriginY
1473+ v.ClipYOrigin = x
1474+ return v
1475+}
1476+func (v *ChangeGCValues) SetClipMask(x Pixmap) *ChangeGCValues {
1477+ v.Mask |= GcClipMask
1478+ v.ClipMask = x
1479+ return v
1480+}
1481+func (v *ChangeGCValues) SetDashOffset(x uint32) *ChangeGCValues {
1482+ v.Mask |= GcDashOffset
1483+ v.DashOffset = x
1484+ return v
1485+}
1486+func (v *ChangeGCValues) SetDashes(x uint32) *ChangeGCValues {
1487+ v.Mask |= GcDashList
1488+ v.Dashes = x
1489+ return v
1490+}
1491+func (v *ChangeGCValues) SetArcMode(x ArcMode) *ChangeGCValues {
1492+ v.Mask |= GcArcMode
1493+ v.ArcMode = x
1494+ return v
1495+}
1496+func ChangeGC(b *xturbo.Buf, gc Gcontext, v *ChangeGCValues) xturbo.Seq {
1497+ p, seq := b.Request(56, 0, 8+4*bits.OnesCount32(uint32(v.Mask)))
1498+ if p == nil {
1499+ return 0
1500+ }
1501+ binary.LittleEndian.PutUint32(p[0:], uint32(gc))
1502+ binary.LittleEndian.PutUint32(p[4:], uint32(v.Mask))
1503+ off := 8
1504+ if v.Mask&GcFunction != 0 {
1505+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Function))
1506+ off += 4
1507+ }
1508+ if v.Mask&GcPlaneMask != 0 {
1509+ binary.LittleEndian.PutUint32(p[off:], uint32(v.PlaneMask))
1510+ off += 4
1511+ }
1512+ if v.Mask&GcForeground != 0 {
1513+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Foreground))
1514+ off += 4
1515+ }
1516+ if v.Mask&GcBackground != 0 {
1517+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Background))
1518+ off += 4
1519+ }
1520+ if v.Mask&GcLineWidth != 0 {
1521+ binary.LittleEndian.PutUint32(p[off:], uint32(v.LineWidth))
1522+ off += 4
1523+ }
1524+ if v.Mask&GcLineStyle != 0 {
1525+ binary.LittleEndian.PutUint32(p[off:], uint32(v.LineStyle))
1526+ off += 4
1527+ }
1528+ if v.Mask&GcCapStyle != 0 {
1529+ binary.LittleEndian.PutUint32(p[off:], uint32(v.CapStyle))
1530+ off += 4
1531+ }
1532+ if v.Mask&GcJoinStyle != 0 {
1533+ binary.LittleEndian.PutUint32(p[off:], uint32(v.JoinStyle))
1534+ off += 4
1535+ }
1536+ if v.Mask&GcFillStyle != 0 {
1537+ binary.LittleEndian.PutUint32(p[off:], uint32(v.FillStyle))
1538+ off += 4
1539+ }
1540+ if v.Mask&GcFillRule != 0 {
1541+ binary.LittleEndian.PutUint32(p[off:], uint32(v.FillRule))
1542+ off += 4
1543+ }
1544+ if v.Mask&GcTile != 0 {
1545+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Tile))
1546+ off += 4
1547+ }
1548+ if v.Mask&GcStipple != 0 {
1549+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Stipple))
1550+ off += 4
1551+ }
1552+ if v.Mask&GcTileStippleOriginX != 0 {
1553+ binary.LittleEndian.PutUint32(p[off:], uint32(v.TileStippleXOrigin))
1554+ off += 4
1555+ }
1556+ if v.Mask&GcTileStippleOriginY != 0 {
1557+ binary.LittleEndian.PutUint32(p[off:], uint32(v.TileStippleYOrigin))
1558+ off += 4
1559+ }
1560+ if v.Mask&GcFont != 0 {
1561+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Font))
1562+ off += 4
1563+ }
1564+ if v.Mask&GcSubwindowMode != 0 {
1565+ binary.LittleEndian.PutUint32(p[off:], uint32(v.SubwindowMode))
1566+ off += 4
1567+ }
1568+ if v.Mask&GcGraphicsExposures != 0 {
1569+ if v.GraphicsExposures {
1570+ binary.LittleEndian.PutUint32(p[off:], 1)
1571+ } else {
1572+ binary.LittleEndian.PutUint32(p[off:], 0)
1573+ }
1574+ off += 4
1575+ }
1576+ if v.Mask&GcClipOriginX != 0 {
1577+ binary.LittleEndian.PutUint32(p[off:], uint32(v.ClipXOrigin))
1578+ off += 4
1579+ }
1580+ if v.Mask&GcClipOriginY != 0 {
1581+ binary.LittleEndian.PutUint32(p[off:], uint32(v.ClipYOrigin))
1582+ off += 4
1583+ }
1584+ if v.Mask&GcClipMask != 0 {
1585+ binary.LittleEndian.PutUint32(p[off:], uint32(v.ClipMask))
1586+ off += 4
1587+ }
1588+ if v.Mask&GcDashOffset != 0 {
1589+ binary.LittleEndian.PutUint32(p[off:], uint32(v.DashOffset))
1590+ off += 4
1591+ }
1592+ if v.Mask&GcDashList != 0 {
1593+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Dashes))
1594+ off += 4
1595+ }
1596+ if v.Mask&GcArcMode != 0 {
1597+ binary.LittleEndian.PutUint32(p[off:], uint32(v.ArcMode))
1598+ off += 4
1599+ }
1600+ _ = off
1601+ return seq
1602+}
1603+
676 func CopyGC(b *xturbo.Buf, srcGc Gcontext, dstGc Gcontext, valueMask Gc) xturbo.Seq {1604 func CopyGC(b *xturbo.Buf, srcGc Gcontext, dstGc Gcontext, valueMask Gc) xturbo.Seq {
677 p, seq := b.Request(57, 0, 12)1605 p, seq := b.Request(57, 0, 12)
678 if p == nil {1606 if p == nil {
@@ -1533,6 +2461,101 @@ func GetKeyboardMapping(b *xturbo.Buf, firstKeycode Keycode, count uint8) xturbo
1533 return seq2461 return seq
1534 }2462 }
1535 2463
2464+type ChangeKeyboardControlValues struct {
2465+ Mask Kb
2466+ KeyClickPercent int32
2467+ BellPercent int32
2468+ BellPitch int32
2469+ BellDuration int32
2470+ Led uint32
2471+ LedMode LedMode
2472+ Key Keycode32
2473+ AutoRepeatMode AutoRepeatMode
2474+}
2475+
2476+func (v *ChangeKeyboardControlValues) SetKeyClickPercent(x int32) *ChangeKeyboardControlValues {
2477+ v.Mask |= KbKeyClickPercent
2478+ v.KeyClickPercent = x
2479+ return v
2480+}
2481+func (v *ChangeKeyboardControlValues) SetBellPercent(x int32) *ChangeKeyboardControlValues {
2482+ v.Mask |= KbBellPercent
2483+ v.BellPercent = x
2484+ return v
2485+}
2486+func (v *ChangeKeyboardControlValues) SetBellPitch(x int32) *ChangeKeyboardControlValues {
2487+ v.Mask |= KbBellPitch
2488+ v.BellPitch = x
2489+ return v
2490+}
2491+func (v *ChangeKeyboardControlValues) SetBellDuration(x int32) *ChangeKeyboardControlValues {
2492+ v.Mask |= KbBellDuration
2493+ v.BellDuration = x
2494+ return v
2495+}
2496+func (v *ChangeKeyboardControlValues) SetLed(x uint32) *ChangeKeyboardControlValues {
2497+ v.Mask |= KbLed
2498+ v.Led = x
2499+ return v
2500+}
2501+func (v *ChangeKeyboardControlValues) SetLedMode(x LedMode) *ChangeKeyboardControlValues {
2502+ v.Mask |= KbLedMode
2503+ v.LedMode = x
2504+ return v
2505+}
2506+func (v *ChangeKeyboardControlValues) SetKey(x Keycode32) *ChangeKeyboardControlValues {
2507+ v.Mask |= KbKey
2508+ v.Key = x
2509+ return v
2510+}
2511+func (v *ChangeKeyboardControlValues) SetAutoRepeatMode(x AutoRepeatMode) *ChangeKeyboardControlValues {
2512+ v.Mask |= KbAutoRepeatMode
2513+ v.AutoRepeatMode = x
2514+ return v
2515+}
2516+func ChangeKeyboardControl(b *xturbo.Buf, v *ChangeKeyboardControlValues) xturbo.Seq {
2517+ p, seq := b.Request(102, 0, 4+4*bits.OnesCount32(uint32(v.Mask)))
2518+ if p == nil {
2519+ return 0
2520+ }
2521+ binary.LittleEndian.PutUint32(p[0:], uint32(v.Mask))
2522+ off := 4
2523+ if v.Mask&KbKeyClickPercent != 0 {
2524+ binary.LittleEndian.PutUint32(p[off:], uint32(v.KeyClickPercent))
2525+ off += 4
2526+ }
2527+ if v.Mask&KbBellPercent != 0 {
2528+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BellPercent))
2529+ off += 4
2530+ }
2531+ if v.Mask&KbBellPitch != 0 {
2532+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BellPitch))
2533+ off += 4
2534+ }
2535+ if v.Mask&KbBellDuration != 0 {
2536+ binary.LittleEndian.PutUint32(p[off:], uint32(v.BellDuration))
2537+ off += 4
2538+ }
2539+ if v.Mask&KbLed != 0 {
2540+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Led))
2541+ off += 4
2542+ }
2543+ if v.Mask&KbLedMode != 0 {
2544+ binary.LittleEndian.PutUint32(p[off:], uint32(v.LedMode))
2545+ off += 4
2546+ }
2547+ if v.Mask&KbKey != 0 {
2548+ binary.LittleEndian.PutUint32(p[off:], uint32(v.Key))
2549+ off += 4
2550+ }
2551+ if v.Mask&KbAutoRepeatMode != 0 {
2552+ binary.LittleEndian.PutUint32(p[off:], uint32(v.AutoRepeatMode))
2553+ off += 4
2554+ }
2555+ _ = off
2556+ return seq
2557+}
2558+
1536 func GetKeyboardControl(b *xturbo.Buf) xturbo.Seq {2559 func GetKeyboardControl(b *xturbo.Buf) xturbo.Seq {
1537 p, seq := b.Request(103, 0, 0)2560 p, seq := b.Request(103, 0, 0)
1538 if p == nil {2561 if p == nil {
M xproto/requests_test.go +23 -0
@@ -5,6 +5,29 @@ import (
55 "testing"
66 )
77
8+func BenchmarkConfigureWindow(b *testing.B) {
9+ buf := xturbo.NewBuf(0)
10+ var v ConfigureWindowValues
11+ v.SetX(-1).SetY(-2).SetWidth(800).SetHeight(600).SetBorderWidth(1).SetSibling(2).SetStackMode(StackModeAbove)
12+ batch := 0
13+ b.ReportAllocs()
14+ b.ResetTimer()
15+ for i := 0; i < b.N; i++ {
16+ if batch == 60000 {
17+ b.StopTimer()
18+ buf = xturbo.NewBuf(0)
19+ batch = 0
20+ b.StartTimer()
21+ }
22+ buf.Reset()
23+ ConfigureWindow(buf, 1, &v)
24+ batch++
25+ }
26+ if buf.Err() != nil {
27+ b.Fatal(buf.Err())
28+ }
29+}
30+
831 func BenchmarkMapWindow(b *testing.B) {
932 buf := xturbo.NewBuf(0)
1033 batch := 0
@@ -5,6 +5,29 @@ import (
5 "testing"5 "testing"
6 )6 )
7 7
8+func BenchmarkConfigureWindow(b *testing.B) {
9+ buf := xturbo.NewBuf(0)
10+ var v ConfigureWindowValues
11+ v.SetX(-1).SetY(-2).SetWidth(800).SetHeight(600).SetBorderWidth(1).SetSibling(2).SetStackMode(StackModeAbove)
12+ batch := 0
13+ b.ReportAllocs()
14+ b.ResetTimer()
15+ for i := 0; i < b.N; i++ {
16+ if batch == 60000 {
17+ b.StopTimer()
18+ buf = xturbo.NewBuf(0)
19+ batch = 0
20+ b.StartTimer()
21+ }
22+ buf.Reset()
23+ ConfigureWindow(buf, 1, &v)
24+ batch++
25+ }
26+ if buf.Err() != nil {
27+ b.Fatal(buf.Err())
28+ }
29+}
30+
8 func BenchmarkMapWindow(b *testing.B) {31 func BenchmarkMapWindow(b *testing.B) {
9 buf := xturbo.NewBuf(0)32 buf := xturbo.NewBuf(0)
10 batch := 033 batch := 0

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