package xturbo_test import ( "bytes" "encoding/binary" "testing" "bnema.dev/xturbo" "bnema.dev/xturbo/internal/xtest" "bnema.dev/xturbo/render" "bnema.dev/xturbo/xproto" ) func TestValueRequestGoldens(t *testing.T) { for _, name := range []string{"xproto/ConfigureWindow", "xproto/ConfigureWindowSparse", "xproto/ConfigureWindowAll", "xproto/CreateWindow", "xproto/ChangeWindowAttributes", "render/CreatePicture"} { t.Run(name, func(t *testing.T) { want, err := xtest.LoadHex("testdata/golden/" + name + ".req.hex") if err != nil { t.Fatal(err) } u32 := func(off int) uint32 { return binary.LittleEndian.Uint32(want[off:]) } b := xturbo.NewBuf(0) var seq xturbo.Seq switch name { case "xproto/ConfigureWindow": seq = xproto.ConfigureWindow(b, xproto.Window(u32(4)), &xproto.ConfigureWindowValues{}) case "xproto/ConfigureWindowSparse": var v xproto.ConfigureWindowValues if v.SetStackMode(xproto.StackModeAbove).SetWidth(80).SetX(-7) != &v { t.Fatal("setter chaining") } seq = xproto.ConfigureWindow(b, xproto.Window(u32(4)), &v) case "xproto/ConfigureWindowAll": var v xproto.ConfigureWindowValues v.SetStackMode(xproto.StackModeAbove).SetSibling(xproto.Window(u32(32))).SetBorderWidth(2).SetHeight(72).SetWidth(96).SetY(9).SetX(-3) seq = xproto.ConfigureWindow(b, xproto.Window(u32(4)), &v) case "xproto/CreateWindow": var v xproto.CreateWindowValues v.SetSaveUnder(false).SetOverrideRedirect(true).SetBackgroundPixel(0x123456) seq = xproto.CreateWindow(b, 0, xproto.Window(u32(4)), xproto.Window(u32(8)), 0, 0, 64, 48, 0, xproto.WindowClassInputOutput, 0, &v) case "xproto/ChangeWindowAttributes": var v xproto.ChangeWindowAttributesValues v.SetSaveUnder(true).SetOverrideRedirect(false) seq = xproto.ChangeWindowAttributes(b, xproto.Window(u32(4)), &v) case "render/CreatePicture": var ext xturbo.ExtTable ext.Set(xturbo.ExtRender, want[0], 0, 0) b.Ext = &ext var v render.CreatePictureValues v.SetClipyorigin(7).SetClipxorigin(-5).SetRepeat(render.RepeatNormal) seq = render.CreatePicture(b, render.Picture(u32(4)), xproto.Drawable(u32(8)), render.Pictformat(u32(12)), &v) } if seq != 1 || b.Err() != nil { t.Fatalf("seq=%d err=%v", seq, b.Err()) } if !bytes.Equal(b.Bytes(), want) { t.Fatalf("got %x want %x", b.Bytes(), want) } }) } } func TestAllocValueRequests(t *testing.T) { b := xturbo.NewBuf(0) var ext xturbo.ExtTable ext.Set(xturbo.ExtRender, 139, 0, 0) b.Ext = &ext var v xproto.ConfigureWindowValues v.SetX(-1).SetY(-2).SetWidth(800).SetHeight(600).SetBorderWidth(1).SetSibling(2).SetStackMode(xproto.StackModeAbove) var create xproto.CreateWindowValues create.SetOverrideRedirect(true).SetSaveUnder(false) var change xproto.ChangeWindowAttributesValues change.SetOverrideRedirect(false).SetSaveUnder(true) var pic render.CreatePictureValues pic.SetRepeat(render.RepeatNormal).SetClipxorigin(-1) if n := testing.AllocsPerRun(1000, func() { b.Reset() xproto.ConfigureWindow(b, 1, &v) xproto.CreateWindow(b, 0, 1, 2, 0, 0, 80, 60, 0, xproto.WindowClassInputOutput, 0, &create) xproto.ChangeWindowAttributes(b, 1, &change) render.CreatePicture(b, 1, 1, 1, &pic) }); n != 0 { t.Fatal(n) } if b.Err() != nil { t.Fatal(b.Err()) } } func TestValueRequestFailures(t *testing.T) { b := xturbo.NewBuf(0) b.Fail(xturbo.ErrBadLength) if xproto.ConfigureWindow(b, 1, &xproto.ConfigureWindowValues{}) != 0 || b.Len() != 0 || b.Err() != xturbo.ErrBadLength { t.Fatal("sticky error") } for _, ext := range []*xturbo.ExtTable{nil, {}} { b := xturbo.NewBuf(0) b.Ext = ext if render.CreatePicture(b, 1, 1, 1, &render.CreatePictureValues{}) != 0 || b.Err() != xturbo.ErrExtMissing || b.Len() != 0 { t.Fatal("missing extension") } } }