1package xturbo_test
2
3import (
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
14func 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
63func 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
90func 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}