v0.4.0 b6be3a8

colorrepresentation.go RawHistoryFolder

1package wayland
2
3import (
4	"github.com/bnema/go-wayland-bindings/server/colorrepresentation"
5	"github.com/bnema/go-wayland-bindings/server/wayland"
6	"github.com/bnema/purego-libwayland/server"
7)
8
9// The absent YUV representation defaults to BT.709 limited, type 0 chroma.
10// RGB without a representation retains premultiplied electrical samples.
11type surfaceRepresentation struct{ coefficients, rangeValue, chroma, alpha uint8 }
12
13const (
14	coefficientIdentity = uint8(colorrepresentation.WpColorRepresentationSurfaceV1CoefficientsIdentity)
15	coefficient709      = uint8(colorrepresentation.WpColorRepresentationSurfaceV1CoefficientsBt709)
16	coefficient601      = uint8(colorrepresentation.WpColorRepresentationSurfaceV1CoefficientsBt601)
17	coefficient2020     = uint8(colorrepresentation.WpColorRepresentationSurfaceV1CoefficientsBt2020)
18	rangeFull           = uint8(colorrepresentation.WpColorRepresentationSurfaceV1RangeFull)
19	rangeLimited        = uint8(colorrepresentation.WpColorRepresentationSurfaceV1RangeLimited)
20)
21
22func isYUV(format uint32) bool { return format == fourccNV12 || format == fourccP010 }
23
24func registerColorRepresentation(d *server.Display, s *Server) error {
25	return colorrepresentation.NewWpColorRepresentationManagerV1Global(d, 1, func(c server.Client, v, id uint32) {
26		r, err := colorrepresentation.NewWpColorRepresentationManagerV1(c, int32(v), id, representationManager{s})
27		if err != nil {
28			return
29		}
30		r.SendSupportedAlphaMode(uint32(colorrepresentation.WpColorRepresentationSurfaceV1AlphaModePremultipliedElectrical))
31		r.SendSupportedCoefficientsAndRanges(uint32(coefficientIdentity), uint32(rangeFull))
32		for _, coeff := range []uint8{coefficient601, coefficient709, coefficient2020} {
33			for _, ran := range []uint8{rangeLimited, rangeFull} {
34				r.SendSupportedCoefficientsAndRanges(uint32(coeff), uint32(ran))
35			}
36		}
37		r.SendDone()
38	})
39}
40
41type representationManager struct{ server *Server }
42
43func (representationManager) Destroy(*colorrepresentation.WpColorRepresentationManagerV1) {}
44func (m representationManager) GetSurface(r *colorrepresentation.WpColorRepresentationManagerV1, id uint32, wl *wayland.Surface) {
45	surf := m.server.surfaceOf(wl)
46	if surf != nil && surf.representationControl != nil {
47		r.PostError(uint32(colorrepresentation.WpColorRepresentationManagerV1ErrorSurfaceExists), "surface already has color representation")
48		return
49	}
50	h := &representationSurface{surf: surf}
51	res, err := colorrepresentation.NewWpColorRepresentationSurfaceV1(r.Client(), r.Version(), id, h)
52	if err != nil {
53		return
54	}
55	h.res = res
56	if surf != nil {
57		surf.representationControl = h
58		res.OnDestroy = func() {
59			if surf.representationControl == h {
60				surf.representationControl = nil
61				surf.next.representation = surfaceRepresentation{}
62			}
63		}
64	}
65}
66
67type representationSurface struct {
68	surf *surface
69	res  *colorrepresentation.WpColorRepresentationSurfaceV1
70}
71
72func (h *representationSurface) Destroy(*colorrepresentation.WpColorRepresentationSurfaceV1) {
73	if h.surf != nil && !h.surf.destroyed {
74		h.surf.next.representation = surfaceRepresentation{}
75	}
76}
77func (h *representationSurface) live(r *colorrepresentation.WpColorRepresentationSurfaceV1) bool {
78	if h.surf == nil || h.surf.destroyed {
79		r.PostError(uint32(colorrepresentation.WpColorRepresentationSurfaceV1ErrorInert), "surface destroyed")
80		return false
81	}
82	return true
83}
84func (h *representationSurface) SetAlphaMode(r *colorrepresentation.WpColorRepresentationSurfaceV1, mode uint32) {
85	if !h.live(r) {
86		return
87	}
88	if mode != uint32(colorrepresentation.WpColorRepresentationSurfaceV1AlphaModePremultipliedElectrical) {
89		r.PostError(uint32(colorrepresentation.WpColorRepresentationSurfaceV1ErrorAlphaMode), "unsupported alpha mode")
90		return
91	}
92	h.surf.next.representation.alpha = uint8(mode)
93}
94func (h *representationSurface) SetCoefficientsAndRange(r *colorrepresentation.WpColorRepresentationSurfaceV1, coeff, ran uint32) {
95	if !h.live(r) {
96		return
97	}
98	valid := coeff == uint32(coefficientIdentity) && ran == uint32(rangeFull) ||
99		(coeff == uint32(coefficient601) || coeff == uint32(coefficient709) || coeff == uint32(coefficient2020)) && (ran == uint32(rangeFull) || ran == uint32(rangeLimited))
100	if !valid {
101		r.PostError(uint32(colorrepresentation.WpColorRepresentationSurfaceV1ErrorCoefficients), "unsupported coefficients or range")
102		return
103	}
104	h.surf.next.representation.coefficients, h.surf.next.representation.rangeValue = uint8(coeff), uint8(ran)
105}
106func (h *representationSurface) SetChromaLocation(r *colorrepresentation.WpColorRepresentationSurfaceV1, chroma uint32) {
107	if !h.live(r) {
108		return
109	}
110	if chroma != uint32(colorrepresentation.WpColorRepresentationSurfaceV1ChromaLocationType0) {
111		r.PostError(uint32(colorrepresentation.WpColorRepresentationSurfaceV1ErrorChromaLocation), "unsupported chroma location")
112		return
113	}
114	h.surf.next.representation.chroma = uint8(chroma)
115}
116
117// The metadata is checked against the buffer the commit will show,
118// including when a client changes representation without attaching a new
119// buffer: then the one of the last queued commit that attached, or the
120// current one.
121func (s *surface) checkRepresentationCommit() bool {
122	rep := s.next.representation
123	if rep.coefficients == 0 && rep.chroma == 0 {
124		return true
125	}
126	buffer := s.current
127	for i := len(s.queue) - 1; i >= 0; i-- {
128		if s.queue[i].attached {
129			buffer = s.queue[i].buffer
130			break
131		}
132	}
133	if s.next.attached {
134		buffer = s.next.buffer
135	}
136	if buffer == nil {
137		return true
138	}
139	b, ok := s.server.buffers[buffer.Resource]
140	if !ok {
141		return true
142	}
143	d, ok := b.(*dmabufBuffer)
144	yuv := ok && isYUV(d.buf.Format)
145	bad := rep.coefficients != 0 && (rep.coefficients == coefficientIdentity) == yuv || rep.chroma != 0 && !yuv
146	if bad && s.representationControl != nil && s.representationControl.res != nil {
147		s.representationControl.res.PostError(uint32(colorrepresentation.WpColorRepresentationSurfaceV1ErrorPixelFormat), "color representation incompatible with pixel format")
148		return false
149	}
150	return true
151}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 25

Tags 10

↑↓ moveenter openesc close