1package wayland
2
3import (
4 "testing"
5
6 cr "github.com/bnema/go-wayland-bindings/server/colorrepresentation"
7 "github.com/bnema/go-wayland-bindings/server/wayland"
8)
9
10func TestColorRepresentationProtocol(t *testing.T) {
11 s, c, _ := colorServer(t)
12 manager := bindProtocol(t, c, "wp_color_representation_manager_v1")
13 events := watchColor(c, manager)
14 if err := c.Roundtrip(); err != nil {
15 t.Fatal(err)
16 }
17 if len(events.events) != 9 || uint32(events.events[len(events.events)-1]) != cr.WpColorRepresentationManagerV1EventDone {
18 t.Fatalf("capabilities %v", events.events)
19 }
20 comp := bindProtocol(t, c, "wl_compositor")
21 wl := c.AllocateID()
22 requestProtocol(t, c, comp, wayland.CompositorRequestCreateSurface, wl)
23 registerProtocol(t, c, wl)
24 obj := c.AllocateID()
25 requestProtocol(t, c, manager, cr.WpColorRepresentationManagerV1RequestGetSurface, obj, wl)
26 registerProtocol(t, c, obj)
27 requestProtocol(t, c, obj, cr.WpColorRepresentationSurfaceV1RequestSetCoefficientsAndRange, uint32(coefficient2020), uint32(rangeLimited))
28 requestProtocol(t, c, obj, cr.WpColorRepresentationSurfaceV1RequestSetChromaLocation, uint32(cr.WpColorRepresentationSurfaceV1ChromaLocationType0))
29 if err := c.Roundtrip(); err != nil {
30 t.Fatal(err)
31 }
32 var before, after surfaceRepresentation
33 s.display.Do(func() {
34 for res, surf := range s.surfaces {
35 if res.ID() == wl {
36 before = surf.representation
37 }
38 }
39 })
40 if before != (surfaceRepresentation{}) {
41 t.Fatalf("applied before commit: %+v", before)
42 }
43 requestProtocol(t, c, wl, wayland.SurfaceRequestCommit)
44 if err := c.Roundtrip(); err != nil {
45 t.Fatal(err)
46 }
47 s.display.Do(func() {
48 for res, surf := range s.surfaces {
49 if res.ID() == wl {
50 after = surf.representation
51 }
52 }
53 })
54 if after.coefficients != coefficient2020 || after.rangeValue != rangeLimited || after.chroma != 1 {
55 t.Fatalf("commit %+v", after)
56 }
57 requestProtocol(t, c, obj, cr.WpColorRepresentationSurfaceV1RequestDestroy)
58 requestProtocol(t, c, wl, wayland.SurfaceRequestCommit)
59 if err := c.Roundtrip(); err != nil {
60 t.Fatal(err)
61 }
62 s.display.Do(func() {
63 for res, surf := range s.surfaces {
64 if res.ID() == wl {
65 after = surf.representation
66 }
67 }
68 })
69 if after != (surfaceRepresentation{}) {
70 t.Fatalf("destroy %+v", after)
71 }
72}
73
74func TestColorRepresentationErrors(t *testing.T) {
75 for _, tc := range []struct {
76 name string
77 op uint32
78 args []any
79 code uint32
80 }{
81 {"alpha", cr.WpColorRepresentationSurfaceV1RequestSetAlphaMode, []any{uint32(2)}, uint32(cr.WpColorRepresentationSurfaceV1ErrorAlphaMode)},
82 {"coefficients", cr.WpColorRepresentationSurfaceV1RequestSetCoefficientsAndRange, []any{uint32(8), uint32(1)}, uint32(cr.WpColorRepresentationSurfaceV1ErrorCoefficients)},
83 {"range", cr.WpColorRepresentationSurfaceV1RequestSetCoefficientsAndRange, []any{uint32(coefficient2020), uint32(3)}, uint32(cr.WpColorRepresentationSurfaceV1ErrorCoefficients)},
84 {"chroma", cr.WpColorRepresentationSurfaceV1RequestSetChromaLocation, []any{uint32(2)}, uint32(cr.WpColorRepresentationSurfaceV1ErrorChromaLocation)},
85 } {
86 t.Run(tc.name, func(t *testing.T) {
87 _, c, _ := colorServer(t)
88 manager := bindProtocol(t, c, "wp_color_representation_manager_v1")
89 registerProtocol(t, c, manager)
90 comp := bindProtocol(t, c, "wl_compositor")
91 wl := c.AllocateID()
92 requestProtocol(t, c, comp, wayland.CompositorRequestCreateSurface, wl)
93 registerProtocol(t, c, wl)
94 obj := c.AllocateID()
95 requestProtocol(t, c, manager, cr.WpColorRepresentationManagerV1RequestGetSurface, obj, wl)
96 registerProtocol(t, c, obj)
97 requestProtocol(t, c, obj, tc.op, tc.args...)
98 expectProtocolError(t, c, obj, tc.code)
99 })
100 }
101}
102
103// A queued commit snapshots representation; later requests must not rewrite it.
104func TestColorRepresentationQueuedCommit(t *testing.T) {
105 s, c, _ := colorServer(t)
106 manager := bindProtocol(t, c, "wp_color_representation_manager_v1")
107 registerProtocol(t, c, manager)
108 comp := bindProtocol(t, c, "wl_compositor")
109 registerProtocol(t, c, comp)
110 wl := c.AllocateID()
111 requestProtocol(t, c, comp, wayland.CompositorRequestCreateSurface, wl)
112 registerProtocol(t, c, wl)
113 obj := c.AllocateID()
114 requestProtocol(t, c, manager, cr.WpColorRepresentationManagerV1RequestGetSurface, obj, wl)
115 registerProtocol(t, c, obj)
116 requestProtocol(t, c, obj, cr.WpColorRepresentationSurfaceV1RequestSetCoefficientsAndRange, uint32(coefficient709), uint32(rangeLimited))
117 if err := c.Roundtrip(); err != nil {
118 t.Fatal(err)
119 }
120 s.display.Do(func() {
121 for res, surf := range s.surfaces {
122 if res.ID() == wl {
123 surf.queueUpdate()
124 }
125 }
126 })
127 requestProtocol(t, c, obj, cr.WpColorRepresentationSurfaceV1RequestSetCoefficientsAndRange, uint32(coefficient2020), uint32(rangeFull))
128 if err := c.Roundtrip(); err != nil {
129 t.Fatal(err)
130 }
131 s.display.Do(func() {
132 for res, surf := range s.surfaces {
133 if res.ID() != wl {
134 continue
135 }
136 // The pacer may have already applied the queued update.
137 if len(surf.queue) == 1 {
138 if surf.queue[0].representation.coefficients != coefficient709 {
139 t.Errorf("queued representation: %+v", surf.queue[0].representation)
140 }
141 u := surf.queue[0]
142 surf.queue = nil
143 surf.applyUpdate(u)
144 }
145 if surf.representation.coefficients != coefficient709 || surf.next.representation.coefficients != coefficient2020 {
146 t.Errorf("applied=%+v pending=%+v", surf.representation, surf.next.representation)
147 }
148 }
149 })
150}
151
152// A representation-only commit is checked against the buffer of the last
153// queued commit, not the applied one it will not keep.
154func TestColorRepresentationChecksQueuedBuffer(t *testing.T) {
155 s, c, _ := colorServer(t)
156 manager := bindProtocol(t, c, "wp_color_representation_manager_v1")
157 registerProtocol(t, c, manager)
158 comp := bindProtocol(t, c, "wl_compositor")
159 registerProtocol(t, c, comp)
160 wl := c.AllocateID()
161 requestProtocol(t, c, comp, wayland.CompositorRequestCreateSurface, wl)
162 registerProtocol(t, c, wl)
163 obj := c.AllocateID()
164 requestProtocol(t, c, manager, cr.WpColorRepresentationManagerV1RequestGetSurface, obj, wl)
165 registerProtocol(t, c, obj)
166 buf := shmBuffer(t, c)
167 requestProtocol(t, c, wl, wayland.SurfaceRequestAttach, buf, int32(0), int32(0))
168 if err := c.Roundtrip(); err != nil {
169 t.Fatal(err)
170 }
171 s.display.Do(func() {
172 for res, surf := range s.surfaces {
173 if res.ID() != wl {
174 continue
175 }
176 // The RGB commit waits in the queue; the next one only sets
177 // YUV coefficients.
178 surf.queueUpdate()
179 surf.next.representation.coefficients = coefficient709
180 if surf.checkRepresentationCommit() {
181 t.Error("YUV coefficients accepted for a queued RGB buffer")
182 }
183 }
184 })
185}
186
187func TestColorRepresentationRejectsRGBWithYUVCoefficients(t *testing.T) {
188 _, c, _ := colorServer(t)
189 manager := bindProtocol(t, c, "wp_color_representation_manager_v1")
190 registerProtocol(t, c, manager)
191 comp := bindProtocol(t, c, "wl_compositor")
192 registerProtocol(t, c, comp)
193 wl := c.AllocateID()
194 requestProtocol(t, c, comp, wayland.CompositorRequestCreateSurface, wl)
195 registerProtocol(t, c, wl)
196 obj := c.AllocateID()
197 requestProtocol(t, c, manager, cr.WpColorRepresentationManagerV1RequestGetSurface, obj, wl)
198 registerProtocol(t, c, obj)
199 buf := shmBuffer(t, c)
200 requestProtocol(t, c, wl, wayland.SurfaceRequestAttach, buf, int32(0), int32(0))
201 requestProtocol(t, c, obj, cr.WpColorRepresentationSurfaceV1RequestSetCoefficientsAndRange, uint32(coefficient709), uint32(rangeLimited))
202 requestProtocol(t, c, wl, wayland.SurfaceRequestCommit)
203 expectProtocolError(t, c, obj, uint32(cr.WpColorRepresentationSurfaceV1ErrorPixelFormat))
204}