feat(xtgen): encode typed mask-ordered request value lists
15 files · +1853 -14
M cmd/xtgen/requests.go +31 -11
| @@ -16,30 +16,27 @@ type Request struct { | |||
| 16 | 16 | Node *Node | |
| 17 | 17 | Derived map[string]string | |
| 18 | 18 | 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 | 23 | func resolveRequests(m *Module) ([]Request, error) { | |
| 23 | 24 | var out []Request | |
| 24 | 25 | for _, n := range m.Root.Children { | |
| 25 | 26 | if n.Kind != "request" { | |
| 26 | 27 | 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 | 29 | name := goName(n.Attr["name"]) | |
| 38 | 30 | if err := m.claim(name, n); err != nil { | |
| 39 | 31 | return nil, err | |
| 40 | 32 | } | |
| 41 | 33 | opcode, _ := strconv.Atoi(n.Attr["opcode"]) | |
| 42 | 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 | 40 | refs := map[string]int{} | |
| 44 | 41 | var countRefs func(*Node) | |
| 45 | 42 | countRefs = func(x *Node) { | |
| @@ -66,6 +63,10 @@ func resolveRequests(m *Module) ([]Request, error) { | |||
| 66 | 63 | if n.Kind == "reply" || n.Kind == "doc" { | |
| 67 | 64 | continue | |
| 68 | 65 | } | |
| 66 | + | if n.Kind == "switch" { | |
| 67 | + | r.Params = append(r.Params, Field{Param: "v", GoType: "*" + name + "Values"}) | |
| 68 | + | continue | |
| 69 | + | } | |
| 69 | 70 | f := Field{Name: goName(n.Attr["name"]), Param: paramName(n.Attr["name"]), Kind: n.Kind, Node: n, Off: off - 4} | |
| 70 | 71 | if n.Kind == "pad" { | |
| 71 | 72 | if n.Attr["align"] != "" { | |
| @@ -117,7 +118,11 @@ func resolveRequests(m *Module) ([]Request, error) { | |||
| 117 | 118 | r.Lists = append(r.Lists, f) | |
| 118 | 119 | r.Params = append(r.Params, f) | |
| 119 | 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 | 127 | if n.Kind == "exprfield" { | |
| 123 | 128 | f.Expr = n.Children[0] | |
| @@ -155,6 +160,9 @@ func resolveRequests(m *Module) ([]Request, error) { | |||
| 155 | 160 | } | |
| 156 | 161 | func requestDecl(m *Module, r Request) (string, error) { | |
| 157 | 162 | var b strings.Builder | |
| 163 | + | if r.Values != nil { | |
| 164 | + | b.WriteString(valuesDecl(r.Name, r.Values)) | |
| 165 | + | } | |
| 158 | 166 | fmt.Fprintf(&b, "func %s(b *xturbo.Buf", r.Name) | |
| 159 | 167 | for _, p := range r.Params { | |
| 160 | 168 | fmt.Fprintf(&b, ", %s %s", p.Param, p.GoType) | |
| @@ -222,6 +230,9 @@ func requestDecl(m *Module, r Request) (string, error) { | |||
| 222 | 230 | b.WriteString("size=(size+3)&^3;") | |
| 223 | 231 | body = "size" | |
| 224 | 232 | } | |
| 233 | + | if r.Values != nil { | |
| 234 | + | body += "+4*bits.OnesCount32(uint32(v.Mask))" | |
| 235 | + | } | |
| 225 | 236 | major := fmt.Sprint(r.Opcode) | |
| 226 | 237 | data := "0" | |
| 227 | 238 | if m.ExtName != "" { | |
| @@ -305,6 +316,15 @@ func requestDecl(m *Module, r Request) (string, error) { | |||
| 305 | 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 | 328 | b.WriteString("return seq }\n") | |
| 309 | 329 | return b.String(), nil | |
| 310 | 330 | } | |
| @@ -16,30 +16,27 @@ type Request struct { | |||||
| 16 | Node *Node | 16 | Node *Node | ||
| 17 | Derived map[string]string | 17 | Derived map[string]string | ||
| 18 | Lists []Field | 18 | 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 []Request | 24 | 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 | continue | 27 | 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, err | 31 | 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 | continue | 64 | 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.Builder | 162 | 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(), nil | 329 | 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 @@ | |||
| 1 | 1 | # 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 | 6 | 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 | 15 | Tests read target/opcode from the fixture, not a hard-coded server assignment. | |
| 16 | 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 | 18 | Replies, events and runtime integration belong to their subsequent tasks. | |
| 20 | 19 | ||
| 21 | 20 | T2.4 adds InternAtom, ChangeProperty and XRes QueryClientIds. A GetProperty | |
| 22 | 21 | read-back validates the property contents. XRes's major opcode is negotiated; | |
| 23 | 22 | QueryVersion 1.2 precedes the ClientIdSpec-list query. The capture is independent | |
| 24 | 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. | |
| @@ -1,6 +1,6 @@ | |||||
| 1 | # Wire goldens | 1 | # 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 -update | 6 | 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 GetProperty | 20 | 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 independent | 22 | 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) { | |||
| 207 | 207 | if p := packet(); p[0] != 1 { | |
| 208 | 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 | 299 | // Closing the client drains the request direction; wait before inspecting tee. | |
| 211 | 300 | client.Close() | |
| 212 | 301 | select { | |
| @@ -220,6 +309,7 @@ func TestCaptureRequests(t *testing.T) { | |||
| 220 | 309 | stream := recorded.Bytes() | |
| 221 | 310 | requests := stream[12:] | |
| 222 | 311 | captured := map[string][]byte{} | |
| 312 | + | configIndex := 0 | |
| 223 | 313 | for len(requests) > 0 { | |
| 224 | 314 | size := int(binary.LittleEndian.Uint16(requests[2:])) * 4 | |
| 225 | 315 | if size < 4 || size > len(requests) { | |
| @@ -227,6 +317,16 @@ func TestCaptureRequests(t *testing.T) { | |||
| 227 | 317 | } | |
| 228 | 318 | p := requests[:size] | |
| 229 | 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 | 330 | case 8: | |
| 231 | 331 | captured["xproto/MapWindow"] = p | |
| 232 | 332 | case 14: | |
| @@ -236,6 +336,9 @@ func TestCaptureRequests(t *testing.T) { | |||
| 236 | 336 | case 18: | |
| 237 | 337 | captured["xproto/ChangeProperty"] = p | |
| 238 | 338 | default: | |
| 339 | + | if p[0] == renderMajor && p[1] == 4 { | |
| 340 | + | captured["render/CreatePicture"] = p | |
| 341 | + | } | |
| 239 | 342 | if p[0] == resMajor && p[1] == 4 { | |
| 240 | 343 | captured["res/QueryClientIds"] = p | |
| 241 | 344 | } | |
| @@ -245,7 +348,7 @@ func TestCaptureRequests(t *testing.T) { | |||
| 245 | 348 | } | |
| 246 | 349 | requests = requests[size:] | |
| 247 | 350 | } | |
| 248 | - | if len(captured) != 6 { | |
| 351 | + | if len(captured) != 12 { | |
| 249 | 352 | t.Fatal("missing captured requests") | |
| 250 | 353 | } | |
| 251 | 354 | 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:])) * 4 | 314 | 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"] = p | 331 | 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"] = p | 337 | 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"] = p | 343 | 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 | |||
| 3 | 3 | ||
| 4 | 4 | import "bnema.dev/xturbo/xproto" | |
| 5 | 5 | import "encoding/binary" | |
| 6 | + | import "math/bits" | |
| 6 | 7 | import "bnema.dev/xturbo" | |
| 7 | 8 | ||
| 8 | 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 | 60 | 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 | 375 | func SetPictureClipRectangles(b *xturbo.Buf, picture Picture, clipXOrigin int16, clipYOrigin int16, rectangles []xproto.Rectangle) xturbo.Seq { | |
| 63 | 376 | size := 0 | |
| 64 | 377 | 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 seq | 60 | 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 := 0 | 376 | size := 0 | ||
| 64 | size += 4 | 377 | 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 @@ | |||
| 2 | 2 | package xproto | |
| 3 | 3 | ||
| 4 | 4 | import "encoding/binary" | |
| 5 | + | import "math/bits" | |
| 5 | 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 | 364 | func GetWindowAttributes(b *xturbo.Buf, window Window) xturbo.Seq { | |
| 8 | 365 | p, seq := b.Request(3, 0, 4) | |
| 9 | 366 | if p == nil { | |
| @@ -88,6 +445,92 @@ func UnmapSubwindows(b *xturbo.Buf, window Window) xturbo.Seq { | |||
| 88 | 445 | 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 | 534 | func CirculateWindow(b *xturbo.Buf, direction Circulate, window Window) xturbo.Seq { | |
| 92 | 535 | p, seq := b.Request(13, uint8(int(direction)), 4) | |
| 93 | 536 | if p == nil { | |
| @@ -673,6 +1116,491 @@ func FreePixmap(b *xturbo.Buf, pixmap Pixmap) xturbo.Seq { | |||
| 673 | 1116 | 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 | 1604 | func CopyGC(b *xturbo.Buf, srcGc Gcontext, dstGc Gcontext, valueMask Gc) xturbo.Seq { | |
| 677 | 1605 | p, seq := b.Request(57, 0, 12) | |
| 678 | 1606 | if p == nil { | |
| @@ -1533,6 +2461,101 @@ func GetKeyboardMapping(b *xturbo.Buf, firstKeycode Keycode, count uint8) xturbo | |||
| 1533 | 2461 | 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 | 2559 | func GetKeyboardControl(b *xturbo.Buf) xturbo.Seq { | |
| 1537 | 2560 | p, seq := b.Request(103, 0, 0) | |
| 1538 | 2561 | if p == nil { | |
| @@ -2,8 +2,365 @@ | |||||
| 2 | package xproto | 2 | 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 seq | 445 | 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 seq | 1116 | 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 seq | 2461 | 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 ( | |||
| 5 | 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 | 31 | func BenchmarkMapWindow(b *testing.B) { | |
| 9 | 32 | buf := xturbo.NewBuf(0) | |
| 10 | 33 | 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 := 0 | 33 | batch := 0 | ||