feat(spec): vendor 64 upstream protocols and add wlbsync
- commit
- 40c4f8d6f8ca70c1f5d5cd51adc3cebe8978110c
- author
- brice · · 2026-10-01 03:37 UTC
- parent
- 20a3136
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
75 files · +21467 -2
A cmd/wlbsync/git.go +189 -0
| @@ -0,0 +1,189 @@ | |||||
| 1 | + | package main | |||
| 2 | + | ||||
| 3 | + | import ( | |||
| 4 | + | "bytes" | |||
| 5 | + | "context" | |||
| 6 | + | "fmt" | |||
| 7 | + | "os" | |||
| 8 | + | "os/exec" | |||
| 9 | + | "regexp" | |||
| 10 | + | "strings" | |||
| 11 | + | "time" | |||
| 12 | + | ) | |||
| 13 | + | ||||
| 14 | + | // Fetcher is the network/git boundary of wlbsync. | |||
| 15 | + | type Fetcher interface { | |||
| 16 | + | // Resolve returns the ref and commit for src. An empty pin selects the | |||
| 17 | + | // default ref of the source (latest tag or branch HEAD); otherwise pin is | |||
| 18 | + | // a tag, a branch, or a 40-hex commit. | |||
| 19 | + | Resolve(src upstream, pin string) (ref, commit string, err error) | |||
| 20 | + | // Checkout materialises commit of src (reached through ref) in the empty | |||
| 21 | + | // directory dir. | |||
| 22 | + | Checkout(src upstream, ref, commit, dir string) error | |||
| 23 | + | } | |||
| 24 | + | ||||
| 25 | + | var fullSHA = regexp.MustCompile(`^[0-9a-f]{40}$`) | |||
| 26 | + | ||||
| 27 | + | // gitFetcher implements Fetcher with the git command line. | |||
| 28 | + | type gitFetcher struct{} | |||
| 29 | + | ||||
| 30 | + | const gitTimeout = 5 * time.Minute | |||
| 31 | + | ||||
| 32 | + | func git(dir string, args ...string) (string, error) { | |||
| 33 | + | ctx, cancel := context.WithTimeout(context.Background(), gitTimeout) | |||
| 34 | + | defer cancel() | |||
| 35 | + | cmd := exec.CommandContext(ctx, "git", args...) | |||
| 36 | + | cmd.Dir = dir | |||
| 37 | + | cmd.Env = append(os.Environ(), "GIT_TERMINAL_PROMPT=0") | |||
| 38 | + | var stdout, stderr bytes.Buffer | |||
| 39 | + | cmd.Stdout, cmd.Stderr = &stdout, &stderr | |||
| 40 | + | if err := cmd.Run(); err != nil { | |||
| 41 | + | return "", fmt.Errorf("git %s: %w: %s", strings.Join(args, " "), err, strings.TrimSpace(stderr.String())) | |||
| 42 | + | } | |||
| 43 | + | return strings.TrimSpace(stdout.String()), nil | |||
| 44 | + | } | |||
| 45 | + | ||||
| 46 | + | // lsRemote lists the tags (peeled to commits) and branches of url. | |||
| 47 | + | func lsRemote(url string) (tags, heads map[string]string, err error) { | |||
| 48 | + | out, err := git("", "ls-remote", "--tags", "--heads", url) | |||
| 49 | + | if err != nil { | |||
| 50 | + | return nil, nil, err | |||
| 51 | + | } | |||
| 52 | + | tags, heads = parseLsRemote(out) | |||
| 53 | + | return tags, heads, nil | |||
| 54 | + | } | |||
| 55 | + | ||||
| 56 | + | // parseLsRemote parses `git ls-remote --tags --heads` output. Annotated tags | |||
| 57 | + | // report the tag object and a peeled "^{}" line; the peeled commit wins. | |||
| 58 | + | func parseLsRemote(out string) (tags, heads map[string]string) { | |||
| 59 | + | tags, heads = map[string]string{}, map[string]string{} | |||
| 60 | + | for _, line := range strings.Split(out, "\n") { | |||
| 61 | + | sha, name, ok := strings.Cut(strings.TrimSpace(line), "\t") | |||
| 62 | + | if !ok { | |||
| 63 | + | continue | |||
| 64 | + | } | |||
| 65 | + | switch { | |||
| 66 | + | case strings.HasPrefix(name, "refs/tags/"): | |||
| 67 | + | tag := strings.TrimPrefix(name, "refs/tags/") | |||
| 68 | + | if t, peeled := strings.CutSuffix(tag, "^{}"); peeled { | |||
| 69 | + | tags[t] = sha | |||
| 70 | + | } else if _, seen := tags[t]; !seen { | |||
| 71 | + | tags[t] = sha | |||
| 72 | + | } | |||
| 73 | + | case strings.HasPrefix(name, "refs/heads/"): | |||
| 74 | + | heads[strings.TrimPrefix(name, "refs/heads/")] = sha | |||
| 75 | + | } | |||
| 76 | + | } | |||
| 77 | + | return tags, heads | |||
| 78 | + | } | |||
| 79 | + | ||||
| 80 | + | // latestTag returns the highest tag of src accepted by its tag filters. | |||
| 81 | + | func latestTag(src upstream, tags map[string]string) (string, error) { | |||
| 82 | + | best := "" | |||
| 83 | + | for t := range tags { | |||
| 84 | + | if src.TagRe != nil && !src.TagRe.MatchString(t) { | |||
| 85 | + | continue | |||
| 86 | + | } | |||
| 87 | + | if src.TagOK != nil && !src.TagOK(t) { | |||
| 88 | + | continue | |||
| 89 | + | } | |||
| 90 | + | if best == "" || compareVersions(t, best) > 0 { | |||
| 91 | + | best = t | |||
| 92 | + | } | |||
| 93 | + | } | |||
| 94 | + | if best == "" { | |||
| 95 | + | return "", fmt.Errorf("%s: no tag matches the release pattern", src.ID) | |||
| 96 | + | } | |||
| 97 | + | return best, nil | |||
| 98 | + | } | |||
| 99 | + | ||||
| 100 | + | // Resolve implements Fetcher. | |||
| 101 | + | func (gitFetcher) Resolve(src upstream, pin string) (string, string, error) { | |||
| 102 | + | if fullSHA.MatchString(pin) { | |||
| 103 | + | if src.Kind == PinBranch { | |||
| 104 | + | return src.Branch, pin, nil // recorded as the branch, at the pinned commit | |||
| 105 | + | } | |||
| 106 | + | return pin, pin, nil | |||
| 107 | + | } | |||
| 108 | + | tags, heads, err := lsRemote(src.URL) | |||
| 109 | + | if err != nil { | |||
| 110 | + | return "", "", fmt.Errorf("%s: %w", src.ID, err) | |||
| 111 | + | } | |||
| 112 | + | if src.Kind == PinBranch { | |||
| 113 | + | branch := src.Branch | |||
| 114 | + | if pin != "" { | |||
| 115 | + | branch = pin | |||
| 116 | + | } | |||
| 117 | + | sha, ok := heads[branch] | |||
| 118 | + | if !ok { | |||
| 119 | + | return "", "", fmt.Errorf("%s: branch %q not found", src.ID, branch) | |||
| 120 | + | } | |||
| 121 | + | return branch, sha, nil | |||
| 122 | + | } | |||
| 123 | + | ref := pin | |||
| 124 | + | if ref == "" { | |||
| 125 | + | if ref, err = latestTag(src, tags); err != nil { | |||
| 126 | + | return "", "", err | |||
| 127 | + | } | |||
| 128 | + | } | |||
| 129 | + | sha, ok := tags[ref] | |||
| 130 | + | if !ok { | |||
| 131 | + | return "", "", fmt.Errorf("%s: tag %q not found", src.ID, ref) | |||
| 132 | + | } | |||
| 133 | + | return ref, sha, nil | |||
| 134 | + | } | |||
| 135 | + | ||||
| 136 | + | // Checkout implements Fetcher: a shallow clone of the tag or branch, falling | |||
| 137 | + | // back to a shallow fetch of the commit when the branch moved past a pinned | |||
| 138 | + | // commit or the ref is itself a commit. HEAD is verified against commit. | |||
| 139 | + | func (gitFetcher) Checkout(src upstream, ref, commit, dir string) error { | |||
| 140 | + | if !fullSHA.MatchString(ref) { | |||
| 141 | + | _, err := git("", "clone", "-q", "--depth", "1", "--branch", ref, src.URL, dir) | |||
| 142 | + | if err != nil { | |||
| 143 | + | return fmt.Errorf("%s: %w", src.ID, err) | |||
| 144 | + | } | |||
| 145 | + | if verifyHead(src, dir, commit) == nil { | |||
| 146 | + | return nil | |||
| 147 | + | } | |||
| 148 | + | if src.Kind != PinBranch { | |||
| 149 | + | return verifyHead(src, dir, commit) | |||
| 150 | + | } | |||
| 151 | + | // The branch moved since the commit was resolved or pinned. | |||
| 152 | + | if err := os.RemoveAll(dir); err != nil { | |||
| 153 | + | return err | |||
| 154 | + | } | |||
| 155 | + | if err := os.MkdirAll(dir, 0o755); err != nil { | |||
| 156 | + | return err | |||
| 157 | + | } | |||
| 158 | + | } | |||
| 159 | + | if err := checkoutCommit(src.URL, commit, dir); err != nil { | |||
| 160 | + | return fmt.Errorf("%s: %w", src.ID, err) | |||
| 161 | + | } | |||
| 162 | + | return nil | |||
| 163 | + | } | |||
| 164 | + | ||||
| 165 | + | func checkoutCommit(url, commit, dir string) error { | |||
| 166 | + | steps := [][]string{ | |||
| 167 | + | {"init", "-q"}, | |||
| 168 | + | {"remote", "add", "origin", url}, | |||
| 169 | + | {"fetch", "-q", "--depth", "1", "origin", commit}, | |||
| 170 | + | {"-c", "advice.detachedHead=false", "checkout", "-q", "FETCH_HEAD"}, | |||
| 171 | + | } | |||
| 172 | + | for _, s := range steps { | |||
| 173 | + | if _, err := git(dir, s...); err != nil { | |||
| 174 | + | return err | |||
| 175 | + | } | |||
| 176 | + | } | |||
| 177 | + | return verifyHead(upstream{ID: url}, dir, commit) | |||
| 178 | + | } | |||
| 179 | + | ||||
| 180 | + | func verifyHead(src upstream, dir, commit string) error { | |||
| 181 | + | head, err := git(dir, "rev-parse", "HEAD") | |||
| 182 | + | if err != nil { | |||
| 183 | + | return err | |||
| 184 | + | } | |||
| 185 | + | if head != commit { | |||
| 186 | + | return fmt.Errorf("%s: checked out %s, expected %s (ref moved during sync?)", src.ID, head, commit) | |||
| 187 | + | } | |||
| 188 | + | return nil | |||
| 189 | + | } | |||
A cmd/wlbsync/git_test.go +101 -0
| @@ -0,0 +1,101 @@ | |||||
| 1 | + | package main | |||
| 2 | + | ||||
| 3 | + | import ( | |||
| 4 | + | "os" | |||
| 5 | + | "os/exec" | |||
| 6 | + | "path/filepath" | |||
| 7 | + | "testing" | |||
| 8 | + | ) | |||
| 9 | + | ||||
| 10 | + | // TestGitFetcherLocal exercises the real git implementation against a local | |||
| 11 | + | // repository; no network is involved. | |||
| 12 | + | func TestGitFetcherLocal(t *testing.T) { | |||
| 13 | + | if _, err := exec.LookPath("git"); err != nil { | |||
| 14 | + | t.Skip("git not installed") | |||
| 15 | + | } | |||
| 16 | + | repo := t.TempDir() | |||
| 17 | + | run := func(args ...string) string { | |||
| 18 | + | t.Helper() | |||
| 19 | + | out, err := git(repo, append([]string{ | |||
| 20 | + | "-c", "user.name=t", "-c", "user.email=t@example.com", "-c", "commit.gpgsign=false", "-c", "tag.gpgsign=false", | |||
| 21 | + | }, args...)...) | |||
| 22 | + | if err != nil { | |||
| 23 | + | t.Fatal(err) | |||
| 24 | + | } | |||
| 25 | + | return out | |||
| 26 | + | } | |||
| 27 | + | run("init", "-q", "-b", "master") | |||
| 28 | + | if err := os.MkdirAll(filepath.Join(repo, "protocol"), 0o755); err != nil { | |||
| 29 | + | t.Fatal(err) | |||
| 30 | + | } | |||
| 31 | + | write := func(content string) { | |||
| 32 | + | if err := os.WriteFile(filepath.Join(repo, "protocol", "wayland.xml"), []byte(content), 0o644); err != nil { | |||
| 33 | + | t.Fatal(err) | |||
| 34 | + | } | |||
| 35 | + | } | |||
| 36 | + | write("one") | |||
| 37 | + | run("add", ".") | |||
| 38 | + | run("commit", "-q", "-m", "one") | |||
| 39 | + | first := run("rev-parse", "HEAD") | |||
| 40 | + | run("tag", "-a", "-m", "release", "1.0.0") // annotated: tag object != commit | |||
| 41 | + | write("two") | |||
| 42 | + | run("commit", "-q", "-am", "two") | |||
| 43 | + | second := run("rev-parse", "HEAD") | |||
| 44 | + | run("tag", "1.2.0") // lightweight | |||
| 45 | + | run("tag", "1.3.1") // odd minor, patch < 90: accepted | |||
| 46 | + | run("tag", "1.5.90") | |||
| 47 | + | run("tag", "not-a-version") | |||
| 48 | + | ||||
| 49 | + | src := upstream{ | |||
| 50 | + | ID: "t", URL: repo, Kind: PinTag, TagRe: tagThreeParts, TagOK: waylandTagOK, | |||
| 51 | + | Match: exactly(Stable, "protocol/wayland.xml"), | |||
| 52 | + | } | |||
| 53 | + | var f gitFetcher | |||
| 54 | + | ||||
| 55 | + | ref, commit, err := f.Resolve(src, "") | |||
| 56 | + | if err != nil || ref != "1.3.1" || commit != second { | |||
| 57 | + | t.Fatalf("latest = %q %q, %v; want 1.3.1 %s", ref, commit, err, second) | |||
| 58 | + | } | |||
| 59 | + | _, commit, err = f.Resolve(src, "1.0.0") | |||
| 60 | + | if err != nil || commit != first { | |||
| 61 | + | t.Fatalf("annotated tag resolved to %q (%v), want peeled commit %s", commit, err, first) | |||
| 62 | + | } | |||
| 63 | + | if _, _, err := f.Resolve(src, "9.9.9"); err == nil { | |||
| 64 | + | t.Error("expected error for missing tag") | |||
| 65 | + | } | |||
| 66 | + | ||||
| 67 | + | check := func(src upstream, ref, commit, want string) { | |||
| 68 | + | t.Helper() | |||
| 69 | + | dir := t.TempDir() | |||
| 70 | + | if err := f.Checkout(src, ref, commit, dir); err != nil { | |||
| 71 | + | t.Fatal(err) | |||
| 72 | + | } | |||
| 73 | + | b, err := os.ReadFile(filepath.Join(dir, "protocol", "wayland.xml")) | |||
| 74 | + | if err != nil || string(b) != want { | |||
| 75 | + | t.Errorf("content = %q, %v; want %q", b, err, want) | |||
| 76 | + | } | |||
| 77 | + | } | |||
| 78 | + | check(src, "1.0.0", first, "one") | |||
| 79 | + | check(src, "1.2.0", second, "two") | |||
| 80 | + | ||||
| 81 | + | // Branch source: HEAD of the branch, then a pinned older commit. | |||
| 82 | + | branch := upstream{ID: "b", URL: repo, Kind: PinBranch, Branch: "master", Match: src.Match} | |||
| 83 | + | ref, commit, err = f.Resolve(branch, "") | |||
| 84 | + | if err != nil || ref != "master" || commit != second { | |||
| 85 | + | t.Fatalf("branch = %q %q, %v", ref, commit, err) | |||
| 86 | + | } | |||
| 87 | + | check(branch, ref, commit, "two") | |||
| 88 | + | ref, commit, err = f.Resolve(branch, first) | |||
| 89 | + | if err != nil || ref != "master" || commit != first { | |||
| 90 | + | t.Fatalf("pinned branch = %q %q, %v", ref, commit, err) | |||
| 91 | + | } | |||
| 92 | + | // Branch moved past the pinned commit: falls back to fetching the commit. | |||
| 93 | + | // (Local repos need uploadpack.allowAnySHA1InWant for non-tip commits.) | |||
| 94 | + | run("config", "uploadpack.allowAnySHA1InWant", "true") | |||
| 95 | + | check(branch, ref, commit, "one") | |||
| 96 | + | ||||
| 97 | + | // A mismatching commit is rejected. | |||
| 98 | + | if err := f.Checkout(src, "1.0.0", second, t.TempDir()); err == nil { | |||
| 99 | + | t.Error("expected error when checkout does not match resolved commit") | |||
| 100 | + | } | |||
| 101 | + | } | |||
A cmd/wlbsync/main.go +114 -0
| @@ -0,0 +1,114 @@ | |||||
| 1 | + | // Command wlbsync vendors upstream Wayland protocol XML into spec/ and writes | |||
| 2 | + | // spec/manifest.json. | |||
| 3 | + | // | |||
| 4 | + | // Usage: | |||
| 5 | + | // | |||
| 6 | + | // wlbsync [-root DIR] [-check] [-notes FILE] [-pin-file FILE] | |||
| 7 | + | // | |||
| 8 | + | // With -check nothing under spec/ is written; the program prints | |||
| 9 | + | // "changed=true" or "changed=false". With -notes, Markdown release notes | |||
| 10 | + | // describing the difference to the current spec are written to FILE. | |||
| 11 | + | // -pin-file reads a JSON object {"<source id>": "<tag|branch|40-hex commit>"} | |||
| 12 | + | // overriding the default ref of each listed source. | |||
| 13 | + | package main | |||
| 14 | + | ||||
| 15 | + | import ( | |||
| 16 | + | "encoding/json" | |||
| 17 | + | "flag" | |||
| 18 | + | "fmt" | |||
| 19 | + | "io" | |||
| 20 | + | "os" | |||
| 21 | + | ) | |||
| 22 | + | ||||
| 23 | + | type options struct { | |||
| 24 | + | root string | |||
| 25 | + | check bool | |||
| 26 | + | notes string | |||
| 27 | + | pinFile string | |||
| 28 | + | } | |||
| 29 | + | ||||
| 30 | + | func main() { | |||
| 31 | + | var o options | |||
| 32 | + | flag.StringVar(&o.root, "root", ".", "repository root containing spec/") | |||
| 33 | + | flag.BoolVar(&o.check, "check", false, "do not write spec/; print changed=true|false") | |||
| 34 | + | flag.StringVar(&o.notes, "notes", "", "write Markdown release notes to `FILE`") | |||
| 35 | + | flag.StringVar(&o.pinFile, "pin-file", "", "JSON file mapping source id to the ref to use") | |||
| 36 | + | flag.Parse() | |||
| 37 | + | if flag.NArg() != 0 { | |||
| 38 | + | fmt.Fprintln(os.Stderr, "wlbsync: unexpected arguments") | |||
| 39 | + | os.Exit(2) | |||
| 40 | + | } | |||
| 41 | + | if err := run(o, defaultSources(), gitFetcher{}, os.Stdout); err != nil { | |||
| 42 | + | fmt.Fprintln(os.Stderr, "wlbsync:", err) | |||
| 43 | + | os.Exit(1) | |||
| 44 | + | } | |||
| 45 | + | } | |||
| 46 | + | ||||
| 47 | + | func loadPins(file string, srcs []upstream) (map[string]string, error) { | |||
| 48 | + | pins := map[string]string{} | |||
| 49 | + | if file == "" { | |||
| 50 | + | return pins, nil | |||
| 51 | + | } | |||
| 52 | + | b, err := os.ReadFile(file) | |||
| 53 | + | if err != nil { | |||
| 54 | + | return nil, err | |||
| 55 | + | } | |||
| 56 | + | if err := json.Unmarshal(b, &pins); err != nil { | |||
| 57 | + | return nil, fmt.Errorf("decode %s: %w", file, err) | |||
| 58 | + | } | |||
| 59 | + | known := map[string]bool{} | |||
| 60 | + | for _, s := range srcs { | |||
| 61 | + | known[s.ID] = true | |||
| 62 | + | } | |||
| 63 | + | for id := range pins { | |||
| 64 | + | if !known[id] { | |||
| 65 | + | return nil, fmt.Errorf("%s: unknown source %q", file, id) | |||
| 66 | + | } | |||
| 67 | + | } | |||
| 68 | + | return pins, nil | |||
| 69 | + | } | |||
| 70 | + | ||||
| 71 | + | func run(o options, srcs []upstream, f Fetcher, stdout io.Writer) error { | |||
| 72 | + | pins, err := loadPins(o.pinFile, srcs) | |||
| 73 | + | if err != nil { | |||
| 74 | + | return err | |||
| 75 | + | } | |||
| 76 | + | cur, err := readState(o.root) | |||
| 77 | + | if err != nil { | |||
| 78 | + | return err | |||
| 79 | + | } | |||
| 80 | + | curParsed, err := parseOld(cur) | |||
| 81 | + | if err != nil { | |||
| 82 | + | return err | |||
| 83 | + | } | |||
| 84 | + | sources, cands, err := collect(srcs, pins, f) | |||
| 85 | + | if err != nil { | |||
| 86 | + | return err | |||
| 87 | + | } | |||
| 88 | + | t, err := build(sources, cands) | |||
| 89 | + | if err != nil { | |||
| 90 | + | return err | |||
| 91 | + | } | |||
| 92 | + | manifest, err := t.manifest.Marshal() | |||
| 93 | + | if err != nil { | |||
| 94 | + | return err | |||
| 95 | + | } | |||
| 96 | + | changed := cur.differs(t, manifest) | |||
| 97 | + | ||||
| 98 | + | if o.notes != "" { | |||
| 99 | + | n, err := diff(cur, curParsed, t) | |||
| 100 | + | if err != nil { | |||
| 101 | + | return err | |||
| 102 | + | } | |||
| 103 | + | if err := os.WriteFile(o.notes, []byte(n.markdown()), 0o644); err != nil { | |||
| 104 | + | return err | |||
| 105 | + | } | |||
| 106 | + | } | |||
| 107 | + | if changed && !o.check { | |||
| 108 | + | if err := write(o.root, cur, t, manifest); err != nil { | |||
| 109 | + | return err | |||
| 110 | + | } | |||
| 111 | + | } | |||
| 112 | + | _, err = fmt.Fprintf(stdout, "changed=%t\n", changed) | |||
| 113 | + | return err | |||
| 114 | + | } | |||
A cmd/wlbsync/notes.go +215 -0
| @@ -0,0 +1,215 @@ | |||||
| 1 | + | package main | |||
| 2 | + | ||||
| 3 | + | import ( | |||
| 4 | + | "fmt" | |||
| 5 | + | "sort" | |||
| 6 | + | "strings" | |||
| 7 | + | ||||
| 8 | + | "github.com/bnema/go-wayland-bindings/spec" | |||
| 9 | + | ) | |||
| 10 | + | ||||
| 11 | + | // notes is the difference between the vendored spec and a new tree. | |||
| 12 | + | type notes struct { | |||
| 13 | + | sources []string // "id: old → new" | |||
| 14 | + | added []string // package names | |||
| 15 | + | removed []string | |||
| 16 | + | bumps []string // "pkg: iface vA → vB" | |||
| 17 | + | newIfaces []string // "pkg: iface (vN)" | |||
| 18 | + | updated []string // packages whose XML bytes changed | |||
| 19 | + | breaking []string | |||
| 20 | + | } | |||
| 21 | + | ||||
| 22 | + | func (n *notes) empty() bool { | |||
| 23 | + | return len(n.sources)+len(n.added)+len(n.removed)+len(n.bumps)+ | |||
| 24 | + | len(n.newIfaces)+len(n.updated)+len(n.breaking) == 0 | |||
| 25 | + | } | |||
| 26 | + | ||||
| 27 | + | // parseOld parses the currently vendored XML of every manifest entry. | |||
| 28 | + | func parseOld(s *state) (map[string]*spec.Protocol, error) { | |||
| 29 | + | out := map[string]*spec.Protocol{} | |||
| 30 | + | for _, e := range s.manifest.Protocols { | |||
| 31 | + | data, ok := s.xml[e.XML] | |||
| 32 | + | if !ok { | |||
| 33 | + | return nil, fmt.Errorf("current manifest lists %s but spec/xml/%s is missing", e.Package, e.XML) | |||
| 34 | + | } | |||
| 35 | + | p, err := spec.Parse(data) | |||
| 36 | + | if err != nil { | |||
| 37 | + | return nil, fmt.Errorf("current %s: %w", e.XML, err) | |||
| 38 | + | } | |||
| 39 | + | out[e.Package] = p | |||
| 40 | + | } | |||
| 41 | + | return out, nil | |||
| 42 | + | } | |||
| 43 | + | ||||
| 44 | + | // diff compares the on-disk state with the desired tree. | |||
| 45 | + | func diff(old *state, oldParsed map[string]*spec.Protocol, t *tree) (*notes, error) { | |||
| 46 | + | n := ¬es{} | |||
| 47 | + | ||||
| 48 | + | oldSrc := map[string]spec.Source{} | |||
| 49 | + | for _, s := range old.manifest.Sources { | |||
| 50 | + | oldSrc[s.ID] = s | |||
| 51 | + | } | |||
| 52 | + | newSrc := map[string]spec.Source{} | |||
| 53 | + | for _, s := range t.manifest.Sources { | |||
| 54 | + | newSrc[s.ID] = s | |||
| 55 | + | switch o, ok := oldSrc[s.ID]; { | |||
| 56 | + | case !ok: | |||
| 57 | + | n.sources = append(n.sources, fmt.Sprintf("%s: added at %s", s.ID, s.Ref)) | |||
| 58 | + | case o.Ref != s.Ref: | |||
| 59 | + | n.sources = append(n.sources, fmt.Sprintf("%s: %s → %s", s.ID, o.Ref, s.Ref)) | |||
| 60 | + | case o.Commit != s.Commit: | |||
| 61 | + | n.sources = append(n.sources, fmt.Sprintf("%s: %s %s → %s", s.ID, s.Ref, short(o.Commit), short(s.Commit))) | |||
| 62 | + | } | |||
| 63 | + | } | |||
| 64 | + | for _, s := range old.manifest.Sources { | |||
| 65 | + | if _, ok := newSrc[s.ID]; !ok { | |||
| 66 | + | n.sources = append(n.sources, fmt.Sprintf("%s: removed", s.ID)) | |||
| 67 | + | } | |||
| 68 | + | } | |||
| 69 | + | ||||
| 70 | + | oldEntries := map[string]spec.ProtocolEntry{} | |||
| 71 | + | for _, e := range old.manifest.Protocols { | |||
| 72 | + | oldEntries[e.Package] = e | |||
| 73 | + | } | |||
| 74 | + | newEntries := map[string]spec.ProtocolEntry{} | |||
| 75 | + | for _, e := range t.manifest.Protocols { | |||
| 76 | + | newEntries[e.Package] = e | |||
| 77 | + | } | |||
| 78 | + | ||||
| 79 | + | for _, e := range t.manifest.Protocols { | |||
| 80 | + | o, existed := oldEntries[e.Package] | |||
| 81 | + | if !existed { | |||
| 82 | + | n.added = append(n.added, e.Package) | |||
| 83 | + | continue | |||
| 84 | + | } | |||
| 85 | + | if o.SHA256 != e.SHA256 { | |||
| 86 | + | n.updated = append(n.updated, e.Package) | |||
| 87 | + | } | |||
| 88 | + | if o.Source != e.Source || o.Path != e.Path { | |||
| 89 | + | n.breaking = append(n.breaking, fmt.Sprintf("%s: major replacement, %s:%s → %s:%s", | |||
| 90 | + | e.Package, o.Source, o.Path, e.Source, e.Path)) | |||
| 91 | + | } | |||
| 92 | + | newP, err := spec.Parse(t.xml[e.XML]) | |||
| 93 | + | if err != nil { | |||
| 94 | + | return nil, err | |||
| 95 | + | } | |||
| 96 | + | diffProtocol(n, e.Package, oldParsed[e.Package], newP) | |||
| 97 | + | } | |||
| 98 | + | for _, e := range old.manifest.Protocols { | |||
| 99 | + | if _, ok := newEntries[e.Package]; !ok { | |||
| 100 | + | n.removed = append(n.removed, e.Package) | |||
| 101 | + | n.breaking = append(n.breaking, fmt.Sprintf("%s: package removed", e.Package)) | |||
| 102 | + | } | |||
| 103 | + | } | |||
| 104 | + | ||||
| 105 | + | for _, l := range []*[]string{&n.sources, &n.added, &n.removed, &n.bumps, &n.newIfaces, &n.updated, &n.breaking} { | |||
| 106 | + | sort.Strings(*l) | |||
| 107 | + | } | |||
| 108 | + | return n, nil | |||
| 109 | + | } | |||
| 110 | + | ||||
| 111 | + | func short(commit string) string { | |||
| 112 | + | if len(commit) > 12 { | |||
| 113 | + | return commit[:12] | |||
| 114 | + | } | |||
| 115 | + | return commit | |||
| 116 | + | } | |||
| 117 | + | ||||
| 118 | + | func diffProtocol(n *notes, pkg string, old, cur *spec.Protocol) { | |||
| 119 | + | oldIf := map[string]spec.Interface{} | |||
| 120 | + | for _, it := range old.Interfaces { | |||
| 121 | + | oldIf[it.Name] = it | |||
| 122 | + | } | |||
| 123 | + | seen := map[string]bool{} | |||
| 124 | + | for _, it := range cur.Interfaces { | |||
| 125 | + | seen[it.Name] = true | |||
| 126 | + | o, ok := oldIf[it.Name] | |||
| 127 | + | if !ok { | |||
| 128 | + | n.newIfaces = append(n.newIfaces, fmt.Sprintf("%s: %s (v%d)", pkg, it.Name, it.Version)) | |||
| 129 | + | continue | |||
| 130 | + | } | |||
| 131 | + | if o.Version != it.Version { | |||
| 132 | + | n.bumps = append(n.bumps, fmt.Sprintf("%s: %s v%d → v%d", pkg, it.Name, o.Version, it.Version)) | |||
| 133 | + | } | |||
| 134 | + | diffMessages(n, pkg, it.Name, "request", o.Requests, it.Requests) | |||
| 135 | + | diffMessages(n, pkg, it.Name, "event", o.Events, it.Events) | |||
| 136 | + | } | |||
| 137 | + | for _, it := range old.Interfaces { | |||
| 138 | + | if !seen[it.Name] { | |||
| 139 | + | n.breaking = append(n.breaking, fmt.Sprintf("%s: interface %s removed", pkg, it.Name)) | |||
| 140 | + | } | |||
| 141 | + | } | |||
| 142 | + | } | |||
| 143 | + | ||||
| 144 | + | func diffMessages(n *notes, pkg, iface, kind string, old, cur []spec.Message) { | |||
| 145 | + | curByName := map[string]spec.Message{} | |||
| 146 | + | for _, m := range cur { | |||
| 147 | + | curByName[m.Name] = m | |||
| 148 | + | } | |||
| 149 | + | for _, o := range old { | |||
| 150 | + | m, ok := curByName[o.Name] | |||
| 151 | + | if !ok { | |||
| 152 | + | n.breaking = append(n.breaking, fmt.Sprintf("%s: %s %s %s removed", pkg, iface, kind, o.Name)) | |||
| 153 | + | continue | |||
| 154 | + | } | |||
| 155 | + | if change := argsChange(o.Args, m.Args); change != "" { | |||
| 156 | + | n.breaking = append(n.breaking, fmt.Sprintf("%s: %s %s %s arguments changed: %s", pkg, iface, kind, o.Name, change)) | |||
| 157 | + | } | |||
| 158 | + | } | |||
| 159 | + | } | |||
| 160 | + | ||||
| 161 | + | // argsChange describes the first difference between two argument lists, | |||
| 162 | + | // comparing name, type and interface by position. It returns "" when equal. | |||
| 163 | + | func argsChange(old, cur []spec.Arg) string { | |||
| 164 | + | if len(old) != len(cur) { | |||
| 165 | + | return fmt.Sprintf("%d → %d arguments", len(old), len(cur)) | |||
| 166 | + | } | |||
| 167 | + | var diffs []string | |||
| 168 | + | for i := range old { | |||
| 169 | + | o, c := old[i], cur[i] | |||
| 170 | + | if o.Name != c.Name || o.Type != c.Type || o.Interface != c.Interface { | |||
| 171 | + | diffs = append(diffs, fmt.Sprintf("#%d %s → %s", i+1, argString(o), argString(c))) | |||
| 172 | + | } | |||
| 173 | + | } | |||
| 174 | + | return strings.Join(diffs, "; ") | |||
| 175 | + | } | |||
| 176 | + | ||||
| 177 | + | func argString(a spec.Arg) string { | |||
| 178 | + | s := a.Name + ":" + a.Type | |||
| 179 | + | if a.Interface != "" { | |||
| 180 | + | s += "<" + a.Interface + ">" | |||
| 181 | + | } | |||
| 182 | + | return s | |||
| 183 | + | } | |||
| 184 | + | ||||
| 185 | + | // markdown renders the release notes. | |||
| 186 | + | func (n *notes) markdown() string { | |||
| 187 | + | var b strings.Builder | |||
| 188 | + | b.WriteString("# Upstream sync\n\n") | |||
| 189 | + | if n.empty() { | |||
| 190 | + | b.WriteString("No changes.\n") | |||
| 191 | + | return b.String() | |||
| 192 | + | } | |||
| 193 | + | section := func(title string, items []string, code bool) { | |||
| 194 | + | if len(items) == 0 { | |||
| 195 | + | return | |||
| 196 | + | } | |||
| 197 | + | fmt.Fprintf(&b, "## %s\n\n", title) | |||
| 198 | + | for _, it := range items { | |||
| 199 | + | if code { | |||
| 200 | + | fmt.Fprintf(&b, "- `%s`\n", it) | |||
| 201 | + | } else { | |||
| 202 | + | fmt.Fprintf(&b, "- %s\n", it) | |||
| 203 | + | } | |||
| 204 | + | } | |||
| 205 | + | b.WriteString("\n") | |||
| 206 | + | } | |||
| 207 | + | section("BREAKING", n.breaking, false) | |||
| 208 | + | section("Sources", n.sources, false) | |||
| 209 | + | section("Added packages", n.added, true) | |||
| 210 | + | section("Removed packages", n.removed, true) | |||
| 211 | + | section("New interfaces", n.newIfaces, false) | |||
| 212 | + | section("Interface version bumps", n.bumps, false) | |||
| 213 | + | section("Updated XML", n.updated, true) | |||
| 214 | + | return strings.TrimRight(b.String(), "\n") + "\n" | |||
| 215 | + | } | |||
A cmd/wlbsync/sources.go +185 -0
| @@ -0,0 +1,185 @@ | |||||
| 1 | + | package main | |||
| 2 | + | ||||
| 3 | + | import ( | |||
| 4 | + | "path" | |||
| 5 | + | "regexp" | |||
| 6 | + | "strconv" | |||
| 7 | + | "strings" | |||
| 8 | + | ) | |||
| 9 | + | ||||
| 10 | + | // Stability ranks upstream protocol maturity; higher wins when several files | |||
| 11 | + | // map to one package. | |||
| 12 | + | type Stability int | |||
| 13 | + | ||||
| 14 | + | // Stability levels. | |||
| 15 | + | const ( | |||
| 16 | + | Unstable Stability = iota + 1 | |||
| 17 | + | Staging | |||
| 18 | + | Stable | |||
| 19 | + | ) | |||
| 20 | + | ||||
| 21 | + | // PinKind says how the default ref of a source is chosen. | |||
| 22 | + | type PinKind int | |||
| 23 | + | ||||
| 24 | + | const ( | |||
| 25 | + | // PinTag follows the latest tag accepted by upstream.TagRe and upstream.TagOK. | |||
| 26 | + | PinTag PinKind = iota | |||
| 27 | + | // PinBranch follows the HEAD commit of upstream.Branch. | |||
| 28 | + | PinBranch | |||
| 29 | + | ) | |||
| 30 | + | ||||
| 31 | + | // upstream describes an upstream repository and which of its files are vendored. | |||
| 32 | + | type upstream struct { | |||
| 33 | + | ID string | |||
| 34 | + | URL string | |||
| 35 | + | ||||
| 36 | + | Kind PinKind | |||
| 37 | + | TagRe *regexp.Regexp // PinTag: tags must match | |||
| 38 | + | TagOK func(tag string) bool // PinTag: optional extra filter | |||
| 39 | + | Branch string // PinBranch: branch name | |||
| 40 | + | ||||
| 41 | + | // Match reports whether the slash-separated repository path rel is a | |||
| 42 | + | // vendored protocol, and its stability. | |||
| 43 | + | Match func(rel string) (Stability, bool) | |||
| 44 | + | } | |||
| 45 | + | ||||
| 46 | + | var ( | |||
| 47 | + | tagThreeParts = regexp.MustCompile(`^\d+\.\d+\.\d+$`) | |||
| 48 | + | tagTwoParts = regexp.MustCompile(`^\d+\.\d+$`) | |||
| 49 | + | tagVThreePart = regexp.MustCompile(`^v\d+\.\d+\.\d+$`) | |||
| 50 | + | ) | |||
| 51 | + | ||||
| 52 | + | // waylandTagOK accepts release tags: even minor, or patch below 90 (patch | |||
| 53 | + | // 90 and above are release candidates). | |||
| 54 | + | func waylandTagOK(tag string) bool { | |||
| 55 | + | v := versionParts(tag) | |||
| 56 | + | if len(v) != 3 { | |||
| 57 | + | return false | |||
| 58 | + | } | |||
| 59 | + | return v[1]%2 == 0 || v[2] < 90 | |||
| 60 | + | } | |||
| 61 | + | ||||
| 62 | + | // exactly matches only the listed repository paths, all with stability s. | |||
| 63 | + | func exactly(s Stability, paths ...string) func(string) (Stability, bool) { | |||
| 64 | + | set := make(map[string]bool, len(paths)) | |||
| 65 | + | for _, p := range paths { | |||
| 66 | + | set[p] = true | |||
| 67 | + | } | |||
| 68 | + | return func(rel string) (Stability, bool) { | |||
| 69 | + | if !set[rel] { | |||
| 70 | + | return 0, false | |||
| 71 | + | } | |||
| 72 | + | return s, true | |||
| 73 | + | } | |||
| 74 | + | } | |||
| 75 | + | ||||
| 76 | + | func matchWaylandProtocols(rel string) (Stability, bool) { | |||
| 77 | + | parts := strings.Split(rel, "/") | |||
| 78 | + | if len(parts) < 2 || !strings.HasSuffix(rel, ".xml") { | |||
| 79 | + | return 0, false | |||
| 80 | + | } | |||
| 81 | + | for _, p := range parts[:len(parts)-1] { | |||
| 82 | + | if p == "tests" || p == "experimental" { | |||
| 83 | + | return 0, false | |||
| 84 | + | } | |||
| 85 | + | } | |||
| 86 | + | switch parts[0] { | |||
| 87 | + | case "stable": | |||
| 88 | + | return Stable, true | |||
| 89 | + | case "staging": | |||
| 90 | + | return Staging, true | |||
| 91 | + | case "unstable": | |||
| 92 | + | return Unstable, true | |||
| 93 | + | } | |||
| 94 | + | return 0, false | |||
| 95 | + | } | |||
| 96 | + | ||||
| 97 | + | func matchWlrProtocols(rel string) (Stability, bool) { | |||
| 98 | + | if path.Dir(rel) == "unstable" && strings.HasSuffix(rel, ".xml") { | |||
| 99 | + | return Unstable, true | |||
| 100 | + | } | |||
| 101 | + | return 0, false | |||
| 102 | + | } | |||
| 103 | + | ||||
| 104 | + | // defaultSources lists the upstream repositories synced into spec/. | |||
| 105 | + | func defaultSources() []upstream { | |||
| 106 | + | return []upstream{ | |||
| 107 | + | { | |||
| 108 | + | ID: "wayland", | |||
| 109 | + | URL: "https://gitlab.freedesktop.org/wayland/wayland.git", | |||
| 110 | + | Kind: PinTag, | |||
| 111 | + | TagRe: tagThreeParts, | |||
| 112 | + | TagOK: waylandTagOK, | |||
| 113 | + | Match: exactly(Stable, "protocol/wayland.xml"), | |||
| 114 | + | }, | |||
| 115 | + | { | |||
| 116 | + | ID: "wayland-protocols", | |||
| 117 | + | URL: "https://gitlab.freedesktop.org/wayland/wayland-protocols.git", | |||
| 118 | + | Kind: PinTag, | |||
| 119 | + | TagRe: tagTwoParts, | |||
| 120 | + | Match: matchWaylandProtocols, | |||
| 121 | + | }, | |||
| 122 | + | { | |||
| 123 | + | ID: "wlr-protocols", | |||
| 124 | + | URL: "https://gitlab.freedesktop.org/wlroots/wlr-protocols.git", | |||
| 125 | + | Kind: PinBranch, | |||
| 126 | + | Branch: "master", | |||
| 127 | + | Match: matchWlrProtocols, | |||
| 128 | + | }, | |||
| 129 | + | { | |||
| 130 | + | ID: "wlroots", | |||
| 131 | + | URL: "https://gitlab.freedesktop.org/wlroots/wlroots.git", | |||
| 132 | + | Kind: PinTag, | |||
| 133 | + | TagRe: tagThreeParts, | |||
| 134 | + | Match: exactly(Unstable, | |||
| 135 | + | "protocol/input-method-unstable-v2.xml", | |||
| 136 | + | "protocol/virtual-keyboard-unstable-v1.xml"), | |||
| 137 | + | }, | |||
| 138 | + | { | |||
| 139 | + | ID: "plasma-wayland-protocols", | |||
| 140 | + | URL: "https://invent.kde.org/libraries/plasma-wayland-protocols.git", | |||
| 141 | + | Kind: PinTag, | |||
| 142 | + | TagRe: tagVThreePart, | |||
| 143 | + | Match: exactly(Unstable, "src/protocols/server-decoration.xml"), | |||
| 144 | + | }, | |||
| 145 | + | } | |||
| 146 | + | } | |||
| 147 | + | ||||
| 148 | + | // versionParts splits "v1.2.3" or "1.2" into its numeric components. | |||
| 149 | + | func versionParts(tag string) []int { | |||
| 150 | + | var out []int | |||
| 151 | + | for _, f := range strings.Split(strings.TrimPrefix(tag, "v"), ".") { | |||
| 152 | + | n, err := strconv.Atoi(f) | |||
| 153 | + | if err != nil { | |||
| 154 | + | return nil | |||
| 155 | + | } | |||
| 156 | + | out = append(out, n) | |||
| 157 | + | } | |||
| 158 | + | return out | |||
| 159 | + | } | |||
| 160 | + | ||||
| 161 | + | // compareVersions orders two tags numerically. | |||
| 162 | + | func compareVersions(a, b string) int { | |||
| 163 | + | x, y := versionParts(a), versionParts(b) | |||
| 164 | + | for i := 0; i < len(x) && i < len(y); i++ { | |||
| 165 | + | if x[i] != y[i] { | |||
| 166 | + | if x[i] < y[i] { | |||
| 167 | + | return -1 | |||
| 168 | + | } | |||
| 169 | + | return 1 | |||
| 170 | + | } | |||
| 171 | + | } | |||
| 172 | + | return len(x) - len(y) | |||
| 173 | + | } | |||
| 174 | + | ||||
| 175 | + | var majorSuffix = regexp.MustCompile(`-v(\d+)$`) | |||
| 176 | + | ||||
| 177 | + | // fileMajor returns the "vN" major of an XML file name; none means 1. | |||
| 178 | + | func fileMajor(file string) int { | |||
| 179 | + | base := strings.TrimSuffix(path.Base(file), ".xml") | |||
| 180 | + | if m := majorSuffix.FindStringSubmatch(base); m != nil { | |||
| 181 | + | n, _ := strconv.Atoi(m[1]) | |||
| 182 | + | return n | |||
| 183 | + | } | |||
| 184 | + | return 1 | |||
| 185 | + | } | |||
A cmd/wlbsync/sync.go +293 -0
| @@ -0,0 +1,293 @@ | |||||
| 1 | + | package main | |||
| 2 | + | ||||
| 3 | + | import ( | |||
| 4 | + | "bytes" | |||
| 5 | + | "crypto/sha256" | |||
| 6 | + | "encoding/hex" | |||
| 7 | + | "encoding/json" | |||
| 8 | + | "errors" | |||
| 9 | + | "fmt" | |||
| 10 | + | "io/fs" | |||
| 11 | + | "os" | |||
| 12 | + | "path/filepath" | |||
| 13 | + | "sort" | |||
| 14 | + | "strings" | |||
| 15 | + | ||||
| 16 | + | "github.com/bnema/go-wayland-bindings/spec" | |||
| 17 | + | ) | |||
| 18 | + | ||||
| 19 | + | // candidate is an upstream XML file that may provide a package. | |||
| 20 | + | type candidate struct { | |||
| 21 | + | source string | |||
| 22 | + | path string // slash-separated path inside the repository | |||
| 23 | + | pkg string | |||
| 24 | + | stability Stability | |||
| 25 | + | major int | |||
| 26 | + | data []byte | |||
| 27 | + | } | |||
| 28 | + | ||||
| 29 | + | // tree is the desired content of spec/: the manifest plus the XML files. | |||
| 30 | + | type tree struct { | |||
| 31 | + | manifest *spec.Manifest | |||
| 32 | + | xml map[string][]byte // file name under spec/xml | |||
| 33 | + | } | |||
| 34 | + | ||||
| 35 | + | // rank orders candidates of one package: higher is better. | |||
| 36 | + | func (c candidate) beats(o candidate) bool { | |||
| 37 | + | if c.stability != o.stability { | |||
| 38 | + | return c.stability > o.stability | |||
| 39 | + | } | |||
| 40 | + | return c.major > o.major | |||
| 41 | + | } | |||
| 42 | + | ||||
| 43 | + | func (c candidate) tied(o candidate) bool { | |||
| 44 | + | return c.stability == o.stability && c.major == o.major | |||
| 45 | + | } | |||
| 46 | + | ||||
| 47 | + | // collect resolves and checks out every source and returns the candidates | |||
| 48 | + | // found, together with the resolved source records. | |||
| 49 | + | func collect(srcs []upstream, pins map[string]string, f Fetcher) ([]spec.Source, []candidate, error) { | |||
| 50 | + | var ( | |||
| 51 | + | sources []spec.Source | |||
| 52 | + | cands []candidate | |||
| 53 | + | ) | |||
| 54 | + | for _, src := range srcs { | |||
| 55 | + | ref, commit, err := f.Resolve(src, pins[src.ID]) | |||
| 56 | + | if err != nil { | |||
| 57 | + | return nil, nil, fmt.Errorf("resolve %s: %w", src.ID, err) | |||
| 58 | + | } | |||
| 59 | + | found, err := checkoutAndScan(src, ref, commit, f) | |||
| 60 | + | if err != nil { | |||
| 61 | + | return nil, nil, err | |||
| 62 | + | } | |||
| 63 | + | if len(found) == 0 { | |||
| 64 | + | return nil, nil, fmt.Errorf("%s@%s: no protocol XML found", src.ID, ref) | |||
| 65 | + | } | |||
| 66 | + | sources = append(sources, spec.Source{ID: src.ID, URL: src.URL, Ref: ref, Commit: commit}) | |||
| 67 | + | cands = append(cands, found...) | |||
| 68 | + | } | |||
| 69 | + | return sources, cands, nil | |||
| 70 | + | } | |||
| 71 | + | ||||
| 72 | + | func checkoutAndScan(src upstream, ref, commit string, f Fetcher) ([]candidate, error) { | |||
| 73 | + | dir, err := os.MkdirTemp("", "wlbsync-"+src.ID+"-") | |||
| 74 | + | if err != nil { | |||
| 75 | + | return nil, err | |||
| 76 | + | } | |||
| 77 | + | defer os.RemoveAll(dir) | |||
| 78 | + | if err := f.Checkout(src, ref, commit, dir); err != nil { | |||
| 79 | + | return nil, fmt.Errorf("checkout %s@%s: %w", src.ID, ref, err) | |||
| 80 | + | } | |||
| 81 | + | var out []candidate | |||
| 82 | + | err = filepath.WalkDir(dir, func(p string, d fs.DirEntry, err error) error { | |||
| 83 | + | if err != nil { | |||
| 84 | + | return err | |||
| 85 | + | } | |||
| 86 | + | if d.IsDir() { | |||
| 87 | + | if d.Name() == ".git" { | |||
| 88 | + | return filepath.SkipDir | |||
| 89 | + | } | |||
| 90 | + | return nil | |||
| 91 | + | } | |||
| 92 | + | rel, err := filepath.Rel(dir, p) | |||
| 93 | + | if err != nil { | |||
| 94 | + | return err | |||
| 95 | + | } | |||
| 96 | + | rel = filepath.ToSlash(rel) | |||
| 97 | + | st, ok := src.Match(rel) | |||
| 98 | + | if !ok { | |||
| 99 | + | return nil | |||
| 100 | + | } | |||
| 101 | + | data, err := os.ReadFile(p) | |||
| 102 | + | if err != nil { | |||
| 103 | + | return err | |||
| 104 | + | } | |||
| 105 | + | out = append(out, candidate{ | |||
| 106 | + | source: src.ID, | |||
| 107 | + | path: rel, | |||
| 108 | + | pkg: spec.PackageName(rel), | |||
| 109 | + | stability: st, | |||
| 110 | + | major: fileMajor(rel), | |||
| 111 | + | data: data, | |||
| 112 | + | }) | |||
| 113 | + | return nil | |||
| 114 | + | }) | |||
| 115 | + | if err != nil { | |||
| 116 | + | return nil, fmt.Errorf("scan %s: %w", src.ID, err) | |||
| 117 | + | } | |||
| 118 | + | return out, nil | |||
| 119 | + | } | |||
| 120 | + | ||||
| 121 | + | // build applies the selection rule and derives the manifest. | |||
| 122 | + | func build(sources []spec.Source, cands []candidate) (*tree, error) { | |||
| 123 | + | byPkg := map[string][]candidate{} | |||
| 124 | + | for _, c := range cands { | |||
| 125 | + | if !spec.ValidPackageName(c.pkg) { | |||
| 126 | + | return nil, fmt.Errorf("%s:%s maps to invalid package name %q", c.source, c.path, c.pkg) | |||
| 127 | + | } | |||
| 128 | + | byPkg[c.pkg] = append(byPkg[c.pkg], c) | |||
| 129 | + | } | |||
| 130 | + | ||||
| 131 | + | t := &tree{manifest: &spec.Manifest{Sources: sources}, xml: map[string][]byte{}} | |||
| 132 | + | parsed := map[string]*spec.Protocol{} | |||
| 133 | + | pkgs := make([]string, 0, len(byPkg)) | |||
| 134 | + | for p := range byPkg { | |||
| 135 | + | pkgs = append(pkgs, p) | |||
| 136 | + | } | |||
| 137 | + | sort.Strings(pkgs) | |||
| 138 | + | ||||
| 139 | + | for _, pkg := range pkgs { | |||
| 140 | + | cs := byPkg[pkg] | |||
| 141 | + | sort.Slice(cs, func(i, j int) bool { | |||
| 142 | + | if cs[i].beats(cs[j]) != cs[j].beats(cs[i]) { | |||
| 143 | + | return cs[i].beats(cs[j]) | |||
| 144 | + | } | |||
| 145 | + | return cs[i].source+":"+cs[i].path < cs[j].source+":"+cs[j].path | |||
| 146 | + | }) | |||
| 147 | + | best := cs[0] | |||
| 148 | + | if len(cs) > 1 && best.tied(cs[1]) { | |||
| 149 | + | return nil, fmt.Errorf("package %q: %s:%s and %s:%s tie (same stability and major version)", | |||
| 150 | + | pkg, best.source, best.path, cs[1].source, cs[1].path) | |||
| 151 | + | } | |||
| 152 | + | p, err := spec.Parse(best.data) | |||
| 153 | + | if err != nil { | |||
| 154 | + | return nil, fmt.Errorf("%s:%s: %w", best.source, best.path, err) | |||
| 155 | + | } | |||
| 156 | + | if strings.TrimSpace(p.Copyright) == "" { | |||
| 157 | + | return nil, fmt.Errorf("%s:%s: missing <copyright>", best.source, best.path) | |||
| 158 | + | } | |||
| 159 | + | parsed[pkg] = p | |||
| 160 | + | ||||
| 161 | + | sum := sha256.Sum256(best.data) | |||
| 162 | + | entry := spec.ProtocolEntry{ | |||
| 163 | + | Package: pkg, | |||
| 164 | + | XML: pkg + ".xml", | |||
| 165 | + | Source: best.source, | |||
| 166 | + | Path: best.path, | |||
| 167 | + | SHA256: hex.EncodeToString(sum[:]), | |||
| 168 | + | License: licenseFor(pkg), | |||
| 169 | + | Deps: []string{}, | |||
| 170 | + | } | |||
| 171 | + | for _, it := range p.Interfaces { | |||
| 172 | + | entry.Interfaces = append(entry.Interfaces, spec.InterfaceEntry{Name: it.Name, Version: it.Version}) | |||
| 173 | + | } | |||
| 174 | + | sort.Slice(entry.Interfaces, func(i, j int) bool { return entry.Interfaces[i].Name < entry.Interfaces[j].Name }) | |||
| 175 | + | t.manifest.Protocols = append(t.manifest.Protocols, entry) | |||
| 176 | + | t.xml[entry.XML] = best.data | |||
| 177 | + | } | |||
| 178 | + | ||||
| 179 | + | owners := map[string]string{} | |||
| 180 | + | for _, e := range t.manifest.Protocols { | |||
| 181 | + | for _, it := range e.Interfaces { | |||
| 182 | + | if prev, dup := owners[it.Name]; dup { | |||
| 183 | + | return nil, fmt.Errorf("interface %q is defined by both %q and %q", it.Name, prev, e.Package) | |||
| 184 | + | } | |||
| 185 | + | owners[it.Name] = e.Package | |||
| 186 | + | } | |||
| 187 | + | } | |||
| 188 | + | for i := range t.manifest.Protocols { | |||
| 189 | + | e := &t.manifest.Protocols[i] | |||
| 190 | + | deps := map[string]bool{} | |||
| 191 | + | for _, ref := range parsed[e.Package].ReferencedInterfaces() { | |||
| 192 | + | owner, ok := owners[ref] | |||
| 193 | + | if !ok { | |||
| 194 | + | return nil, fmt.Errorf("package %q references unknown interface %q", e.Package, ref) | |||
| 195 | + | } | |||
| 196 | + | if owner != e.Package { | |||
| 197 | + | deps[owner] = true | |||
| 198 | + | } | |||
| 199 | + | } | |||
| 200 | + | for d := range deps { | |||
| 201 | + | e.Deps = append(e.Deps, d) | |||
| 202 | + | } | |||
| 203 | + | sort.Strings(e.Deps) | |||
| 204 | + | } | |||
| 205 | + | t.manifest.Sort() | |||
| 206 | + | return t, nil | |||
| 207 | + | } | |||
| 208 | + | ||||
| 209 | + | func licenseFor(pkg string) string { | |||
| 210 | + | if pkg == "serverdecoration" { | |||
| 211 | + | return "LGPL-2.1-or-later" | |||
| 212 | + | } | |||
| 213 | + | return "MIT" | |||
| 214 | + | } | |||
| 215 | + | ||||
| 216 | + | // state is what is currently on disk under spec/. | |||
| 217 | + | type state struct { | |||
| 218 | + | manifest *spec.Manifest | |||
| 219 | + | raw []byte | |||
| 220 | + | xml map[string][]byte | |||
| 221 | + | } | |||
| 222 | + | ||||
| 223 | + | func readState(root string) (*state, error) { | |||
| 224 | + | s := &state{manifest: &spec.Manifest{}, xml: map[string][]byte{}} | |||
| 225 | + | raw, err := os.ReadFile(filepath.Join(root, "spec", "manifest.json")) | |||
| 226 | + | switch { | |||
| 227 | + | case errors.Is(err, fs.ErrNotExist): | |||
| 228 | + | case err != nil: | |||
| 229 | + | return nil, err | |||
| 230 | + | default: | |||
| 231 | + | s.raw = raw | |||
| 232 | + | if len(bytes.TrimSpace(raw)) > 0 { | |||
| 233 | + | if err := json.Unmarshal(raw, s.manifest); err != nil { | |||
| 234 | + | return nil, fmt.Errorf("decode current manifest: %w", err) | |||
| 235 | + | } | |||
| 236 | + | } | |||
| 237 | + | } | |||
| 238 | + | entries, err := os.ReadDir(filepath.Join(root, "spec", "xml")) | |||
| 239 | + | if err != nil && !errors.Is(err, fs.ErrNotExist) { | |||
| 240 | + | return nil, err | |||
| 241 | + | } | |||
| 242 | + | for _, e := range entries { | |||
| 243 | + | if e.IsDir() { | |||
| 244 | + | continue | |||
| 245 | + | } | |||
| 246 | + | b, err := os.ReadFile(filepath.Join(root, "spec", "xml", e.Name())) | |||
| 247 | + | if err != nil { | |||
| 248 | + | return nil, err | |||
| 249 | + | } | |||
| 250 | + | s.xml[e.Name()] = b | |||
| 251 | + | } | |||
| 252 | + | return s, nil | |||
| 253 | + | } | |||
| 254 | + | ||||
| 255 | + | // differs reports whether writing t would change anything on disk. | |||
| 256 | + | func (s *state) differs(t *tree, manifest []byte) bool { | |||
| 257 | + | if !bytes.Equal(s.raw, manifest) || len(s.xml) != len(t.xml) { | |||
| 258 | + | return true | |||
| 259 | + | } | |||
| 260 | + | for name, b := range t.xml { | |||
| 261 | + | if old, ok := s.xml[name]; !ok || !bytes.Equal(old, b) { | |||
| 262 | + | return true | |||
| 263 | + | } | |||
| 264 | + | } | |||
| 265 | + | return false | |||
| 266 | + | } | |||
| 267 | + | ||||
| 268 | + | // write stores t under root/spec and removes stale XML files. | |||
| 269 | + | func write(root string, s *state, t *tree, manifest []byte) error { | |||
| 270 | + | dir := filepath.Join(root, "spec", "xml") | |||
| 271 | + | if err := os.MkdirAll(dir, 0o755); err != nil { | |||
| 272 | + | return err | |||
| 273 | + | } | |||
| 274 | + | for name, b := range t.xml { | |||
| 275 | + | if old, ok := s.xml[name]; ok && bytes.Equal(old, b) { | |||
| 276 | + | continue | |||
| 277 | + | } | |||
| 278 | + | if err := os.WriteFile(filepath.Join(dir, name), b, 0o644); err != nil { | |||
| 279 | + | return err | |||
| 280 | + | } | |||
| 281 | + | } | |||
| 282 | + | for name := range s.xml { | |||
| 283 | + | if _, keep := t.xml[name]; !keep { | |||
| 284 | + | if err := os.Remove(filepath.Join(dir, name)); err != nil { | |||
| 285 | + | return err | |||
| 286 | + | } | |||
| 287 | + | } | |||
| 288 | + | } | |||
| 289 | + | if !bytes.Equal(s.raw, manifest) { | |||
| 290 | + | return os.WriteFile(filepath.Join(root, "spec", "manifest.json"), manifest, 0o644) | |||
| 291 | + | } | |||
| 292 | + | return nil | |||
| 293 | + | } | |||
A cmd/wlbsync/sync_test.go +776 -0
| @@ -0,0 +1,776 @@ | |||||
| 1 | + | package main | |||
| 2 | + | ||||
| 3 | + | import ( | |||
| 4 | + | "bytes" | |||
| 5 | + | "fmt" | |||
| 6 | + | "os" | |||
| 7 | + | "path/filepath" | |||
| 8 | + | "reflect" | |||
| 9 | + | "sort" | |||
| 10 | + | "strings" | |||
| 11 | + | "testing" | |||
| 12 | + | ||||
| 13 | + | "github.com/bnema/go-wayland-bindings/spec" | |||
| 14 | + | ) | |||
| 15 | + | ||||
| 16 | + | // fakeFetcher serves source trees from memory; no network or git. | |||
| 17 | + | type fakeFetcher struct { | |||
| 18 | + | // trees[source id][ref] = repository files. | |||
| 19 | + | trees map[string]map[string]map[string]string | |||
| 20 | + | // latest[source id] = ref used when no pin is given. | |||
| 21 | + | latest map[string]string | |||
| 22 | + | } | |||
| 23 | + | ||||
| 24 | + | func (f *fakeFetcher) commit(id, ref string) string { | |||
| 25 | + | return fmt.Sprintf("%040x", len(id)*1000+len(ref)) // deterministic, 40 chars | |||
| 26 | + | } | |||
| 27 | + | ||||
| 28 | + | func (f *fakeFetcher) Resolve(src upstream, pin string) (string, string, error) { | |||
| 29 | + | ref := pin | |||
| 30 | + | if ref == "" { | |||
| 31 | + | ref = f.latest[src.ID] | |||
| 32 | + | } | |||
| 33 | + | if _, ok := f.trees[src.ID][ref]; !ok { | |||
| 34 | + | return "", "", fmt.Errorf("fake: %s has no ref %q", src.ID, ref) | |||
| 35 | + | } | |||
| 36 | + | return ref, f.commit(src.ID, ref), nil | |||
| 37 | + | } | |||
| 38 | + | ||||
| 39 | + | func (f *fakeFetcher) Checkout(src upstream, ref, commit, dir string) error { | |||
| 40 | + | files, ok := f.trees[src.ID][ref] | |||
| 41 | + | if !ok { | |||
| 42 | + | return fmt.Errorf("fake: %s has no ref %q", src.ID, ref) | |||
| 43 | + | } | |||
| 44 | + | for name, content := range files { | |||
| 45 | + | p := filepath.Join(dir, filepath.FromSlash(name)) | |||
| 46 | + | if err := os.MkdirAll(filepath.Dir(p), 0o755); err != nil { | |||
| 47 | + | return err | |||
| 48 | + | } | |||
| 49 | + | if err := os.WriteFile(p, []byte(content), 0o644); err != nil { | |||
| 50 | + | return err | |||
| 51 | + | } | |||
| 52 | + | } | |||
| 53 | + | return nil | |||
| 54 | + | } | |||
| 55 | + | ||||
| 56 | + | // xmlDoc builds a protocol document. Each interface is "name:version" followed | |||
| 57 | + | // by optional requests "req(arg:type[:iface],...)". | |||
| 58 | + | func xmlDoc(name string, copyright bool, ifaces ...string) string { | |||
| 59 | + | var b strings.Builder | |||
| 60 | + | fmt.Fprintf(&b, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<protocol name=%q>\n", name) | |||
| 61 | + | if copyright { | |||
| 62 | + | b.WriteString(" <copyright>Copyright test</copyright>\n") | |||
| 63 | + | } | |||
| 64 | + | for _, spec := range ifaces { | |||
| 65 | + | parts := strings.Split(spec, "|") | |||
| 66 | + | nv := strings.SplitN(parts[0], ":", 2) | |||
| 67 | + | fmt.Fprintf(&b, " <interface name=%q version=%q>\n", nv[0], nv[1]) | |||
| 68 | + | for _, req := range parts[1:] { | |||
| 69 | + | open := strings.Index(req, "(") | |||
| 70 | + | fmt.Fprintf(&b, " <request name=%q>\n", req[:open]) | |||
| 71 | + | args := strings.TrimSuffix(req[open+1:], ")") | |||
| 72 | + | if args != "" { | |||
| 73 | + | for _, a := range strings.Split(args, ",") { | |||
| 74 | + | f := strings.Split(a, ":") | |||
| 75 | + | if len(f) == 3 { | |||
| 76 | + | fmt.Fprintf(&b, " <arg name=%q type=%q interface=%q/>\n", f[0], f[1], f[2]) | |||
| 77 | + | } else { | |||
| 78 | + | fmt.Fprintf(&b, " <arg name=%q type=%q/>\n", f[0], f[1]) | |||
| 79 | + | } | |||
| 80 | + | } | |||
| 81 | + | } | |||
| 82 | + | b.WriteString(" </request>\n") | |||
| 83 | + | } | |||
| 84 | + | b.WriteString(" </interface>\n") | |||
| 85 | + | } | |||
| 86 | + | b.WriteString("</protocol>\n") | |||
| 87 | + | return b.String() | |||
| 88 | + | } | |||
| 89 | + | ||||
| 90 | + | func testSources() []upstream { | |||
| 91 | + | var out []upstream | |||
| 92 | + | for _, s := range defaultSources() { | |||
| 93 | + | if s.ID == "wayland" || s.ID == "wayland-protocols" { | |||
| 94 | + | out = append(out, s) | |||
| 95 | + | } | |||
| 96 | + | } | |||
| 97 | + | return out | |||
| 98 | + | } | |||
| 99 | + | ||||
| 100 | + | func waylandTree() map[string]string { | |||
| 101 | + | return map[string]string{ | |||
| 102 | + | "protocol/wayland.xml": xmlDoc("wayland", true, "wl_surface:6", "wl_seat:9"), | |||
| 103 | + | "protocol/other.xml": "ignored: not a vendored path", | |||
| 104 | + | } | |||
| 105 | + | } | |||
| 106 | + | ||||
| 107 | + | func baseFetcher() *fakeFetcher { | |||
| 108 | + | return &fakeFetcher{ | |||
| 109 | + | trees: map[string]map[string]map[string]string{ | |||
| 110 | + | "wayland": {"1.0.0": waylandTree()}, | |||
| 111 | + | "wayland-protocols": { | |||
| 112 | + | "1.0": { | |||
| 113 | + | "stable/xdg-shell/xdg-shell.xml": xmlDoc("xdg_shell", true, | |||
| 114 | + | "xdg_wm_base:5|get_surface(id:new_id:xdg_surface,surface:object:wl_surface)", | |||
| 115 | + | "xdg_surface:5"), | |||
| 116 | + | "staging/foo/foo-v1.xml": xmlDoc("foo", true, "foo_manager_v1:1|make(seat:object:wl_seat)"), | |||
| 117 | + | "stable/tests/skip.xml": xmlDoc("skip", false), | |||
| 118 | + | "experimental/x/xx.xml": xmlDoc("xx", false), | |||
| 119 | + | "unstable/old/old-unstable-v1.xml": xmlDoc("old", true, | |||
| 120 | + | "old_thing_v1:1|poke(n:uint)"), | |||
| 121 | + | "README.md": "not xml", | |||
| 122 | + | }, | |||
| 123 | + | }, | |||
| 124 | + | }, | |||
| 125 | + | latest: map[string]string{"wayland": "1.0.0", "wayland-protocols": "1.0"}, | |||
| 126 | + | } | |||
| 127 | + | } | |||
| 128 | + | ||||
| 129 | + | func syncOnce(t *testing.T, root string, f Fetcher, o options) (string, error) { | |||
| 130 | + | t.Helper() | |||
| 131 | + | o.root = root | |||
| 132 | + | var out bytes.Buffer | |||
| 133 | + | err := run(o, testSources(), f, &out) | |||
| 134 | + | return strings.TrimSpace(out.String()), err | |||
| 135 | + | } | |||
| 136 | + | ||||
| 137 | + | func mustSync(t *testing.T, root string, f Fetcher, o options) string { | |||
| 138 | + | t.Helper() | |||
| 139 | + | out, err := syncOnce(t, root, f, o) | |||
| 140 | + | if err != nil { | |||
| 141 | + | t.Fatal(err) | |||
| 142 | + | } | |||
| 143 | + | return out | |||
| 144 | + | } | |||
| 145 | + | ||||
| 146 | + | func snapshot(t *testing.T, root string) map[string]string { | |||
| 147 | + | t.Helper() | |||
| 148 | + | out := map[string]string{} | |||
| 149 | + | err := filepath.Walk(root, func(p string, info os.FileInfo, err error) error { | |||
| 150 | + | if err != nil || info.IsDir() { | |||
| 151 | + | return err | |||
| 152 | + | } | |||
| 153 | + | b, err := os.ReadFile(p) | |||
| 154 | + | out[p] = string(b) | |||
| 155 | + | return err | |||
| 156 | + | }) | |||
| 157 | + | if err != nil { | |||
| 158 | + | t.Fatal(err) | |||
| 159 | + | } | |||
| 160 | + | return out | |||
| 161 | + | } | |||
| 162 | + | ||||
| 163 | + | func readNotes(t *testing.T, path string) string { | |||
| 164 | + | t.Helper() | |||
| 165 | + | b, err := os.ReadFile(path) | |||
| 166 | + | if err != nil { | |||
| 167 | + | t.Fatal(err) | |||
| 168 | + | } | |||
| 169 | + | return string(b) | |||
| 170 | + | } | |||
| 171 | + | ||||
| 172 | + | func loadRoot(t *testing.T, root string) *spec.Manifest { | |||
| 173 | + | t.Helper() | |||
| 174 | + | m, err := spec.LoadFS(os.DirFS(filepath.Join(root, "spec"))) | |||
| 175 | + | if err != nil { | |||
| 176 | + | t.Fatal(err) | |||
| 177 | + | } | |||
| 178 | + | return m | |||
| 179 | + | } | |||
| 180 | + | ||||
| 181 | + | func TestInitialSync(t *testing.T) { | |||
| 182 | + | root := t.TempDir() | |||
| 183 | + | f := baseFetcher() | |||
| 184 | + | if got := mustSync(t, root, f, options{}); got != "changed=true" { | |||
| 185 | + | t.Fatalf("output %q", got) | |||
| 186 | + | } | |||
| 187 | + | m := loadRoot(t, root) | |||
| 188 | + | ||||
| 189 | + | var pkgs []string | |||
| 190 | + | for _, e := range m.Protocols { | |||
| 191 | + | pkgs = append(pkgs, e.Package) | |||
| 192 | + | } | |||
| 193 | + | if want := []string{"foo", "old", "wayland", "xdgshell"}; !reflect.DeepEqual(pkgs, want) { | |||
| 194 | + | t.Fatalf("packages = %v, want %v", pkgs, want) | |||
| 195 | + | } | |||
| 196 | + | ||||
| 197 | + | xdg, _ := m.Package("xdgshell") | |||
| 198 | + | if xdg.Source != "wayland-protocols" || xdg.Path != "stable/xdg-shell/xdg-shell.xml" || xdg.License != "MIT" { | |||
| 199 | + | t.Errorf("xdgshell = %+v", xdg) | |||
| 200 | + | } | |||
| 201 | + | if want := []string{"wayland"}; !reflect.DeepEqual(xdg.Deps, want) { | |||
| 202 | + | t.Errorf("xdgshell deps = %v", xdg.Deps) | |||
| 203 | + | } | |||
| 204 | + | if want := []spec.InterfaceEntry{{Name: "xdg_surface", Version: 5}, {Name: "xdg_wm_base", Version: 5}}; !reflect.DeepEqual(xdg.Interfaces, want) { | |||
| 205 | + | t.Errorf("xdgshell interfaces = %v", xdg.Interfaces) | |||
| 206 | + | } | |||
| 207 | + | if w, _ := m.Package("wayland"); len(w.Deps) != 0 || w.Deps == nil { | |||
| 208 | + | t.Errorf("wayland deps = %#v, want empty non-nil", w.Deps) | |||
| 209 | + | } | |||
| 210 | + | if len(m.Sources) != 2 || m.Sources[0].ID != "wayland" || m.Sources[1].Ref != "1.0" { | |||
| 211 | + | t.Errorf("sources = %+v", m.Sources) | |||
| 212 | + | } | |||
| 213 | + | ||||
| 214 | + | // Bytes are copied unchanged, and the sha256 describes them. | |||
| 215 | + | got, err := os.ReadFile(filepath.Join(root, "spec", "xml", "xdgshell.xml")) | |||
| 216 | + | if err != nil { | |||
| 217 | + | t.Fatal(err) | |||
| 218 | + | } | |||
| 219 | + | if string(got) != f.trees["wayland-protocols"]["1.0"]["stable/xdg-shell/xdg-shell.xml"] { | |||
| 220 | + | t.Error("xml bytes differ from upstream") | |||
| 221 | + | } | |||
| 222 | + | if len(xdg.SHA256) != 64 { | |||
| 223 | + | t.Errorf("sha256 = %q", xdg.SHA256) | |||
| 224 | + | } | |||
| 225 | + | if _, err := os.Stat(filepath.Join(root, "spec", "xml", "skip.xml")); err == nil { | |||
| 226 | + | t.Error("tests/ file was vendored") | |||
| 227 | + | } | |||
| 228 | + | ||||
| 229 | + | // Second run: nothing changes. | |||
| 230 | + | before := snapshot(t, root) | |||
| 231 | + | if got := mustSync(t, root, f, options{}); got != "changed=false" { | |||
| 232 | + | t.Errorf("rerun output %q", got) | |||
| 233 | + | } | |||
| 234 | + | if !reflect.DeepEqual(before, snapshot(t, root)) { | |||
| 235 | + | t.Error("rerun modified spec/") | |||
| 236 | + | } | |||
| 237 | + | } | |||
| 238 | + | ||||
| 239 | + | func TestLicenseServerDecoration(t *testing.T) { | |||
| 240 | + | var src []upstream | |||
| 241 | + | for _, s := range defaultSources() { | |||
| 242 | + | if s.ID == "plasma-wayland-protocols" { | |||
| 243 | + | src = append(src, s) | |||
| 244 | + | } | |||
| 245 | + | } | |||
| 246 | + | f := &fakeFetcher{ | |||
| 247 | + | trees: map[string]map[string]map[string]string{"plasma-wayland-protocols": {"v1.0.0": { | |||
| 248 | + | "src/protocols/server-decoration.xml": xmlDoc("server_decoration", true, "org_kde_kwin_server_decoration:1"), | |||
| 249 | + | }}}, | |||
| 250 | + | latest: map[string]string{"plasma-wayland-protocols": "v1.0.0"}, | |||
| 251 | + | } | |||
| 252 | + | root := t.TempDir() | |||
| 253 | + | if err := run(options{root: root}, src, f, &bytes.Buffer{}); err != nil { | |||
| 254 | + | t.Fatal(err) | |||
| 255 | + | } | |||
| 256 | + | e, ok := loadRoot(t, root).Package("serverdecoration") | |||
| 257 | + | if !ok || e.License != "LGPL-2.1-or-later" { | |||
| 258 | + | t.Errorf("entry = %+v, %v", e, ok) | |||
| 259 | + | } | |||
| 260 | + | } | |||
| 261 | + | ||||
| 262 | + | func TestCheckWritesNothing(t *testing.T) { | |||
| 263 | + | root := t.TempDir() | |||
| 264 | + | f := baseFetcher() | |||
| 265 | + | ||||
| 266 | + | // Empty tree: check reports a change but creates nothing. | |||
| 267 | + | if got := mustSync(t, root, f, options{check: true}); got != "changed=true" { | |||
| 268 | + | t.Errorf("output %q", got) | |||
| 269 | + | } | |||
| 270 | + | if len(snapshot(t, root)) != 0 { | |||
| 271 | + | t.Errorf("-check wrote files: %v", snapshot(t, root)) | |||
| 272 | + | } | |||
| 273 | + | ||||
| 274 | + | mustSync(t, root, f, options{}) | |||
| 275 | + | if got := mustSync(t, root, f, options{check: true}); got != "changed=false" { | |||
| 276 | + | t.Errorf("output %q", got) | |||
| 277 | + | } | |||
| 278 | + | ||||
| 279 | + | // Upstream moves on; -check reports it and leaves everything alone, | |||
| 280 | + | // while -notes still works. | |||
| 281 | + | f.trees["wayland-protocols"]["1.1"] = map[string]string{ | |||
| 282 | + | "stable/xdg-shell/xdg-shell.xml": xmlDoc("xdg_shell", true, "xdg_wm_base:6", "xdg_surface:5"), | |||
| 283 | + | "staging/foo/foo-v1.xml": f.trees["wayland-protocols"]["1.0"]["staging/foo/foo-v1.xml"], | |||
| 284 | + | } | |||
| 285 | + | f.latest["wayland-protocols"] = "1.1" | |||
| 286 | + | before := snapshot(t, root) | |||
| 287 | + | notesFile := filepath.Join(t.TempDir(), "notes.md") | |||
| 288 | + | if got := mustSync(t, root, f, options{check: true, notes: notesFile}); got != "changed=true" { | |||
| 289 | + | t.Errorf("output %q", got) | |||
| 290 | + | } | |||
| 291 | + | if !reflect.DeepEqual(before, snapshot(t, root)) { | |||
| 292 | + | t.Error("-check modified spec/") | |||
| 293 | + | } | |||
| 294 | + | if n := readNotes(t, notesFile); !strings.Contains(n, "xdg_wm_base v5 → v6") { | |||
| 295 | + | t.Errorf("notes missing bump:\n%s", n) | |||
| 296 | + | } | |||
| 297 | + | } | |||
| 298 | + | ||||
| 299 | + | func TestNotes(t *testing.T) { | |||
| 300 | + | root := t.TempDir() | |||
| 301 | + | f := baseFetcher() | |||
| 302 | + | mustSync(t, root, f, options{}) | |||
| 303 | + | ||||
| 304 | + | // New upstream release: | |||
| 305 | + | // - xdg_wm_base version bump, request get_surface keeps its args | |||
| 306 | + | // - xdg_popup interface added | |||
| 307 | + | // - foo-v2 replaces foo-v1 (major replacement) | |||
| 308 | + | // - old package removed | |||
| 309 | + | // - new package "bar" added | |||
| 310 | + | // - wayland: new tag, identical content (only the source ref changes) | |||
| 311 | + | f.trees["wayland-protocols"]["1.1"] = map[string]string{ | |||
| 312 | + | "stable/xdg-shell/xdg-shell.xml": xmlDoc("xdg_shell", true, | |||
| 313 | + | "xdg_wm_base:6|get_surface(id:new_id:xdg_surface,surface:object:wl_surface)", | |||
| 314 | + | "xdg_surface:5", | |||
| 315 | + | "xdg_popup:5"), | |||
| 316 | + | "staging/foo/foo-v1.xml": f.trees["wayland-protocols"]["1.0"]["staging/foo/foo-v1.xml"], | |||
| 317 | + | "staging/foo/foo-v2.xml": xmlDoc("foo", true, "foo_manager_v2:1|make(seat:object:wl_seat)"), | |||
| 318 | + | "staging/bar/bar-v1.xml": xmlDoc("bar", true, "bar_manager_v1:1"), | |||
| 319 | + | } | |||
| 320 | + | f.trees["wayland"]["1.0.1"] = map[string]string{ | |||
| 321 | + | "protocol/wayland.xml": xmlDoc("wayland", true, "wl_surface:6", "wl_seat:9"), | |||
| 322 | + | } | |||
| 323 | + | f.latest["wayland-protocols"] = "1.1" | |||
| 324 | + | f.latest["wayland"] = "1.0.1" | |||
| 325 | + | ||||
| 326 | + | notesFile := filepath.Join(t.TempDir(), "notes.md") | |||
| 327 | + | mustSync(t, root, f, options{notes: notesFile}) | |||
| 328 | + | n := readNotes(t, notesFile) | |||
| 329 | + | ||||
| 330 | + | for _, want := range []string{ | |||
| 331 | + | "## BREAKING", | |||
| 332 | + | "- old: package removed", | |||
| 333 | + | "- foo: major replacement, wayland-protocols:staging/foo/foo-v1.xml → wayland-protocols:staging/foo/foo-v2.xml", | |||
| 334 | + | "- foo: interface foo_manager_v1 removed", | |||
| 335 | + | "## Sources", | |||
| 336 | + | "- wayland-protocols: 1.0 → 1.1", | |||
| 337 | + | "- wayland: 1.0.0 → 1.0.1", | |||
| 338 | + | "## Added packages", | |||
| 339 | + | "- `bar`", | |||
| 340 | + | "## Removed packages", | |||
| 341 | + | "- `old`", | |||
| 342 | + | "## New interfaces", | |||
| 343 | + | "- xdgshell: xdg_popup (v5)", | |||
| 344 | + | "## Interface version bumps", | |||
| 345 | + | "- xdgshell: xdg_wm_base v5 → v6", | |||
| 346 | + | } { | |||
| 347 | + | if !strings.Contains(n, want) { | |||
| 348 | + | t.Errorf("notes missing %q:\n%s", want, n) | |||
| 349 | + | } | |||
| 350 | + | } | |||
| 351 | + | if strings.Contains(n, "get_surface") { | |||
| 352 | + | t.Errorf("unchanged message reported:\n%s", n) | |||
| 353 | + | } | |||
| 354 | + | // Stale XML removed, new XML present. | |||
| 355 | + | if _, err := os.Stat(filepath.Join(root, "spec", "xml", "old.xml")); err == nil { | |||
| 356 | + | t.Error("stale old.xml not removed") | |||
| 357 | + | } | |||
| 358 | + | if _, err := os.Stat(filepath.Join(root, "spec", "xml", "bar.xml")); err != nil { | |||
| 359 | + | t.Error("bar.xml missing") | |||
| 360 | + | } | |||
| 361 | + | m := loadRoot(t, root) | |||
| 362 | + | if foo, _ := m.Package("foo"); foo.Path != "staging/foo/foo-v2.xml" { | |||
| 363 | + | t.Errorf("foo path = %s", foo.Path) | |||
| 364 | + | } | |||
| 365 | + | ||||
| 366 | + | // Rerun against the same upstream: zero changes, notes say so. | |||
| 367 | + | if got := mustSync(t, root, f, options{notes: notesFile}); got != "changed=false" { | |||
| 368 | + | t.Errorf("rerun output %q", got) | |||
| 369 | + | } | |||
| 370 | + | if n := readNotes(t, notesFile); !strings.Contains(n, "No changes.") { | |||
| 371 | + | t.Errorf("notes for unchanged sync:\n%s", n) | |||
| 372 | + | } | |||
| 373 | + | } | |||
| 374 | + | ||||
| 375 | + | func TestBreakingMessageChanges(t *testing.T) { | |||
| 376 | + | root := t.TempDir() | |||
| 377 | + | f := baseFetcher() | |||
| 378 | + | mustSync(t, root, f, options{}) | |||
| 379 | + | ||||
| 380 | + | f.trees["wayland-protocols"]["1.1"] = map[string]string{ | |||
| 381 | + | "stable/xdg-shell/xdg-shell.xml": xmlDoc("xdg_shell", true, | |||
| 382 | + | // get_surface: arg 2 interface changes; surface type kept. | |||
| 383 | + | "xdg_wm_base:5|get_surface(id:new_id:xdg_surface,surface:object:wl_seat)|extra(a:int)", | |||
| 384 | + | // xdg_surface unchanged. | |||
| 385 | + | "xdg_surface:5"), | |||
| 386 | + | "staging/foo/foo-v1.xml": xmlDoc("foo", true, | |||
| 387 | + | // make: arg count changes. | |||
| 388 | + | "foo_manager_v1:1|make(seat:object:wl_seat,n:uint)"), | |||
| 389 | + | "unstable/old/old-unstable-v1.xml": xmlDoc("old", true, | |||
| 390 | + | // poke removed, arg type of nothing; new request added. | |||
| 391 | + | "old_thing_v1:1|prod(n:uint)"), | |||
| 392 | + | } | |||
| 393 | + | f.latest["wayland-protocols"] = "1.1" | |||
| 394 | + | notesFile := filepath.Join(t.TempDir(), "notes.md") | |||
| 395 | + | mustSync(t, root, f, options{notes: notesFile}) | |||
| 396 | + | n := readNotes(t, notesFile) | |||
| 397 | + | for _, want := range []string{ | |||
| 398 | + | "- xdgshell: xdg_wm_base request get_surface arguments changed: #2 surface:object<wl_surface> → surface:object<wl_seat>", | |||
| 399 | + | "- foo: foo_manager_v1 request make arguments changed: 1 → 2 arguments", | |||
| 400 | + | "- old: old_thing_v1 request poke removed", | |||
| 401 | + | } { | |||
| 402 | + | if !strings.Contains(n, want) { | |||
| 403 | + | t.Errorf("notes missing %q:\n%s", want, n) | |||
| 404 | + | } | |||
| 405 | + | } | |||
| 406 | + | if strings.Contains(n, "request extra") || strings.Contains(n, "prod") { | |||
| 407 | + | t.Errorf("added requests must not be breaking:\n%s", n) | |||
| 408 | + | } | |||
| 409 | + | } | |||
| 410 | + | ||||
| 411 | + | func TestBreakingEventAndRename(t *testing.T) { | |||
| 412 | + | old := &spec.Protocol{Interfaces: []spec.Interface{{ | |||
| 413 | + | Name: "a", | |||
| 414 | + | Events: []spec.Message{{Name: "e", Args: []spec.Arg{{Name: "x", Type: "int"}}}}, | |||
| 415 | + | }}} | |||
| 416 | + | cur := &spec.Protocol{Interfaces: []spec.Interface{{ | |||
| 417 | + | Name: "a", | |||
| 418 | + | Events: []spec.Message{{Name: "e", Args: []spec.Arg{{Name: "y", Type: "int"}}}, {Name: "f"}}, | |||
| 419 | + | }}} | |||
| 420 | + | n := ¬es{} | |||
| 421 | + | diffProtocol(n, "p", old, cur) | |||
| 422 | + | if len(n.breaking) != 1 || !strings.Contains(n.breaking[0], "event e arguments changed: #1 x:int → y:int") { | |||
| 423 | + | t.Errorf("breaking = %v", n.breaking) | |||
| 424 | + | } | |||
| 425 | + | n = ¬es{} | |||
| 426 | + | diffProtocol(n, "p", cur, old) | |||
| 427 | + | if len(n.breaking) != 2 || !strings.Contains(n.breaking[1], "event f removed") { | |||
| 428 | + | t.Errorf("breaking = %v", n.breaking) | |||
| 429 | + | } | |||
| 430 | + | } | |||
| 431 | + | ||||
| 432 | + | func TestSelectionRule(t *testing.T) { | |||
| 433 | + | cases := []struct { | |||
| 434 | + | name string | |||
| 435 | + | files map[string]string | |||
| 436 | + | want string // selected path | |||
| 437 | + | }{ | |||
| 438 | + | { | |||
| 439 | + | name: "stable beats staging beats unstable", | |||
| 440 | + | files: map[string]string{ | |||
| 441 | + | "stable/s/foo.xml": xmlDoc("a", true, "a_s:1"), | |||
| 442 | + | "staging/s/foo-v3.xml": xmlDoc("b", true, "b_s:1"), | |||
| 443 | + | "unstable/s/foo-unstable-v4.xml": xmlDoc("c", true, "c_s:1"), | |||
| 444 | + | }, | |||
| 445 | + | want: "stable/s/foo.xml", | |||
| 446 | + | }, | |||
| 447 | + | { | |||
| 448 | + | name: "higher major wins within a stability", | |||
| 449 | + | files: map[string]string{ | |||
| 450 | + | "staging/s/foo-v1.xml": xmlDoc("a", true, "a_s:1"), | |||
| 451 | + | "staging/s/foo-v2.xml": xmlDoc("b", true, "b_s:1"), | |||
| 452 | + | "staging/s/foo-v10.xml": xmlDoc("c", true, "c_s:1"), | |||
| 453 | + | }, | |||
| 454 | + | want: "staging/s/foo-v10.xml", | |||
| 455 | + | }, | |||
| 456 | + | { | |||
| 457 | + | name: "no suffix counts as v1", | |||
| 458 | + | files: map[string]string{ | |||
| 459 | + | "staging/s/foo.xml": xmlDoc("a", true, "a_s:1"), | |||
| 460 | + | "staging/s/foo-v2.xml": xmlDoc("b", true, "b_s:1"), | |||
| 461 | + | }, | |||
| 462 | + | want: "staging/s/foo-v2.xml", | |||
| 463 | + | }, | |||
| 464 | + | { | |||
| 465 | + | name: "unstable suffix dropped before version", | |||
| 466 | + | files: map[string]string{ | |||
| 467 | + | "unstable/s/foo-unstable-v1.xml": xmlDoc("a", true, "a_s:1"), | |||
| 468 | + | "staging/s/foo-v1.xml": xmlDoc("b", true, "b_s:1"), | |||
| 469 | + | }, | |||
| 470 | + | want: "staging/s/foo-v1.xml", | |||
| 471 | + | }, | |||
| 472 | + | } | |||
| 473 | + | for _, tc := range cases { | |||
| 474 | + | t.Run(tc.name, func(t *testing.T) { | |||
| 475 | + | f := &fakeFetcher{ | |||
| 476 | + | trees: map[string]map[string]map[string]string{"wayland-protocols": {"1.0": tc.files}}, | |||
| 477 | + | latest: map[string]string{"wayland-protocols": "1.0"}, | |||
| 478 | + | } | |||
| 479 | + | root := t.TempDir() | |||
| 480 | + | src := testSources()[1:] | |||
| 481 | + | if err := run(options{root: root}, src, f, &bytes.Buffer{}); err != nil { | |||
| 482 | + | t.Fatal(err) | |||
| 483 | + | } | |||
| 484 | + | e, ok := loadRoot(t, root).Package("foo") | |||
| 485 | + | if !ok || e.Path != tc.want { | |||
| 486 | + | t.Errorf("selected %q, want %q", e.Path, tc.want) | |||
| 487 | + | } | |||
| 488 | + | }) | |||
| 489 | + | } | |||
| 490 | + | } | |||
| 491 | + | ||||
| 492 | + | func TestCollisions(t *testing.T) { | |||
| 493 | + | cases := []struct { | |||
| 494 | + | name string | |||
| 495 | + | files map[string]string | |||
| 496 | + | wantErr string | |||
| 497 | + | }{ | |||
| 498 | + | { | |||
| 499 | + | name: "tie on stability and major", | |||
| 500 | + | files: map[string]string{ | |||
| 501 | + | "stable/a/foo-v1.xml": xmlDoc("a", true, "a_s:1"), | |||
| 502 | + | "stable/b/foo.xml": xmlDoc("b", true, "b_s:1"), | |||
| 503 | + | }, | |||
| 504 | + | wantErr: `package "foo"`, | |||
| 505 | + | }, | |||
| 506 | + | { | |||
| 507 | + | name: "same interface in two packages", | |||
| 508 | + | files: map[string]string{ | |||
| 509 | + | "stable/a/foo.xml": xmlDoc("a", true, "shared:1"), | |||
| 510 | + | "stable/b/bar.xml": xmlDoc("b", true, "shared:1"), | |||
| 511 | + | }, | |||
| 512 | + | wantErr: `interface "shared" is defined by both`, | |||
| 513 | + | }, | |||
| 514 | + | { | |||
| 515 | + | name: "missing copyright", | |||
| 516 | + | files: map[string]string{ | |||
| 517 | + | "stable/a/foo.xml": xmlDoc("a", false, "a_s:1"), | |||
| 518 | + | }, | |||
| 519 | + | wantErr: "missing <copyright>", | |||
| 520 | + | }, | |||
| 521 | + | { | |||
| 522 | + | name: "unparsable xml", | |||
| 523 | + | files: map[string]string{ | |||
| 524 | + | "stable/a/foo.xml": "<protocol", | |||
| 525 | + | }, | |||
| 526 | + | wantErr: "foo.xml", | |||
| 527 | + | }, | |||
| 528 | + | { | |||
| 529 | + | name: "unknown referenced interface", | |||
| 530 | + | files: map[string]string{ | |||
| 531 | + | "stable/a/foo.xml": xmlDoc("a", true, "a_s:1|r(x:object:ghost)"), | |||
| 532 | + | }, | |||
| 533 | + | wantErr: `unknown interface "ghost"`, | |||
| 534 | + | }, | |||
| 535 | + | } | |||
| 536 | + | for _, tc := range cases { | |||
| 537 | + | t.Run(tc.name, func(t *testing.T) { | |||
| 538 | + | f := &fakeFetcher{ | |||
| 539 | + | trees: map[string]map[string]map[string]string{"wayland-protocols": {"1.0": tc.files}}, | |||
| 540 | + | latest: map[string]string{"wayland-protocols": "1.0"}, | |||
| 541 | + | } | |||
| 542 | + | root := t.TempDir() | |||
| 543 | + | err := run(options{root: root}, testSources()[1:], f, &bytes.Buffer{}) | |||
| 544 | + | if err == nil || !strings.Contains(err.Error(), tc.wantErr) { | |||
| 545 | + | t.Fatalf("error = %v, want containing %q", err, tc.wantErr) | |||
| 546 | + | } | |||
| 547 | + | if len(snapshot(t, root)) != 0 { | |||
| 548 | + | t.Error("files written despite error") | |||
| 549 | + | } | |||
| 550 | + | }) | |||
| 551 | + | } | |||
| 552 | + | } | |||
| 553 | + | ||||
| 554 | + | func TestErrorsLeaveSpecUntouched(t *testing.T) { | |||
| 555 | + | root := t.TempDir() | |||
| 556 | + | f := baseFetcher() | |||
| 557 | + | mustSync(t, root, f, options{}) | |||
| 558 | + | before := snapshot(t, root) | |||
| 559 | + | ||||
| 560 | + | f.trees["wayland-protocols"]["1.1"] = map[string]string{ | |||
| 561 | + | "stable/xdg-shell/xdg-shell.xml": xmlDoc("xdg_shell", false, "xdg_wm_base:5"), | |||
| 562 | + | } | |||
| 563 | + | f.latest["wayland-protocols"] = "1.1" | |||
| 564 | + | if _, err := syncOnce(t, root, f, options{}); err == nil { | |||
| 565 | + | t.Fatal("expected error") | |||
| 566 | + | } | |||
| 567 | + | if !reflect.DeepEqual(before, snapshot(t, root)) { | |||
| 568 | + | t.Error("spec/ modified after failed sync") | |||
| 569 | + | } | |||
| 570 | + | ||||
| 571 | + | // Unknown ref is an error too. | |||
| 572 | + | if _, err := syncOnce(t, root, f, options{pinFile: writePins(t, `{"wayland":"9.9.9"}`)}); err == nil { | |||
| 573 | + | t.Error("expected error for unknown pin") | |||
| 574 | + | } | |||
| 575 | + | } | |||
| 576 | + | ||||
| 577 | + | func writePins(t *testing.T, content string) string { | |||
| 578 | + | t.Helper() | |||
| 579 | + | p := filepath.Join(t.TempDir(), "pins.json") | |||
| 580 | + | if err := os.WriteFile(p, []byte(content), 0o644); err != nil { | |||
| 581 | + | t.Fatal(err) | |||
| 582 | + | } | |||
| 583 | + | return p | |||
| 584 | + | } | |||
| 585 | + | ||||
| 586 | + | func TestPinFile(t *testing.T) { | |||
| 587 | + | root := t.TempDir() | |||
| 588 | + | f := baseFetcher() | |||
| 589 | + | f.trees["wayland-protocols"]["1.1"] = map[string]string{ | |||
| 590 | + | "stable/xdg-shell/xdg-shell.xml": xmlDoc("xdg_shell", true, "xdg_wm_base:6"), | |||
| 591 | + | } | |||
| 592 | + | f.latest["wayland-protocols"] = "1.1" | |||
| 593 | + | ||||
| 594 | + | // Pin to the older ref although 1.1 is latest. | |||
| 595 | + | mustSync(t, root, f, options{pinFile: writePins(t, `{"wayland-protocols":"1.0"}`)}) | |||
| 596 | + | m := loadRoot(t, root) | |||
| 597 | + | if m.Sources[1].Ref != "1.0" { | |||
| 598 | + | t.Errorf("ref = %s, want pinned 1.0", m.Sources[1].Ref) | |||
| 599 | + | } | |||
| 600 | + | if e, _ := m.Package("xdgshell"); e.Interfaces[0].Version != 5 && e.Interfaces[1].Version != 5 { | |||
| 601 | + | t.Errorf("pinned content not used: %+v", e) | |||
| 602 | + | } | |||
| 603 | + | ||||
| 604 | + | // Without the pin the latest is used. | |||
| 605 | + | mustSync(t, root, f, options{}) | |||
| 606 | + | if got := loadRoot(t, root).Sources[1].Ref; got != "1.1" { | |||
| 607 | + | t.Errorf("ref = %s, want 1.1", got) | |||
| 608 | + | } | |||
| 609 | + | ||||
| 610 | + | if _, err := syncOnce(t, root, f, options{pinFile: writePins(t, `{"nope":"1"}`)}); err == nil || !strings.Contains(err.Error(), "unknown source") { | |||
| 611 | + | t.Errorf("unknown source error = %v", err) | |||
| 612 | + | } | |||
| 613 | + | if _, err := syncOnce(t, root, f, options{pinFile: writePins(t, `[`)}); err == nil { | |||
| 614 | + | t.Error("expected decode error") | |||
| 615 | + | } | |||
| 616 | + | } | |||
| 617 | + | ||||
| 618 | + | func TestInitialPinsFile(t *testing.T) { | |||
| 619 | + | pins, err := loadPins("testdata/initial-pins.json", defaultSources()) | |||
| 620 | + | if err != nil { | |||
| 621 | + | t.Fatal(err) | |||
| 622 | + | } | |||
| 623 | + | want := map[string]string{ | |||
| 624 | + | "wayland": "1.26.0", | |||
| 625 | + | "wayland-protocols": "1.49", | |||
| 626 | + | "wlr-protocols": "bf4fc79abc359eea5a0edec0ac6d4a2b2955f82a", | |||
| 627 | + | "wlroots": "0.20.2", | |||
| 628 | + | "plasma-wayland-protocols": "v1.23.0", | |||
| 629 | + | } | |||
| 630 | + | if !reflect.DeepEqual(pins, want) { | |||
| 631 | + | t.Errorf("pins = %v", pins) | |||
| 632 | + | } | |||
| 633 | + | } | |||
| 634 | + | ||||
| 635 | + | func TestNoXMLFound(t *testing.T) { | |||
| 636 | + | f := &fakeFetcher{ | |||
| 637 | + | trees: map[string]map[string]map[string]string{"wayland": {"1.0.0": {"README": "x"}}}, | |||
| 638 | + | latest: map[string]string{"wayland": "1.0.0"}, | |||
| 639 | + | } | |||
| 640 | + | err := run(options{root: t.TempDir()}, testSources()[:1], f, &bytes.Buffer{}) | |||
| 641 | + | if err == nil || !strings.Contains(err.Error(), "no protocol XML") { | |||
| 642 | + | t.Errorf("error = %v", err) | |||
| 643 | + | } | |||
| 644 | + | } | |||
| 645 | + | ||||
| 646 | + | func TestSourceTable(t *testing.T) { | |||
| 647 | + | got := map[string]upstream{} | |||
| 648 | + | for _, s := range defaultSources() { | |||
| 649 | + | got[s.ID] = s | |||
| 650 | + | } | |||
| 651 | + | urls := map[string]string{ | |||
| 652 | + | "wayland": "https://gitlab.freedesktop.org/wayland/wayland.git", | |||
| 653 | + | "wayland-protocols": "https://gitlab.freedesktop.org/wayland/wayland-protocols.git", | |||
| 654 | + | "wlr-protocols": "https://gitlab.freedesktop.org/wlroots/wlr-protocols.git", | |||
| 655 | + | "wlroots": "https://gitlab.freedesktop.org/wlroots/wlroots.git", | |||
| 656 | + | "plasma-wayland-protocols": "https://invent.kde.org/libraries/plasma-wayland-protocols.git", | |||
| 657 | + | } | |||
| 658 | + | for id, url := range urls { | |||
| 659 | + | if got[id].URL != url { | |||
| 660 | + | t.Errorf("%s url = %q", id, got[id].URL) | |||
| 661 | + | } | |||
| 662 | + | } | |||
| 663 | + | if len(got) != len(urls) { | |||
| 664 | + | t.Errorf("%d sources", len(got)) | |||
| 665 | + | } | |||
| 666 | + | if s := got["wlr-protocols"]; s.Kind != PinBranch || s.Branch != "master" { | |||
| 667 | + | t.Errorf("wlr-protocols = %+v", s) | |||
| 668 | + | } | |||
| 669 | + | ||||
| 670 | + | type m struct { | |||
| 671 | + | id, path string | |||
| 672 | + | ok bool | |||
| 673 | + | st Stability | |||
| 674 | + | } | |||
| 675 | + | for _, c := range []m{ | |||
| 676 | + | {"wayland", "protocol/wayland.xml", true, Stable}, | |||
| 677 | + | {"wayland", "protocol/other.xml", false, 0}, | |||
| 678 | + | {"wayland-protocols", "stable/xdg-shell/xdg-shell.xml", true, Stable}, | |||
| 679 | + | {"wayland-protocols", "staging/xdg-dialog/xdg-dialog-v1.xml", true, Staging}, | |||
| 680 | + | {"wayland-protocols", "unstable/tablet/tablet-unstable-v2.xml", true, Unstable}, | |||
| 681 | + | {"wayland-protocols", "stable/tests/x.xml", false, 0}, | |||
| 682 | + | {"wayland-protocols", "staging/experimental/x.xml", false, 0}, | |||
| 683 | + | {"wayland-protocols", "experimental/xx-shell/xx-shell-v1.xml", false, 0}, | |||
| 684 | + | {"wayland-protocols", "stable/xdg-shell/README.md", false, 0}, | |||
| 685 | + | {"wlr-protocols", "unstable/wlr-layer-shell-unstable-v1.xml", true, Unstable}, | |||
| 686 | + | {"wlr-protocols", "unstable/sub/x.xml", false, 0}, | |||
| 687 | + | {"wlr-protocols", "stable/x.xml", false, 0}, | |||
| 688 | + | {"wlroots", "protocol/input-method-unstable-v2.xml", true, Unstable}, | |||
| 689 | + | {"wlroots", "protocol/virtual-keyboard-unstable-v1.xml", true, Unstable}, | |||
| 690 | + | {"wlroots", "protocol/wlr-layer-shell-unstable-v1.xml", false, 0}, | |||
| 691 | + | {"plasma-wayland-protocols", "src/protocols/server-decoration.xml", true, Unstable}, | |||
| 692 | + | {"plasma-wayland-protocols", "src/protocols/idle.xml", false, 0}, | |||
| 693 | + | } { | |||
| 694 | + | st, ok := got[c.id].Match(c.path) | |||
| 695 | + | if ok != c.ok || st != c.st { | |||
| 696 | + | t.Errorf("%s Match(%q) = %v,%v want %v,%v", c.id, c.path, st, ok, c.st, c.ok) | |||
| 697 | + | } | |||
| 698 | + | } | |||
| 699 | + | } | |||
| 700 | + | ||||
| 701 | + | func TestTagSelection(t *testing.T) { | |||
| 702 | + | tags := map[string]string{} | |||
| 703 | + | for _, tg := range []string{"1.2.0", "1.10.0", "1.10.90", "1.11.91", "1.11.1", "1.9.0", "1.9.95", "1.10.0-rc1", "v1.12.0", "1.27.0-rc1"} { | |||
| 704 | + | tags[tg] = "sha-" + tg | |||
| 705 | + | } | |||
| 706 | + | var wayland, protocols, plasma upstream | |||
| 707 | + | for _, s := range defaultSources() { | |||
| 708 | + | switch s.ID { | |||
| 709 | + | case "wayland": | |||
| 710 | + | wayland = s | |||
| 711 | + | case "wayland-protocols": | |||
| 712 | + | protocols = s | |||
| 713 | + | case "plasma-wayland-protocols": | |||
| 714 | + | plasma = s | |||
| 715 | + | } | |||
| 716 | + | } | |||
| 717 | + | // Even minor or patch<90: 1.10.90 allowed (even minor), 1.11.91 and 1.9.95 are not, | |||
| 718 | + | // 1.11.1 is. Numeric compare: 1.10.90 > 1.11.1? No: 1.11.1 > 1.10.90. | |||
| 719 | + | if got, err := latestTag(wayland, tags); err != nil || got != "1.11.1" { | |||
| 720 | + | t.Errorf("wayland latest = %q, %v", got, err) | |||
| 721 | + | } | |||
| 722 | + | delete(tags, "1.11.1") | |||
| 723 | + | if got, _ := latestTag(wayland, tags); got != "1.10.90" { | |||
| 724 | + | t.Errorf("wayland latest = %q", got) | |||
| 725 | + | } | |||
| 726 | + | ||||
| 727 | + | if got, err := latestTag(protocols, map[string]string{"1.9": "a", "1.10": "b", "1.49": "c", "1.49.1": "d", "v1.50": "e"}); err != nil || got != "1.49" { | |||
| 728 | + | t.Errorf("wayland-protocols latest = %q, %v", got, err) | |||
| 729 | + | } | |||
| 730 | + | if got, err := latestTag(plasma, map[string]string{"v1.9.0": "a", "v1.23.0": "b", "1.99.0": "c"}); err != nil || got != "v1.23.0" { | |||
| 731 | + | t.Errorf("plasma latest = %q, %v", got, err) | |||
| 732 | + | } | |||
| 733 | + | if _, err := latestTag(plasma, map[string]string{"1.0.0": "a"}); err == nil { | |||
| 734 | + | t.Error("expected error when no tag matches") | |||
| 735 | + | } | |||
| 736 | + | } | |||
| 737 | + | ||||
| 738 | + | func TestParseLsRemote(t *testing.T) { | |||
| 739 | + | out := strings.Join([]string{ | |||
| 740 | + | "aaaa\trefs/heads/master", | |||
| 741 | + | "bbbb\trefs/tags/1.0", | |||
| 742 | + | "cccc\trefs/tags/1.0^{}", | |||
| 743 | + | "dddd\trefs/tags/1.1", | |||
| 744 | + | "", | |||
| 745 | + | }, "\n") | |||
| 746 | + | tags, heads := parseLsRemote(out) | |||
| 747 | + | if want := map[string]string{"1.0": "cccc", "1.1": "dddd"}; !reflect.DeepEqual(tags, want) { | |||
| 748 | + | t.Errorf("tags = %v (annotated tags must resolve to the peeled commit)", tags) | |||
| 749 | + | } | |||
| 750 | + | if want := map[string]string{"master": "aaaa"}; !reflect.DeepEqual(heads, want) { | |||
| 751 | + | t.Errorf("heads = %v", heads) | |||
| 752 | + | } | |||
| 753 | + | // Peeled line before the tag object line. | |||
| 754 | + | tags, _ = parseLsRemote("cccc\trefs/tags/2.0^{}\nbbbb\trefs/tags/2.0") | |||
| 755 | + | if tags["2.0"] != "cccc" { | |||
| 756 | + | t.Errorf("tags = %v", tags) | |||
| 757 | + | } | |||
| 758 | + | } | |||
| 759 | + | ||||
| 760 | + | func TestFileMajorAndVersions(t *testing.T) { | |||
| 761 | + | for in, want := range map[string]int{ | |||
| 762 | + | "foo.xml": 1, "foo-v2.xml": 2, "stable/x/foo-unstable-v3.xml": 3, "a-v12.xml": 12, "v2-thing.xml": 1, | |||
| 763 | + | } { | |||
| 764 | + | if got := fileMajor(in); got != want { | |||
| 765 | + | t.Errorf("fileMajor(%q) = %d, want %d", in, got, want) | |||
| 766 | + | } | |||
| 767 | + | } | |||
| 768 | + | vs := []string{"1.10", "1.2", "1.9"} | |||
| 769 | + | sort.Slice(vs, func(i, j int) bool { return compareVersions(vs[i], vs[j]) < 0 }) | |||
| 770 | + | if !reflect.DeepEqual(vs, []string{"1.2", "1.9", "1.10"}) { | |||
| 771 | + | t.Errorf("sorted = %v", vs) | |||
| 772 | + | } | |||
| 773 | + | if compareVersions("v1.2.3", "1.2.3") != 0 { | |||
| 774 | + | t.Error("v prefix should be ignored") | |||
| 775 | + | } | |||
| 776 | + | } | |||
A cmd/wlbsync/testdata/initial-pins.json +7 -0
| @@ -0,0 +1,7 @@ | |||||
| 1 | + | { | |||
| 2 | + | "wayland": "1.26.0", | |||
| 3 | + | "wayland-protocols": "1.49", | |||
| 4 | + | "wlr-protocols": "bf4fc79abc359eea5a0edec0ac6d4a2b2955f82a", | |||
| 5 | + | "wlroots": "0.20.2", | |||
| 6 | + | "plasma-wayland-protocols": "v1.23.0" | |||
| 7 | + | } | |||
M spec/manifest.json +1614 -2
| @@ -1,4 +1,1616 @@ | |||||
| 1 | { | 1 | { | ||
| 2 | - | "sources": [], | 2 | + | "sources": [ |
| 3 | - | "protocols": [] | 3 | + | { |
| 4 | + | "id": "plasma-wayland-protocols", | |||
| 5 | + | "url": "https://invent.kde.org/libraries/plasma-wayland-protocols.git", | |||
| 6 | + | "ref": "v1.23.0", | |||
| 7 | + | "commit": "c5ac4db818f4a575a6ccfe0065b73ecfaba6e93e" | |||
| 8 | + | }, | |||
| 9 | + | { | |||
| 10 | + | "id": "wayland", | |||
| 11 | + | "url": "https://gitlab.freedesktop.org/wayland/wayland.git", | |||
| 12 | + | "ref": "1.26.0", | |||
| 13 | + | "commit": "87cc8a8728a923fc57938faa81ba0e74f34ecdc7" | |||
| 14 | + | }, | |||
| 15 | + | { | |||
| 16 | + | "id": "wayland-protocols", | |||
| 17 | + | "url": "https://gitlab.freedesktop.org/wayland/wayland-protocols.git", | |||
| 18 | + | "ref": "1.49", | |||
| 19 | + | "commit": "ee78491a237eaff9389a0ccf8680521d074407d3" | |||
| 20 | + | }, | |||
| 21 | + | { | |||
| 22 | + | "id": "wlr-protocols", | |||
| 23 | + | "url": "https://gitlab.freedesktop.org/wlroots/wlr-protocols.git", | |||
| 24 | + | "ref": "master", | |||
| 25 | + | "commit": "bf4fc79abc359eea5a0edec0ac6d4a2b2955f82a" | |||
| 26 | + | }, | |||
| 27 | + | { | |||
| 28 | + | "id": "wlroots", | |||
| 29 | + | "url": "https://gitlab.freedesktop.org/wlroots/wlroots.git", | |||
| 30 | + | "ref": "0.20.2", | |||
| 31 | + | "commit": "d783533489e1f75d6886c2ab5c5960090ef268f8" | |||
| 32 | + | } | |||
| 33 | + | ], | |||
| 34 | + | "protocols": [ | |||
| 35 | + | { | |||
| 36 | + | "package": "alphamodifier", | |||
| 37 | + | "xml": "alphamodifier.xml", | |||
| 38 | + | "source": "wayland-protocols", | |||
| 39 | + | "path": "staging/alpha-modifier/alpha-modifier-v1.xml", | |||
| 40 | + | "sha256": "f0b4a43b9e48783fafdb46319fa72b34a41afd932f8613d7cadaf7203f2ffa35", | |||
| 41 | + | "license": "MIT", | |||
| 42 | + | "interfaces": [ | |||
| 43 | + | { | |||
| 44 | + | "name": "wp_alpha_modifier_surface_v1", | |||
| 45 | + | "version": 1 | |||
| 46 | + | }, | |||
| 47 | + | { | |||
| 48 | + | "name": "wp_alpha_modifier_v1", | |||
| 49 | + | "version": 1 | |||
| 50 | + | } | |||
| 51 | + | ], | |||
| 52 | + | "deps": [ | |||
| 53 | + | "wayland" | |||
| 54 | + | ] | |||
| 55 | + | }, | |||
| 56 | + | { | |||
| 57 | + | "package": "colormanagement", | |||
| 58 | + | "xml": "colormanagement.xml", | |||
| 59 | + | "source": "wayland-protocols", | |||
| 60 | + | "path": "staging/color-management/color-management-v1.xml", | |||
| 61 | + | "sha256": "18a2678e3352c3be3fbeed20005d48852b7235d0d78f08b9c987a0b8e91449f9", | |||
| 62 | + | "license": "MIT", | |||
| 63 | + | "interfaces": [ | |||
| 64 | + | { | |||
| 65 | + | "name": "wp_color_management_output_v1", | |||
| 66 | + | "version": 3 | |||
| 67 | + | }, | |||
| 68 | + | { | |||
| 69 | + | "name": "wp_color_management_surface_feedback_v1", | |||
| 70 | + | "version": 3 | |||
| 71 | + | }, | |||
| 72 | + | { | |||
| 73 | + | "name": "wp_color_management_surface_v1", | |||
| 74 | + | "version": 3 | |||
| 75 | + | }, | |||
| 76 | + | { | |||
| 77 | + | "name": "wp_color_manager_v1", | |||
| 78 | + | "version": 3 | |||
| 79 | + | }, | |||
| 80 | + | { | |||
| 81 | + | "name": "wp_image_description_creator_icc_v1", | |||
| 82 | + | "version": 3 | |||
| 83 | + | }, | |||
| 84 | + | { | |||
| 85 | + | "name": "wp_image_description_creator_params_v1", | |||
| 86 | + | "version": 3 | |||
| 87 | + | }, | |||
| 88 | + | { | |||
| 89 | + | "name": "wp_image_description_info_v1", | |||
| 90 | + | "version": 3 | |||
| 91 | + | }, | |||
| 92 | + | { | |||
| 93 | + | "name": "wp_image_description_reference_v1", | |||
| 94 | + | "version": 1 | |||
| 95 | + | }, | |||
| 96 | + | { | |||
| 97 | + | "name": "wp_image_description_v1", | |||
| 98 | + | "version": 3 | |||
| 99 | + | } | |||
| 100 | + | ], | |||
| 101 | + | "deps": [ | |||
| 102 | + | "wayland" | |||
| 103 | + | ] | |||
| 104 | + | }, | |||
| 105 | + | { | |||
| 106 | + | "package": "colorrepresentation", | |||
| 107 | + | "xml": "colorrepresentation.xml", | |||
| 108 | + | "source": "wayland-protocols", | |||
| 109 | + | "path": "staging/color-representation/color-representation-v1.xml", | |||
| 110 | + | "sha256": "b824688e0e5c1d01e12afe1d3f82503092ec7599affcd6471fda6d296d4f7e3b", | |||
| 111 | + | "license": "MIT", | |||
| 112 | + | "interfaces": [ | |||
| 113 | + | { | |||
| 114 | + | "name": "wp_color_representation_manager_v1", | |||
| 115 | + | "version": 1 | |||
| 116 | + | }, | |||
| 117 | + | { | |||
| 118 | + | "name": "wp_color_representation_surface_v1", | |||
| 119 | + | "version": 1 | |||
| 120 | + | } | |||
| 121 | + | ], | |||
| 122 | + | "deps": [ | |||
| 123 | + | "wayland" | |||
| 124 | + | ] | |||
| 125 | + | }, | |||
| 126 | + | { | |||
| 127 | + | "package": "committiming", | |||
| 128 | + | "xml": "committiming.xml", | |||
| 129 | + | "source": "wayland-protocols", | |||
| 130 | + | "path": "staging/commit-timing/commit-timing-v1.xml", | |||
| 131 | + | "sha256": "ff3fcf31d13d44bad756a50fda663a43008bacbbd2bf8cba3a1bf5ffe7f54172", | |||
| 132 | + | "license": "MIT", | |||
| 133 | + | "interfaces": [ | |||
| 134 | + | { | |||
| 135 | + | "name": "wp_commit_timer_v1", | |||
| 136 | + | "version": 1 | |||
| 137 | + | }, | |||
| 138 | + | { | |||
| 139 | + | "name": "wp_commit_timing_manager_v1", | |||
| 140 | + | "version": 1 | |||
| 141 | + | } | |||
| 142 | + | ], | |||
| 143 | + | "deps": [ | |||
| 144 | + | "wayland" | |||
| 145 | + | ] | |||
| 146 | + | }, | |||
| 147 | + | { | |||
| 148 | + | "package": "contenttype", | |||
| 149 | + | "xml": "contenttype.xml", | |||
| 150 | + | "source": "wayland-protocols", | |||
| 151 | + | "path": "staging/content-type/content-type-v1.xml", | |||
| 152 | + | "sha256": "203d17a26baa2ab4a8c2c9cb737c953fa3263c73a0a8aa6e552a41b3eac2196d", | |||
| 153 | + | "license": "MIT", | |||
| 154 | + | "interfaces": [ | |||
| 155 | + | { | |||
| 156 | + | "name": "wp_content_type_manager_v1", | |||
| 157 | + | "version": 1 | |||
| 158 | + | }, | |||
| 159 | + | { | |||
| 160 | + | "name": "wp_content_type_v1", | |||
| 161 | + | "version": 1 | |||
| 162 | + | } | |||
| 163 | + | ], | |||
| 164 | + | "deps": [ | |||
| 165 | + | "wayland" | |||
| 166 | + | ] | |||
| 167 | + | }, | |||
| 168 | + | { | |||
| 169 | + | "package": "cursorshape", | |||
| 170 | + | "xml": "cursorshape.xml", | |||
| 171 | + | "source": "wayland-protocols", | |||
| 172 | + | "path": "staging/cursor-shape/cursor-shape-v1.xml", | |||
| 173 | + | "sha256": "bb57d91e53a79dadab7c612dab87c233393cee73673feefa7442cfbfdd9aed2f", | |||
| 174 | + | "license": "MIT", | |||
| 175 | + | "interfaces": [ | |||
| 176 | + | { | |||
| 177 | + | "name": "wp_cursor_shape_device_v1", | |||
| 178 | + | "version": 2 | |||
| 179 | + | }, | |||
| 180 | + | { | |||
| 181 | + | "name": "wp_cursor_shape_manager_v1", | |||
| 182 | + | "version": 2 | |||
| 183 | + | } | |||
| 184 | + | ], | |||
| 185 | + | "deps": [ | |||
| 186 | + | "tablet", | |||
| 187 | + | "wayland" | |||
| 188 | + | ] | |||
| 189 | + | }, | |||
| 190 | + | { | |||
| 191 | + | "package": "drmlease", | |||
| 192 | + | "xml": "drmlease.xml", | |||
| 193 | + | "source": "wayland-protocols", | |||
| 194 | + | "path": "staging/drm-lease/drm-lease-v1.xml", | |||
| 195 | + | "sha256": "18f325e92285473eca0567ea1038abb16849b8638b36e458ff551f3ca68ef80c", | |||
| 196 | + | "license": "MIT", | |||
| 197 | + | "interfaces": [ | |||
| 198 | + | { | |||
| 199 | + | "name": "wp_drm_lease_connector_v1", | |||
| 200 | + | "version": 1 | |||
| 201 | + | }, | |||
| 202 | + | { | |||
| 203 | + | "name": "wp_drm_lease_device_v1", | |||
| 204 | + | "version": 1 | |||
| 205 | + | }, | |||
| 206 | + | { | |||
| 207 | + | "name": "wp_drm_lease_request_v1", | |||
| 208 | + | "version": 1 | |||
| 209 | + | }, | |||
| 210 | + | { | |||
| 211 | + | "name": "wp_drm_lease_v1", | |||
| 212 | + | "version": 1 | |||
| 213 | + | } | |||
| 214 | + | ], | |||
| 215 | + | "deps": [] | |||
| 216 | + | }, | |||
| 217 | + | { | |||
| 218 | + | "package": "extbackgroundeffect", | |||
| 219 | + | "xml": "extbackgroundeffect.xml", | |||
| 220 | + | "source": "wayland-protocols", | |||
| 221 | + | "path": "staging/ext-background-effect/ext-background-effect-v1.xml", | |||
| 222 | + | "sha256": "e463b7863c97d7be05489b52b15cd0b3a5d8290b51340f62023b47d03b4217e3", | |||
| 223 | + | "license": "MIT", | |||
| 224 | + | "interfaces": [ | |||
| 225 | + | { | |||
| 226 | + | "name": "ext_background_effect_manager_v1", | |||
| 227 | + | "version": 1 | |||
| 228 | + | }, | |||
| 229 | + | { | |||
| 230 | + | "name": "ext_background_effect_surface_v1", | |||
| 231 | + | "version": 1 | |||
| 232 | + | } | |||
| 233 | + | ], | |||
| 234 | + | "deps": [ | |||
| 235 | + | "wayland" | |||
| 236 | + | ] | |||
| 237 | + | }, | |||
| 238 | + | { | |||
| 239 | + | "package": "extdatacontrol", | |||
| 240 | + | "xml": "extdatacontrol.xml", | |||
| 241 | + | "source": "wayland-protocols", | |||
| 242 | + | "path": "staging/ext-data-control/ext-data-control-v1.xml", | |||
| 243 | + | "sha256": "293deba5dfdb974fbcf8dcf891a30a51a36a8bba0047dc6bdf6a03194089b7fb", | |||
| 244 | + | "license": "MIT", | |||
| 245 | + | "interfaces": [ | |||
| 246 | + | { | |||
| 247 | + | "name": "ext_data_control_device_v1", | |||
| 248 | + | "version": 1 | |||
| 249 | + | }, | |||
| 250 | + | { | |||
| 251 | + | "name": "ext_data_control_manager_v1", | |||
| 252 | + | "version": 1 | |||
| 253 | + | }, | |||
| 254 | + | { | |||
| 255 | + | "name": "ext_data_control_offer_v1", | |||
| 256 | + | "version": 1 | |||
| 257 | + | }, | |||
| 258 | + | { | |||
| 259 | + | "name": "ext_data_control_source_v1", | |||
| 260 | + | "version": 1 | |||
| 261 | + | } | |||
| 262 | + | ], | |||
| 263 | + | "deps": [ | |||
| 264 | + | "wayland" | |||
| 265 | + | ] | |||
| 266 | + | }, | |||
| 267 | + | { | |||
| 268 | + | "package": "extforeigntoplevellist", | |||
| 269 | + | "xml": "extforeigntoplevellist.xml", | |||
| 270 | + | "source": "wayland-protocols", | |||
| 271 | + | "path": "staging/ext-foreign-toplevel-list/ext-foreign-toplevel-list-v1.xml", | |||
| 272 | + | "sha256": "6b2ffb3a07d679d1c4170263adfefb9a7c37dd34ed3db5180bf58cb8ff8fbd0b", | |||
| 273 | + | "license": "MIT", | |||
| 274 | + | "interfaces": [ | |||
| 275 | + | { | |||
| 276 | + | "name": "ext_foreign_toplevel_handle_v1", | |||
| 277 | + | "version": 1 | |||
| 278 | + | }, | |||
| 279 | + | { | |||
| 280 | + | "name": "ext_foreign_toplevel_list_v1", | |||
| 281 | + | "version": 1 | |||
| 282 | + | } | |||
| 283 | + | ], | |||
| 284 | + | "deps": [] | |||
| 285 | + | }, | |||
| 286 | + | { | |||
| 287 | + | "package": "extidlenotify", | |||
| 288 | + | "xml": "extidlenotify.xml", | |||
| 289 | + | "source": "wayland-protocols", | |||
| 290 | + | "path": "staging/ext-idle-notify/ext-idle-notify-v1.xml", | |||
| 291 | + | "sha256": "e56a9c22684e6b46655f7221b798328e304c1efc8f63f01241a1cf8c070f4c30", | |||
| 292 | + | "license": "MIT", | |||
| 293 | + | "interfaces": [ | |||
| 294 | + | { | |||
| 295 | + | "name": "ext_idle_notification_v1", | |||
| 296 | + | "version": 2 | |||
| 297 | + | }, | |||
| 298 | + | { | |||
| 299 | + | "name": "ext_idle_notifier_v1", | |||
| 300 | + | "version": 2 | |||
| 301 | + | } | |||
| 302 | + | ], | |||
| 303 | + | "deps": [ | |||
| 304 | + | "wayland" | |||
| 305 | + | ] | |||
| 306 | + | }, | |||
| 307 | + | { | |||
| 308 | + | "package": "extimagecapturesource", | |||
| 309 | + | "xml": "extimagecapturesource.xml", | |||
| 310 | + | "source": "wayland-protocols", | |||
| 311 | + | "path": "staging/ext-image-capture-source/ext-image-capture-source-v1.xml", | |||
| 312 | + | "sha256": "4ef41d15e4cdb9f550158391358ceec724a6708b43b7efedec03121a6bb8458d", | |||
| 313 | + | "license": "MIT", | |||
| 314 | + | "interfaces": [ | |||
| 315 | + | { | |||
| 316 | + | "name": "ext_foreign_toplevel_image_capture_source_manager_v1", | |||
| 317 | + | "version": 1 | |||
| 318 | + | }, | |||
| 319 | + | { | |||
| 320 | + | "name": "ext_image_capture_source_v1", | |||
| 321 | + | "version": 1 | |||
| 322 | + | }, | |||
| 323 | + | { | |||
| 324 | + | "name": "ext_output_image_capture_source_manager_v1", | |||
| 325 | + | "version": 1 | |||
| 326 | + | } | |||
| 327 | + | ], | |||
| 328 | + | "deps": [ | |||
| 329 | + | "extforeigntoplevellist", | |||
| 330 | + | "wayland" | |||
| 331 | + | ] | |||
| 332 | + | }, | |||
| 333 | + | { | |||
| 334 | + | "package": "extimagecopycapture", | |||
| 335 | + | "xml": "extimagecopycapture.xml", | |||
| 336 | + | "source": "wayland-protocols", | |||
| 337 | + | "path": "staging/ext-image-copy-capture/ext-image-copy-capture-v1.xml", | |||
| 338 | + | "sha256": "41a446653f788fabb404cab3168c0bd667c1ff4b54f1f0bb1e18810a1f47d73f", | |||
| 339 | + | "license": "MIT", | |||
| 340 | + | "interfaces": [ | |||
| 341 | + | { | |||
| 342 | + | "name": "ext_image_copy_capture_cursor_session_v1", | |||
| 343 | + | "version": 1 | |||
| 344 | + | }, | |||
| 345 | + | { | |||
| 346 | + | "name": "ext_image_copy_capture_frame_v1", | |||
| 347 | + | "version": 1 | |||
| 348 | + | }, | |||
| 349 | + | { | |||
| 350 | + | "name": "ext_image_copy_capture_manager_v1", | |||
| 351 | + | "version": 1 | |||
| 352 | + | }, | |||
| 353 | + | { | |||
| 354 | + | "name": "ext_image_copy_capture_session_v1", | |||
| 355 | + | "version": 1 | |||
| 356 | + | } | |||
| 357 | + | ], | |||
| 358 | + | "deps": [ | |||
| 359 | + | "extimagecapturesource", | |||
| 360 | + | "wayland" | |||
| 361 | + | ] | |||
| 362 | + | }, | |||
| 363 | + | { | |||
| 364 | + | "package": "extsessionlock", | |||
| 365 | + | "xml": "extsessionlock.xml", | |||
| 366 | + | "source": "wayland-protocols", | |||
| 367 | + | "path": "staging/ext-session-lock/ext-session-lock-v1.xml", | |||
| 368 | + | "sha256": "a05df7d95c5e523e457037b3a149484e8064828cda66971f3c7caeb87d597a81", | |||
| 369 | + | "license": "MIT", | |||
| 370 | + | "interfaces": [ | |||
| 371 | + | { | |||
| 372 | + | "name": "ext_session_lock_manager_v1", | |||
| 373 | + | "version": 1 | |||
| 374 | + | }, | |||
| 375 | + | { | |||
| 376 | + | "name": "ext_session_lock_surface_v1", | |||
| 377 | + | "version": 1 | |||
| 378 | + | }, | |||
| 379 | + | { | |||
| 380 | + | "name": "ext_session_lock_v1", | |||
| 381 | + | "version": 1 | |||
| 382 | + | } | |||
| 383 | + | ], | |||
| 384 | + | "deps": [ | |||
| 385 | + | "wayland" | |||
| 386 | + | ] | |||
| 387 | + | }, | |||
| 388 | + | { | |||
| 389 | + | "package": "exttransientseat", | |||
| 390 | + | "xml": "exttransientseat.xml", | |||
| 391 | + | "source": "wayland-protocols", | |||
| 392 | + | "path": "staging/ext-transient-seat/ext-transient-seat-v1.xml", | |||
| 393 | + | "sha256": "d7d836047218030558bbd4e706e6a9b7e91338c4b2b637215be6a5d26da58d81", | |||
| 394 | + | "license": "MIT", | |||
| 395 | + | "interfaces": [ | |||
| 396 | + | { | |||
| 397 | + | "name": "ext_transient_seat_manager_v1", | |||
| 398 | + | "version": 1 | |||
| 399 | + | }, | |||
| 400 | + | { | |||
| 401 | + | "name": "ext_transient_seat_v1", | |||
| 402 | + | "version": 1 | |||
| 403 | + | } | |||
| 404 | + | ], | |||
| 405 | + | "deps": [] | |||
| 406 | + | }, | |||
| 407 | + | { | |||
| 408 | + | "package": "extworkspace", | |||
| 409 | + | "xml": "extworkspace.xml", | |||
| 410 | + | "source": "wayland-protocols", | |||
| 411 | + | "path": "staging/ext-workspace/ext-workspace-v1.xml", | |||
| 412 | + | "sha256": "9b449d9d5d40f6032eba9813d18093b84f249a2cf38d6755dec7bca7eb96b0f3", | |||
| 413 | + | "license": "MIT", | |||
| 414 | + | "interfaces": [ | |||
| 415 | + | { | |||
| 416 | + | "name": "ext_workspace_group_handle_v1", | |||
| 417 | + | "version": 1 | |||
| 418 | + | }, | |||
| 419 | + | { | |||
| 420 | + | "name": "ext_workspace_handle_v1", | |||
| 421 | + | "version": 1 | |||
| 422 | + | }, | |||
| 423 | + | { | |||
| 424 | + | "name": "ext_workspace_manager_v1", | |||
| 425 | + | "version": 1 | |||
| 426 | + | } | |||
| 427 | + | ], | |||
| 428 | + | "deps": [ | |||
| 429 | + | "wayland" | |||
| 430 | + | ] | |||
| 431 | + | }, | |||
| 432 | + | { | |||
| 433 | + | "package": "fifo", | |||
| 434 | + | "xml": "fifo.xml", | |||
| 435 | + | "source": "wayland-protocols", | |||
| 436 | + | "path": "staging/fifo/fifo-v1.xml", | |||
| 437 | + | "sha256": "0b6c31dfe6bca19b712745c9de7a4a398558cfa1087b1938e96fd3b10ffc1069", | |||
| 438 | + | "license": "MIT", | |||
| 439 | + | "interfaces": [ | |||
| 440 | + | { | |||
| 441 | + | "name": "wp_fifo_manager_v1", | |||
| 442 | + | "version": 1 | |||
| 443 | + | }, | |||
| 444 | + | { | |||
| 445 | + | "name": "wp_fifo_v1", | |||
| 446 | + | "version": 1 | |||
| 447 | + | } | |||
| 448 | + | ], | |||
| 449 | + | "deps": [ | |||
| 450 | + | "wayland" | |||
| 451 | + | ] | |||
| 452 | + | }, | |||
| 453 | + | { | |||
| 454 | + | "package": "fractionalscale", | |||
| 455 | + | "xml": "fractionalscale.xml", | |||
| 456 | + | "source": "wayland-protocols", | |||
| 457 | + | "path": "staging/fractional-scale/fractional-scale-v1.xml", | |||
| 458 | + | "sha256": "5941de5d28f427ecdadddc8623a6f6af0a30b0ab4726847236ba7a7652b81316", | |||
| 459 | + | "license": "MIT", | |||
| 460 | + | "interfaces": [ | |||
| 461 | + | { | |||
| 462 | + | "name": "wp_fractional_scale_manager_v1", | |||
| 463 | + | "version": 1 | |||
| 464 | + | }, | |||
| 465 | + | { | |||
| 466 | + | "name": "wp_fractional_scale_v1", | |||
| 467 | + | "version": 1 | |||
| 468 | + | } | |||
| 469 | + | ], | |||
| 470 | + | "deps": [ | |||
| 471 | + | "wayland" | |||
| 472 | + | ] | |||
| 473 | + | }, | |||
| 474 | + | { | |||
| 475 | + | "package": "fullscreenshell", | |||
| 476 | + | "xml": "fullscreenshell.xml", | |||
| 477 | + | "source": "wayland-protocols", | |||
| 478 | + | "path": "unstable/fullscreen-shell/fullscreen-shell-unstable-v1.xml", | |||
| 479 | + | "sha256": "fcc50bf0b48610d55bbe096a53da433e8557ea36a31feba2d77bf0cb9181bb52", | |||
| 480 | + | "license": "MIT", | |||
| 481 | + | "interfaces": [ | |||
| 482 | + | { | |||
| 483 | + | "name": "zwp_fullscreen_shell_mode_feedback_v1", | |||
| 484 | + | "version": 1 | |||
| 485 | + | }, | |||
| 486 | + | { | |||
| 487 | + | "name": "zwp_fullscreen_shell_v1", | |||
| 488 | + | "version": 1 | |||
| 489 | + | } | |||
| 490 | + | ], | |||
| 491 | + | "deps": [ | |||
| 492 | + | "wayland" | |||
| 493 | + | ] | |||
| 494 | + | }, | |||
| 495 | + | { | |||
| 496 | + | "package": "idleinhibit", | |||
| 497 | + | "xml": "idleinhibit.xml", | |||
| 498 | + | "source": "wayland-protocols", | |||
| 499 | + | "path": "unstable/idle-inhibit/idle-inhibit-unstable-v1.xml", | |||
| 500 | + | "sha256": "c2ac9f002c6669ca6c02eb9b587b8e9108e3ce6deab4a2de58b576f4f864ca38", | |||
| 501 | + | "license": "MIT", | |||
| 502 | + | "interfaces": [ | |||
| 503 | + | { | |||
| 504 | + | "name": "zwp_idle_inhibit_manager_v1", | |||
| 505 | + | "version": 1 | |||
| 506 | + | }, | |||
| 507 | + | { | |||
| 508 | + | "name": "zwp_idle_inhibitor_v1", | |||
| 509 | + | "version": 1 | |||
| 510 | + | } | |||
| 511 | + | ], | |||
| 512 | + | "deps": [ | |||
| 513 | + | "wayland" | |||
| 514 | + | ] | |||
| 515 | + | }, | |||
| 516 | + | { | |||
| 517 | + | "package": "inputmethod", | |||
| 518 | + | "xml": "inputmethod.xml", | |||
| 519 | + | "source": "wlroots", | |||
| 520 | + | "path": "protocol/input-method-unstable-v2.xml", | |||
| 521 | + | "sha256": "aaf68b2aec481f507a4b915ab7c624bf676495ebb2030eaf207a9c8bcac7630d", | |||
| 522 | + | "license": "MIT", | |||
| 523 | + | "interfaces": [ | |||
| 524 | + | { | |||
| 525 | + | "name": "zwp_input_method_keyboard_grab_v2", | |||
| 526 | + | "version": 1 | |||
| 527 | + | }, | |||
| 528 | + | { | |||
| 529 | + | "name": "zwp_input_method_manager_v2", | |||
| 530 | + | "version": 1 | |||
| 531 | + | }, | |||
| 532 | + | { | |||
| 533 | + | "name": "zwp_input_method_v2", | |||
| 534 | + | "version": 1 | |||
| 535 | + | }, | |||
| 536 | + | { | |||
| 537 | + | "name": "zwp_input_popup_surface_v2", | |||
| 538 | + | "version": 1 | |||
| 539 | + | } | |||
| 540 | + | ], | |||
| 541 | + | "deps": [ | |||
| 542 | + | "wayland" | |||
| 543 | + | ] | |||
| 544 | + | }, | |||
| 545 | + | { | |||
| 546 | + | "package": "inputtimestamps", | |||
| 547 | + | "xml": "inputtimestamps.xml", | |||
| 548 | + | "source": "wayland-protocols", | |||
| 549 | + | "path": "unstable/input-timestamps/input-timestamps-unstable-v1.xml", | |||
| 550 | + | "sha256": "92d9911f070407d470458f59ffdee5406ce3b6368270a93e6ecd9f4f71368bb0", | |||
| 551 | + | "license": "MIT", | |||
| 552 | + | "interfaces": [ | |||
| 553 | + | { | |||
| 554 | + | "name": "zwp_input_timestamps_manager_v1", | |||
| 555 | + | "version": 1 | |||
| 556 | + | }, | |||
| 557 | + | { | |||
| 558 | + | "name": "zwp_input_timestamps_v1", | |||
| 559 | + | "version": 1 | |||
| 560 | + | } | |||
| 561 | + | ], | |||
| 562 | + | "deps": [ | |||
| 563 | + | "wayland" | |||
| 564 | + | ] | |||
| 565 | + | }, | |||
| 566 | + | { | |||
| 567 | + | "package": "keyboardshortcutsinhibit", | |||
| 568 | + | "xml": "keyboardshortcutsinhibit.xml", | |||
| 569 | + | "source": "wayland-protocols", | |||
| 570 | + | "path": "unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml", | |||
| 571 | + | "sha256": "9117d9e8ec02e9a3c3c55803b41e1227e76986f555f7c12eeb29f796fa63e69b", | |||
| 572 | + | "license": "MIT", | |||
| 573 | + | "interfaces": [ | |||
| 574 | + | { | |||
| 575 | + | "name": "zwp_keyboard_shortcuts_inhibit_manager_v1", | |||
| 576 | + | "version": 1 | |||
| 577 | + | }, | |||
| 578 | + | { | |||
| 579 | + | "name": "zwp_keyboard_shortcuts_inhibitor_v1", | |||
| 580 | + | "version": 1 | |||
| 581 | + | } | |||
| 582 | + | ], | |||
| 583 | + | "deps": [ | |||
| 584 | + | "wayland" | |||
| 585 | + | ] | |||
| 586 | + | }, | |||
| 587 | + | { | |||
| 588 | + | "package": "linuxdmabuf", | |||
| 589 | + | "xml": "linuxdmabuf.xml", | |||
| 590 | + | "source": "wayland-protocols", | |||
| 591 | + | "path": "stable/linux-dmabuf/linux-dmabuf-v1.xml", | |||
| 592 | + | "sha256": "2735bb4589cbb364dfcb6a821dd3abbf0c0257956b716b9691718ddfd453df4c", | |||
| 593 | + | "license": "MIT", | |||
| 594 | + | "interfaces": [ | |||
| 595 | + | { | |||
| 596 | + | "name": "zwp_linux_buffer_params_v1", | |||
| 597 | + | "version": 6 | |||
| 598 | + | }, | |||
| 599 | + | { | |||
| 600 | + | "name": "zwp_linux_dmabuf_feedback_v1", | |||
| 601 | + | "version": 6 | |||
| 602 | + | }, | |||
| 603 | + | { | |||
| 604 | + | "name": "zwp_linux_dmabuf_v1", | |||
| 605 | + | "version": 6 | |||
| 606 | + | } | |||
| 607 | + | ], | |||
| 608 | + | "deps": [ | |||
| 609 | + | "wayland" | |||
| 610 | + | ] | |||
| 611 | + | }, | |||
| 612 | + | { | |||
| 613 | + | "package": "linuxdrmsyncobj", | |||
| 614 | + | "xml": "linuxdrmsyncobj.xml", | |||
| 615 | + | "source": "wayland-protocols", | |||
| 616 | + | "path": "staging/linux-drm-syncobj/linux-drm-syncobj-v1.xml", | |||
| 617 | + | "sha256": "5ede41a56eced6aa635caa7ab2996066bff9fd211620dbf9f73aafab740bec71", | |||
| 618 | + | "license": "MIT", | |||
| 619 | + | "interfaces": [ | |||
| 620 | + | { | |||
| 621 | + | "name": "wp_linux_drm_syncobj_manager_v1", | |||
| 622 | + | "version": 1 | |||
| 623 | + | }, | |||
| 624 | + | { | |||
| 625 | + | "name": "wp_linux_drm_syncobj_surface_v1", | |||
| 626 | + | "version": 1 | |||
| 627 | + | }, | |||
| 628 | + | { | |||
| 629 | + | "name": "wp_linux_drm_syncobj_timeline_v1", | |||
| 630 | + | "version": 1 | |||
| 631 | + | } | |||
| 632 | + | ], | |||
| 633 | + | "deps": [ | |||
| 634 | + | "wayland" | |||
| 635 | + | ] | |||
| 636 | + | }, | |||
| 637 | + | { | |||
| 638 | + | "package": "linuxexplicitsynchronization", | |||
| 639 | + | "xml": "linuxexplicitsynchronization.xml", | |||
| 640 | + | "source": "wayland-protocols", | |||
| 641 | + | "path": "unstable/linux-explicit-synchronization/linux-explicit-synchronization-unstable-v1.xml", | |||
| 642 | + | "sha256": "4d83eed81e2911ec7731137d4209f685faeab76c15a994d8a46963a83fce02ea", | |||
| 643 | + | "license": "MIT", | |||
| 644 | + | "interfaces": [ | |||
| 645 | + | { | |||
| 646 | + | "name": "zwp_linux_buffer_release_v1", | |||
| 647 | + | "version": 1 | |||
| 648 | + | }, | |||
| 649 | + | { | |||
| 650 | + | "name": "zwp_linux_explicit_synchronization_v1", | |||
| 651 | + | "version": 2 | |||
| 652 | + | }, | |||
| 653 | + | { | |||
| 654 | + | "name": "zwp_linux_surface_synchronization_v1", | |||
| 655 | + | "version": 2 | |||
| 656 | + | } | |||
| 657 | + | ], | |||
| 658 | + | "deps": [ | |||
| 659 | + | "wayland" | |||
| 660 | + | ] | |||
| 661 | + | }, | |||
| 662 | + | { | |||
| 663 | + | "package": "pointerconstraints", | |||
| 664 | + | "xml": "pointerconstraints.xml", | |||
| 665 | + | "source": "wayland-protocols", | |||
| 666 | + | "path": "unstable/pointer-constraints/pointer-constraints-unstable-v1.xml", | |||
| 667 | + | "sha256": "f980fac900ba1dcfbbe97f588fc17b893926bd2b57624563653a1bfe4d035948", | |||
| 668 | + | "license": "MIT", | |||
| 669 | + | "interfaces": [ | |||
| 670 | + | { | |||
| 671 | + | "name": "zwp_confined_pointer_v1", | |||
| 672 | + | "version": 1 | |||
| 673 | + | }, | |||
| 674 | + | { | |||
| 675 | + | "name": "zwp_locked_pointer_v1", | |||
| 676 | + | "version": 1 | |||
| 677 | + | }, | |||
| 678 | + | { | |||
| 679 | + | "name": "zwp_pointer_constraints_v1", | |||
| 680 | + | "version": 1 | |||
| 681 | + | } | |||
| 682 | + | ], | |||
| 683 | + | "deps": [ | |||
| 684 | + | "wayland" | |||
| 685 | + | ] | |||
| 686 | + | }, | |||
| 687 | + | { | |||
| 688 | + | "package": "pointergestures", | |||
| 689 | + | "xml": "pointergestures.xml", | |||
| 690 | + | "source": "wayland-protocols", | |||
| 691 | + | "path": "unstable/pointer-gestures/pointer-gestures-unstable-v1.xml", | |||
| 692 | + | "sha256": "9f7b6ad542f444001312113395b8de6f24e59d6f0c57c9b44f6c3c498ef004d7", | |||
| 693 | + | "license": "MIT", | |||
| 694 | + | "interfaces": [ | |||
| 695 | + | { | |||
| 696 | + | "name": "zwp_pointer_gesture_hold_v1", | |||
| 697 | + | "version": 3 | |||
| 698 | + | }, | |||
| 699 | + | { | |||
| 700 | + | "name": "zwp_pointer_gesture_pinch_v1", | |||
| 701 | + | "version": 3 | |||
| 702 | + | }, | |||
| 703 | + | { | |||
| 704 | + | "name": "zwp_pointer_gesture_swipe_v1", | |||
| 705 | + | "version": 3 | |||
| 706 | + | }, | |||
| 707 | + | { | |||
| 708 | + | "name": "zwp_pointer_gestures_v1", | |||
| 709 | + | "version": 3 | |||
| 710 | + | } | |||
| 711 | + | ], | |||
| 712 | + | "deps": [ | |||
| 713 | + | "wayland" | |||
| 714 | + | ] | |||
| 715 | + | }, | |||
| 716 | + | { | |||
| 717 | + | "package": "pointerwarp", | |||
| 718 | + | "xml": "pointerwarp.xml", | |||
| 719 | + | "source": "wayland-protocols", | |||
| 720 | + | "path": "staging/pointer-warp/pointer-warp-v1.xml", | |||
| 721 | + | "sha256": "1389e89c68c6f6d231fd2dcda57fa9c75c5230d0ac1deffa8d80a7648e197e66", | |||
| 722 | + | "license": "MIT", | |||
| 723 | + | "interfaces": [ | |||
| 724 | + | { | |||
| 725 | + | "name": "wp_pointer_warp_v1", | |||
| 726 | + | "version": 1 | |||
| 727 | + | } | |||
| 728 | + | ], | |||
| 729 | + | "deps": [ | |||
| 730 | + | "wayland" | |||
| 731 | + | ] | |||
| 732 | + | }, | |||
| 733 | + | { | |||
| 734 | + | "package": "presentationtime", | |||
| 735 | + | "xml": "presentationtime.xml", | |||
| 736 | + | "source": "wayland-protocols", | |||
| 737 | + | "path": "stable/presentation-time/presentation-time.xml", | |||
| 738 | + | "sha256": "dffac93bcb2bb1d8c385e72b8a8c2c0d4d79a336866322f3ba886dce2b27b1e2", | |||
| 739 | + | "license": "MIT", | |||
| 740 | + | "interfaces": [ | |||
| 741 | + | { | |||
| 742 | + | "name": "wp_presentation", | |||
| 743 | + | "version": 2 | |||
| 744 | + | }, | |||
| 745 | + | { | |||
| 746 | + | "name": "wp_presentation_feedback", | |||
| 747 | + | "version": 2 | |||
| 748 | + | } | |||
| 749 | + | ], | |||
| 750 | + | "deps": [ | |||
| 751 | + | "wayland" | |||
| 752 | + | ] | |||
| 753 | + | }, | |||
| 754 | + | { | |||
| 755 | + | "package": "primaryselection", | |||
| 756 | + | "xml": "primaryselection.xml", | |||
| 757 | + | "source": "wayland-protocols", | |||
| 758 | + | "path": "unstable/primary-selection/primary-selection-unstable-v1.xml", | |||
| 759 | + | "sha256": "d568482ba84df6e531698b1f531810860995ca24d69495427fe43aee6017f52c", | |||
| 760 | + | "license": "MIT", | |||
| 761 | + | "interfaces": [ | |||
| 762 | + | { | |||
| 763 | + | "name": "zwp_primary_selection_device_manager_v1", | |||
| 764 | + | "version": 1 | |||
| 765 | + | }, | |||
| 766 | + | { | |||
| 767 | + | "name": "zwp_primary_selection_device_v1", | |||
| 768 | + | "version": 1 | |||
| 769 | + | }, | |||
| 770 | + | { | |||
| 771 | + | "name": "zwp_primary_selection_offer_v1", | |||
| 772 | + | "version": 1 | |||
| 773 | + | }, | |||
| 774 | + | { | |||
| 775 | + | "name": "zwp_primary_selection_source_v1", | |||
| 776 | + | "version": 1 | |||
| 777 | + | } | |||
| 778 | + | ], | |||
| 779 | + | "deps": [ | |||
| 780 | + | "wayland" | |||
| 781 | + | ] | |||
| 782 | + | }, | |||
| 783 | + | { | |||
| 784 | + | "package": "relativepointer", | |||
| 785 | + | "xml": "relativepointer.xml", | |||
| 786 | + | "source": "wayland-protocols", | |||
| 787 | + | "path": "unstable/relative-pointer/relative-pointer-unstable-v1.xml", | |||
| 788 | + | "sha256": "ab4930dd3084f732b6fdd12ee6dbd0a112a758ed8a57b170366391dbeb1a22ff", | |||
| 789 | + | "license": "MIT", | |||
| 790 | + | "interfaces": [ | |||
| 791 | + | { | |||
| 792 | + | "name": "zwp_relative_pointer_manager_v1", | |||
| 793 | + | "version": 1 | |||
| 794 | + | }, | |||
| 795 | + | { | |||
| 796 | + | "name": "zwp_relative_pointer_v1", | |||
| 797 | + | "version": 1 | |||
| 798 | + | } | |||
| 799 | + | ], | |||
| 800 | + | "deps": [ | |||
| 801 | + | "wayland" | |||
| 802 | + | ] | |||
| 803 | + | }, | |||
| 804 | + | { | |||
| 805 | + | "package": "securitycontext", | |||
| 806 | + | "xml": "securitycontext.xml", | |||
| 807 | + | "source": "wayland-protocols", | |||
| 808 | + | "path": "staging/security-context/security-context-v1.xml", | |||
| 809 | + | "sha256": "f4f8ba15ebd2df62db611b1de32e992f660a4aeeea83250cb88fa468da42ffcb", | |||
| 810 | + | "license": "MIT", | |||
| 811 | + | "interfaces": [ | |||
| 812 | + | { | |||
| 813 | + | "name": "wp_security_context_manager_v1", | |||
| 814 | + | "version": 1 | |||
| 815 | + | }, | |||
| 816 | + | { | |||
| 817 | + | "name": "wp_security_context_v1", | |||
| 818 | + | "version": 1 | |||
| 819 | + | } | |||
| 820 | + | ], | |||
| 821 | + | "deps": [] | |||
| 822 | + | }, | |||
| 823 | + | { | |||
| 824 | + | "package": "serverdecoration", | |||
| 825 | + | "xml": "serverdecoration.xml", | |||
| 826 | + | "source": "plasma-wayland-protocols", | |||
| 827 | + | "path": "src/protocols/server-decoration.xml", | |||
| 828 | + | "sha256": "c5f857734bb190dc9adfb65fb05550a6245f12af1a2be5eefd05be199805a68c", | |||
| 829 | + | "license": "LGPL-2.1-or-later", | |||
| 830 | + | "interfaces": [ | |||
| 831 | + | { | |||
| 832 | + | "name": "org_kde_kwin_server_decoration", | |||
| 833 | + | "version": 1 | |||
| 834 | + | }, | |||
| 835 | + | { | |||
| 836 | + | "name": "org_kde_kwin_server_decoration_manager", | |||
| 837 | + | "version": 1 | |||
| 838 | + | } | |||
| 839 | + | ], | |||
| 840 | + | "deps": [ | |||
| 841 | + | "wayland" | |||
| 842 | + | ] | |||
| 843 | + | }, | |||
| 844 | + | { | |||
| 845 | + | "package": "singlepixelbuffer", | |||
| 846 | + | "xml": "singlepixelbuffer.xml", | |||
| 847 | + | "source": "wayland-protocols", | |||
| 848 | + | "path": "staging/single-pixel-buffer/single-pixel-buffer-v1.xml", | |||
| 849 | + | "sha256": "4c2cc1355b06a2d2fe68ccb1cf4b72cca51e1ba21c5d3e0c404f577f40d1301e", | |||
| 850 | + | "license": "MIT", | |||
| 851 | + | "interfaces": [ | |||
| 852 | + | { | |||
| 853 | + | "name": "wp_single_pixel_buffer_manager_v1", | |||
| 854 | + | "version": 1 | |||
| 855 | + | } | |||
| 856 | + | ], | |||
| 857 | + | "deps": [ | |||
| 858 | + | "wayland" | |||
| 859 | + | ] | |||
| 860 | + | }, | |||
| 861 | + | { | |||
| 862 | + | "package": "tablet", | |||
| 863 | + | "xml": "tablet.xml", | |||
| 864 | + | "source": "wayland-protocols", | |||
| 865 | + | "path": "stable/tablet/tablet-v2.xml", | |||
| 866 | + | "sha256": "ac1128b26c779cf90b9ed71182ba5e34a7262826789adae206d825a4d45908b4", | |||
| 867 | + | "license": "MIT", | |||
| 868 | + | "interfaces": [ | |||
| 869 | + | { | |||
| 870 | + | "name": "zwp_tablet_manager_v2", | |||
| 871 | + | "version": 2 | |||
| 872 | + | }, | |||
| 873 | + | { | |||
| 874 | + | "name": "zwp_tablet_pad_dial_v2", | |||
| 875 | + | "version": 2 | |||
| 876 | + | }, | |||
| 877 | + | { | |||
| 878 | + | "name": "zwp_tablet_pad_group_v2", | |||
| 879 | + | "version": 2 | |||
| 880 | + | }, | |||
| 881 | + | { | |||
| 882 | + | "name": "zwp_tablet_pad_ring_v2", | |||
| 883 | + | "version": 2 | |||
| 884 | + | }, | |||
| 885 | + | { | |||
| 886 | + | "name": "zwp_tablet_pad_strip_v2", | |||
| 887 | + | "version": 2 | |||
| 888 | + | }, | |||
| 889 | + | { | |||
| 890 | + | "name": "zwp_tablet_pad_v2", | |||
| 891 | + | "version": 2 | |||
| 892 | + | }, | |||
| 893 | + | { | |||
| 894 | + | "name": "zwp_tablet_seat_v2", | |||
| 895 | + | "version": 2 | |||
| 896 | + | }, | |||
| 897 | + | { | |||
| 898 | + | "name": "zwp_tablet_tool_v2", | |||
| 899 | + | "version": 2 | |||
| 900 | + | }, | |||
| 901 | + | { | |||
| 902 | + | "name": "zwp_tablet_v2", | |||
| 903 | + | "version": 2 | |||
| 904 | + | } | |||
| 905 | + | ], | |||
| 906 | + | "deps": [ | |||
| 907 | + | "wayland" | |||
| 908 | + | ] | |||
| 909 | + | }, | |||
| 910 | + | { | |||
| 911 | + | "package": "tearingcontrol", | |||
| 912 | + | "xml": "tearingcontrol.xml", | |||
| 913 | + | "source": "wayland-protocols", | |||
| 914 | + | "path": "staging/tearing-control/tearing-control-v1.xml", | |||
| 915 | + | "sha256": "846895b4a90ba1ddd75673cefc596480beef318f1694ec7dbca0fec54bb27043", | |||
| 916 | + | "license": "MIT", | |||
| 917 | + | "interfaces": [ | |||
| 918 | + | { | |||
| 919 | + | "name": "wp_tearing_control_manager_v1", | |||
| 920 | + | "version": 1 | |||
| 921 | + | }, | |||
| 922 | + | { | |||
| 923 | + | "name": "wp_tearing_control_v1", | |||
| 924 | + | "version": 1 | |||
| 925 | + | } | |||
| 926 | + | ], | |||
| 927 | + | "deps": [ | |||
| 928 | + | "wayland" | |||
| 929 | + | ] | |||
| 930 | + | }, | |||
| 931 | + | { | |||
| 932 | + | "package": "textinput", | |||
| 933 | + | "xml": "textinput.xml", | |||
| 934 | + | "source": "wayland-protocols", | |||
| 935 | + | "path": "unstable/text-input/text-input-unstable-v3.xml", | |||
| 936 | + | "sha256": "160815cda13c285a30df1971d8f0a5b3aac07071537df59916d2f748b18e4f59", | |||
| 937 | + | "license": "MIT", | |||
| 938 | + | "interfaces": [ | |||
| 939 | + | { | |||
| 940 | + | "name": "zwp_text_input_manager_v3", | |||
| 941 | + | "version": 2 | |||
| 942 | + | }, | |||
| 943 | + | { | |||
| 944 | + | "name": "zwp_text_input_v3", | |||
| 945 | + | "version": 2 | |||
| 946 | + | } | |||
| 947 | + | ], | |||
| 948 | + | "deps": [ | |||
| 949 | + | "wayland" | |||
| 950 | + | ] | |||
| 951 | + | }, | |||
| 952 | + | { | |||
| 953 | + | "package": "viewporter", | |||
| 954 | + | "xml": "viewporter.xml", | |||
| 955 | + | "source": "wayland-protocols", | |||
| 956 | + | "path": "stable/viewporter/viewporter.xml", | |||
| 957 | + | "sha256": "dcb12279a03746301fe490aaed4b38a403485a925abfce2ccfceb644e104fe71", | |||
| 958 | + | "license": "MIT", | |||
| 959 | + | "interfaces": [ | |||
| 960 | + | { | |||
| 961 | + | "name": "wp_viewport", | |||
| 962 | + | "version": 1 | |||
| 963 | + | }, | |||
| 964 | + | { | |||
| 965 | + | "name": "wp_viewporter", | |||
| 966 | + | "version": 1 | |||
| 967 | + | } | |||
| 968 | + | ], | |||
| 969 | + | "deps": [ | |||
| 970 | + | "wayland" | |||
| 971 | + | ] | |||
| 972 | + | }, | |||
| 973 | + | { | |||
| 974 | + | "package": "virtualkeyboard", | |||
| 975 | + | "xml": "virtualkeyboard.xml", | |||
| 976 | + | "source": "wlroots", | |||
| 977 | + | "path": "protocol/virtual-keyboard-unstable-v1.xml", | |||
| 978 | + | "sha256": "7ad7870003ecd592cae47dc19d277a609b7f18fd7b7be012623cf3225a7294f5", | |||
| 979 | + | "license": "MIT", | |||
| 980 | + | "interfaces": [ | |||
| 981 | + | { | |||
| 982 | + | "name": "zwp_virtual_keyboard_manager_v1", | |||
| 983 | + | "version": 1 | |||
| 984 | + | }, | |||
| 985 | + | { | |||
| 986 | + | "name": "zwp_virtual_keyboard_v1", | |||
| 987 | + | "version": 1 | |||
| 988 | + | } | |||
| 989 | + | ], | |||
| 990 | + | "deps": [ | |||
| 991 | + | "wayland" | |||
| 992 | + | ] | |||
| 993 | + | }, | |||
| 994 | + | { | |||
| 995 | + | "package": "wayland", | |||
| 996 | + | "xml": "wayland.xml", | |||
| 997 | + | "source": "wayland", | |||
| 998 | + | "path": "protocol/wayland.xml", | |||
| 999 | + | "sha256": "cc860987e54f8d85c940e97fa1270c69b6e4ad31fbcf5a7f00107ce1157f5e07", | |||
| 1000 | + | "license": "MIT", | |||
| 1001 | + | "interfaces": [ | |||
| 1002 | + | { | |||
| 1003 | + | "name": "wl_buffer", | |||
| 1004 | + | "version": 1 | |||
| 1005 | + | }, | |||
| 1006 | + | { | |||
| 1007 | + | "name": "wl_callback", | |||
| 1008 | + | "version": 1 | |||
| 1009 | + | }, | |||
| 1010 | + | { | |||
| 1011 | + | "name": "wl_compositor", | |||
| 1012 | + | "version": 7 | |||
| 1013 | + | }, | |||
| 1014 | + | { | |||
| 1015 | + | "name": "wl_data_device", | |||
| 1016 | + | "version": 4 | |||
| 1017 | + | }, | |||
| 1018 | + | { | |||
| 1019 | + | "name": "wl_data_device_manager", | |||
| 1020 | + | "version": 4 | |||
| 1021 | + | }, | |||
| 1022 | + | { | |||
| 1023 | + | "name": "wl_data_offer", | |||
| 1024 | + | "version": 4 | |||
| 1025 | + | }, | |||
| 1026 | + | { | |||
| 1027 | + | "name": "wl_data_source", | |||
| 1028 | + | "version": 4 | |||
| 1029 | + | }, | |||
| 1030 | + | { | |||
| 1031 | + | "name": "wl_display", | |||
| 1032 | + | "version": 1 | |||
| 1033 | + | }, | |||
| 1034 | + | { | |||
| 1035 | + | "name": "wl_fixes", | |||
| 1036 | + | "version": 2 | |||
| 1037 | + | }, | |||
| 1038 | + | { | |||
| 1039 | + | "name": "wl_keyboard", | |||
| 1040 | + | "version": 11 | |||
| 1041 | + | }, | |||
| 1042 | + | { | |||
| 1043 | + | "name": "wl_output", | |||
| 1044 | + | "version": 4 | |||
| 1045 | + | }, | |||
| 1046 | + | { | |||
| 1047 | + | "name": "wl_pointer", | |||
| 1048 | + | "version": 11 | |||
| 1049 | + | }, | |||
| 1050 | + | { | |||
| 1051 | + | "name": "wl_region", | |||
| 1052 | + | "version": 7 | |||
| 1053 | + | }, | |||
| 1054 | + | { | |||
| 1055 | + | "name": "wl_registry", | |||
| 1056 | + | "version": 1 | |||
| 1057 | + | }, | |||
| 1058 | + | { | |||
| 1059 | + | "name": "wl_seat", | |||
| 1060 | + | "version": 11 | |||
| 1061 | + | }, | |||
| 1062 | + | { | |||
| 1063 | + | "name": "wl_shell", | |||
| 1064 | + | "version": 1 | |||
| 1065 | + | }, | |||
| 1066 | + | { | |||
| 1067 | + | "name": "wl_shell_surface", | |||
| 1068 | + | "version": 1 | |||
| 1069 | + | }, | |||
| 1070 | + | { | |||
| 1071 | + | "name": "wl_shm", | |||
| 1072 | + | "version": 3 | |||
| 1073 | + | }, | |||
| 1074 | + | { | |||
| 1075 | + | "name": "wl_shm_pool", | |||
| 1076 | + | "version": 3 | |||
| 1077 | + | }, | |||
| 1078 | + | { | |||
| 1079 | + | "name": "wl_subcompositor", | |||
| 1080 | + | "version": 1 | |||
| 1081 | + | }, | |||
| 1082 | + | { | |||
| 1083 | + | "name": "wl_subsurface", | |||
| 1084 | + | "version": 1 | |||
| 1085 | + | }, | |||
| 1086 | + | { | |||
| 1087 | + | "name": "wl_surface", | |||
| 1088 | + | "version": 7 | |||
| 1089 | + | }, | |||
| 1090 | + | { | |||
| 1091 | + | "name": "wl_touch", | |||
| 1092 | + | "version": 11 | |||
| 1093 | + | } | |||
| 1094 | + | ], | |||
| 1095 | + | "deps": [] | |||
| 1096 | + | }, | |||
| 1097 | + | { | |||
| 1098 | + | "package": "wlrdatacontrol", | |||
| 1099 | + | "xml": "wlrdatacontrol.xml", | |||
| 1100 | + | "source": "wlr-protocols", | |||
| 1101 | + | "path": "unstable/wlr-data-control-unstable-v1.xml", | |||
| 1102 | + | "sha256": "5f10d6bf9bfa9d12266a6f423fb77bbb98e415f6d64fe24680710ffb362a7082", | |||
| 1103 | + | "license": "MIT", | |||
| 1104 | + | "interfaces": [ | |||
| 1105 | + | { | |||
| 1106 | + | "name": "zwlr_data_control_device_v1", | |||
| 1107 | + | "version": 2 | |||
| 1108 | + | }, | |||
| 1109 | + | { | |||
| 1110 | + | "name": "zwlr_data_control_manager_v1", | |||
| 1111 | + | "version": 2 | |||
| 1112 | + | }, | |||
| 1113 | + | { | |||
| 1114 | + | "name": "zwlr_data_control_offer_v1", | |||
| 1115 | + | "version": 1 | |||
| 1116 | + | }, | |||
| 1117 | + | { | |||
| 1118 | + | "name": "zwlr_data_control_source_v1", | |||
| 1119 | + | "version": 1 | |||
| 1120 | + | } | |||
| 1121 | + | ], | |||
| 1122 | + | "deps": [ | |||
| 1123 | + | "wayland" | |||
| 1124 | + | ] | |||
| 1125 | + | }, | |||
| 1126 | + | { | |||
| 1127 | + | "package": "wlrexportdmabuf", | |||
| 1128 | + | "xml": "wlrexportdmabuf.xml", | |||
| 1129 | + | "source": "wlr-protocols", | |||
| 1130 | + | "path": "unstable/wlr-export-dmabuf-unstable-v1.xml", | |||
| 1131 | + | "sha256": "24e2334d804eb12b65a0471ec41ba9aed2b7997caf81c0fe4dc44b86b7f3fed8", | |||
| 1132 | + | "license": "MIT", | |||
| 1133 | + | "interfaces": [ | |||
| 1134 | + | { | |||
| 1135 | + | "name": "zwlr_export_dmabuf_frame_v1", | |||
| 1136 | + | "version": 1 | |||
| 1137 | + | }, | |||
| 1138 | + | { | |||
| 1139 | + | "name": "zwlr_export_dmabuf_manager_v1", | |||
| 1140 | + | "version": 1 | |||
| 1141 | + | } | |||
| 1142 | + | ], | |||
| 1143 | + | "deps": [ | |||
| 1144 | + | "wayland" | |||
| 1145 | + | ] | |||
| 1146 | + | }, | |||
| 1147 | + | { | |||
| 1148 | + | "package": "wlrforeigntoplevelmanagement", | |||
| 1149 | + | "xml": "wlrforeigntoplevelmanagement.xml", | |||
| 1150 | + | "source": "wlr-protocols", | |||
| 1151 | + | "path": "unstable/wlr-foreign-toplevel-management-unstable-v1.xml", | |||
| 1152 | + | "sha256": "4ecc4588858e29fe680a33521e1f22bcf22071d66d1553fe96b4ddec03d591d2", | |||
| 1153 | + | "license": "MIT", | |||
| 1154 | + | "interfaces": [ | |||
| 1155 | + | { | |||
| 1156 | + | "name": "zwlr_foreign_toplevel_handle_v1", | |||
| 1157 | + | "version": 3 | |||
| 1158 | + | }, | |||
| 1159 | + | { | |||
| 1160 | + | "name": "zwlr_foreign_toplevel_manager_v1", | |||
| 1161 | + | "version": 3 | |||
| 1162 | + | } | |||
| 1163 | + | ], | |||
| 1164 | + | "deps": [ | |||
| 1165 | + | "wayland" | |||
| 1166 | + | ] | |||
| 1167 | + | }, | |||
| 1168 | + | { | |||
| 1169 | + | "package": "wlrgammacontrol", | |||
| 1170 | + | "xml": "wlrgammacontrol.xml", | |||
| 1171 | + | "source": "wlr-protocols", | |||
| 1172 | + | "path": "unstable/wlr-gamma-control-unstable-v1.xml", | |||
| 1173 | + | "sha256": "4065cbc291a80348b7ef311168fbfb5cf245efe977a6dc32211291ef1a9529a1", | |||
| 1174 | + | "license": "MIT", | |||
| 1175 | + | "interfaces": [ | |||
| 1176 | + | { | |||
| 1177 | + | "name": "zwlr_gamma_control_manager_v1", | |||
| 1178 | + | "version": 1 | |||
| 1179 | + | }, | |||
| 1180 | + | { | |||
| 1181 | + | "name": "zwlr_gamma_control_v1", | |||
| 1182 | + | "version": 1 | |||
| 1183 | + | } | |||
| 1184 | + | ], | |||
| 1185 | + | "deps": [ | |||
| 1186 | + | "wayland" | |||
| 1187 | + | ] | |||
| 1188 | + | }, | |||
| 1189 | + | { | |||
| 1190 | + | "package": "wlrinputinhibitor", | |||
| 1191 | + | "xml": "wlrinputinhibitor.xml", | |||
| 1192 | + | "source": "wlr-protocols", | |||
| 1193 | + | "path": "unstable/wlr-input-inhibitor-unstable-v1.xml", | |||
| 1194 | + | "sha256": "325ee67e0762258ad0dcf43d1366f36fe6a3ac2bec84eaf1172b1a5e1187edf8", | |||
| 1195 | + | "license": "MIT", | |||
| 1196 | + | "interfaces": [ | |||
| 1197 | + | { | |||
| 1198 | + | "name": "zwlr_input_inhibit_manager_v1", | |||
| 1199 | + | "version": 1 | |||
| 1200 | + | }, | |||
| 1201 | + | { | |||
| 1202 | + | "name": "zwlr_input_inhibitor_v1", | |||
| 1203 | + | "version": 1 | |||
| 1204 | + | } | |||
| 1205 | + | ], | |||
| 1206 | + | "deps": [] | |||
| 1207 | + | }, | |||
| 1208 | + | { | |||
| 1209 | + | "package": "wlrlayershell", | |||
| 1210 | + | "xml": "wlrlayershell.xml", | |||
| 1211 | + | "source": "wlr-protocols", | |||
| 1212 | + | "path": "unstable/wlr-layer-shell-unstable-v1.xml", | |||
| 1213 | + | "sha256": "87e0b9c837aecd6977f76f3c47d73088b7159871f5d979dc1840f6cadb5e2ed8", | |||
| 1214 | + | "license": "MIT", | |||
| 1215 | + | "interfaces": [ | |||
| 1216 | + | { | |||
| 1217 | + | "name": "zwlr_layer_shell_v1", | |||
| 1218 | + | "version": 5 | |||
| 1219 | + | }, | |||
| 1220 | + | { | |||
| 1221 | + | "name": "zwlr_layer_surface_v1", | |||
| 1222 | + | "version": 5 | |||
| 1223 | + | } | |||
| 1224 | + | ], | |||
| 1225 | + | "deps": [ | |||
| 1226 | + | "wayland", | |||
| 1227 | + | "xdgshell" | |||
| 1228 | + | ] | |||
| 1229 | + | }, | |||
| 1230 | + | { | |||
| 1231 | + | "package": "wlroutputmanagement", | |||
| 1232 | + | "xml": "wlroutputmanagement.xml", | |||
| 1233 | + | "source": "wlr-protocols", | |||
| 1234 | + | "path": "unstable/wlr-output-management-unstable-v1.xml", | |||
| 1235 | + | "sha256": "65b0f82a6cf129bf1a1c31a2428795abd33886c15ddd5f3ad97e5922d7bdc3a7", | |||
| 1236 | + | "license": "MIT", | |||
| 1237 | + | "interfaces": [ | |||
| 1238 | + | { | |||
| 1239 | + | "name": "zwlr_output_configuration_head_v1", | |||
| 1240 | + | "version": 4 | |||
| 1241 | + | }, | |||
| 1242 | + | { | |||
| 1243 | + | "name": "zwlr_output_configuration_v1", | |||
| 1244 | + | "version": 4 | |||
| 1245 | + | }, | |||
| 1246 | + | { | |||
| 1247 | + | "name": "zwlr_output_head_v1", | |||
| 1248 | + | "version": 4 | |||
| 1249 | + | }, | |||
| 1250 | + | { | |||
| 1251 | + | "name": "zwlr_output_manager_v1", | |||
| 1252 | + | "version": 4 | |||
| 1253 | + | }, | |||
| 1254 | + | { | |||
| 1255 | + | "name": "zwlr_output_mode_v1", | |||
| 1256 | + | "version": 3 | |||
| 1257 | + | } | |||
| 1258 | + | ], | |||
| 1259 | + | "deps": [] | |||
| 1260 | + | }, | |||
| 1261 | + | { | |||
| 1262 | + | "package": "wlroutputpowermanagement", | |||
| 1263 | + | "xml": "wlroutputpowermanagement.xml", | |||
| 1264 | + | "source": "wlr-protocols", | |||
| 1265 | + | "path": "unstable/wlr-output-power-management-unstable-v1.xml", | |||
| 1266 | + | "sha256": "7ebd98f3449d246a57829e4b4dd9fbc3ef98e3dd42fa94ea102f14f490eb20de", | |||
| 1267 | + | "license": "MIT", | |||
| 1268 | + | "interfaces": [ | |||
| 1269 | + | { | |||
| 1270 | + | "name": "zwlr_output_power_manager_v1", | |||
| 1271 | + | "version": 1 | |||
| 1272 | + | }, | |||
| 1273 | + | { | |||
| 1274 | + | "name": "zwlr_output_power_v1", | |||
| 1275 | + | "version": 1 | |||
| 1276 | + | } | |||
| 1277 | + | ], | |||
| 1278 | + | "deps": [ | |||
| 1279 | + | "wayland" | |||
| 1280 | + | ] | |||
| 1281 | + | }, | |||
| 1282 | + | { | |||
| 1283 | + | "package": "wlrscreencopy", | |||
| 1284 | + | "xml": "wlrscreencopy.xml", | |||
| 1285 | + | "source": "wlr-protocols", | |||
| 1286 | + | "path": "unstable/wlr-screencopy-unstable-v1.xml", | |||
| 1287 | + | "sha256": "131b8f9b4aad0c8a9cf705e90d2a1511a5ca0c477637fd3400cf1cc4fa963fb8", | |||
| 1288 | + | "license": "MIT", | |||
| 1289 | + | "interfaces": [ | |||
| 1290 | + | { | |||
| 1291 | + | "name": "zwlr_screencopy_frame_v1", | |||
| 1292 | + | "version": 3 | |||
| 1293 | + | }, | |||
| 1294 | + | { | |||
| 1295 | + | "name": "zwlr_screencopy_manager_v1", | |||
| 1296 | + | "version": 3 | |||
| 1297 | + | } | |||
| 1298 | + | ], | |||
| 1299 | + | "deps": [ | |||
| 1300 | + | "wayland" | |||
| 1301 | + | ] | |||
| 1302 | + | }, | |||
| 1303 | + | { | |||
| 1304 | + | "package": "wlrvirtualpointer", | |||
| 1305 | + | "xml": "wlrvirtualpointer.xml", | |||
| 1306 | + | "source": "wlr-protocols", | |||
| 1307 | + | "path": "unstable/wlr-virtual-pointer-unstable-v1.xml", | |||
| 1308 | + | "sha256": "3ff6d540be0bc5228195bf072bde42117ea17945a5c2061add5d3cf97d6bb524", | |||
| 1309 | + | "license": "MIT", | |||
| 1310 | + | "interfaces": [ | |||
| 1311 | + | { | |||
| 1312 | + | "name": "zwlr_virtual_pointer_manager_v1", | |||
| 1313 | + | "version": 2 | |||
| 1314 | + | }, | |||
| 1315 | + | { | |||
| 1316 | + | "name": "zwlr_virtual_pointer_v1", | |||
| 1317 | + | "version": 2 | |||
| 1318 | + | } | |||
| 1319 | + | ], | |||
| 1320 | + | "deps": [ | |||
| 1321 | + | "wayland" | |||
| 1322 | + | ] | |||
| 1323 | + | }, | |||
| 1324 | + | { | |||
| 1325 | + | "package": "xdgactivation", | |||
| 1326 | + | "xml": "xdgactivation.xml", | |||
| 1327 | + | "source": "wayland-protocols", | |||
| 1328 | + | "path": "staging/xdg-activation/xdg-activation-v1.xml", | |||
| 1329 | + | "sha256": "d8418be2d5738d50aff788bef1c7574f33f26659aa045447ff2ef9b78c58fe01", | |||
| 1330 | + | "license": "MIT", | |||
| 1331 | + | "interfaces": [ | |||
| 1332 | + | { | |||
| 1333 | + | "name": "xdg_activation_token_v1", | |||
| 1334 | + | "version": 1 | |||
| 1335 | + | }, | |||
| 1336 | + | { | |||
| 1337 | + | "name": "xdg_activation_v1", | |||
| 1338 | + | "version": 1 | |||
| 1339 | + | } | |||
| 1340 | + | ], | |||
| 1341 | + | "deps": [ | |||
| 1342 | + | "wayland" | |||
| 1343 | + | ] | |||
| 1344 | + | }, | |||
| 1345 | + | { | |||
| 1346 | + | "package": "xdgdecoration", | |||
| 1347 | + | "xml": "xdgdecoration.xml", | |||
| 1348 | + | "source": "wayland-protocols", | |||
| 1349 | + | "path": "unstable/xdg-decoration/xdg-decoration-unstable-v1.xml", | |||
| 1350 | + | "sha256": "68753c4a85a28659e3aa1fe0f138329a8bf3dff0b4789f4663a2c7fedbfecf2f", | |||
| 1351 | + | "license": "MIT", | |||
| 1352 | + | "interfaces": [ | |||
| 1353 | + | { | |||
| 1354 | + | "name": "zxdg_decoration_manager_v1", | |||
| 1355 | + | "version": 2 | |||
| 1356 | + | }, | |||
| 1357 | + | { | |||
| 1358 | + | "name": "zxdg_toplevel_decoration_v1", | |||
| 1359 | + | "version": 2 | |||
| 1360 | + | } | |||
| 1361 | + | ], | |||
| 1362 | + | "deps": [ | |||
| 1363 | + | "xdgshell" | |||
| 1364 | + | ] | |||
| 1365 | + | }, | |||
| 1366 | + | { | |||
| 1367 | + | "package": "xdgdialog", | |||
| 1368 | + | "xml": "xdgdialog.xml", | |||
| 1369 | + | "source": "wayland-protocols", | |||
| 1370 | + | "path": "staging/xdg-dialog/xdg-dialog-v1.xml", | |||
| 1371 | + | "sha256": "2822956bdf13d51848ff4b5e29c509028c1204c6e06262ee926b001f43a42dbb", | |||
| 1372 | + | "license": "MIT", | |||
| 1373 | + | "interfaces": [ | |||
| 1374 | + | { | |||
| 1375 | + | "name": "xdg_dialog_v1", | |||
| 1376 | + | "version": 1 | |||
| 1377 | + | }, | |||
| 1378 | + | { | |||
| 1379 | + | "name": "xdg_wm_dialog_v1", | |||
| 1380 | + | "version": 1 | |||
| 1381 | + | } | |||
| 1382 | + | ], | |||
| 1383 | + | "deps": [ | |||
| 1384 | + | "xdgshell" | |||
| 1385 | + | ] | |||
| 1386 | + | }, | |||
| 1387 | + | { | |||
| 1388 | + | "package": "xdgforeign", | |||
| 1389 | + | "xml": "xdgforeign.xml", | |||
| 1390 | + | "source": "wayland-protocols", | |||
| 1391 | + | "path": "unstable/xdg-foreign/xdg-foreign-unstable-v2.xml", | |||
| 1392 | + | "sha256": "625d83fbb068f48e69e739eafde507f10cdfe7480146f3ac10af9a2ddf551c80", | |||
| 1393 | + | "license": "MIT", | |||
| 1394 | + | "interfaces": [ | |||
| 1395 | + | { | |||
| 1396 | + | "name": "zxdg_exported_v2", | |||
| 1397 | + | "version": 1 | |||
| 1398 | + | }, | |||
| 1399 | + | { | |||
| 1400 | + | "name": "zxdg_exporter_v2", | |||
| 1401 | + | "version": 1 | |||
| 1402 | + | }, | |||
| 1403 | + | { | |||
| 1404 | + | "name": "zxdg_imported_v2", | |||
| 1405 | + | "version": 1 | |||
| 1406 | + | }, | |||
| 1407 | + | { | |||
| 1408 | + | "name": "zxdg_importer_v2", | |||
| 1409 | + | "version": 1 | |||
| 1410 | + | } | |||
| 1411 | + | ], | |||
| 1412 | + | "deps": [ | |||
| 1413 | + | "wayland" | |||
| 1414 | + | ] | |||
| 1415 | + | }, | |||
| 1416 | + | { | |||
| 1417 | + | "package": "xdgoutput", | |||
| 1418 | + | "xml": "xdgoutput.xml", | |||
| 1419 | + | "source": "wayland-protocols", | |||
| 1420 | + | "path": "unstable/xdg-output/xdg-output-unstable-v1.xml", | |||
| 1421 | + | "sha256": "363d547c3eefe8959160cac903ff90b311d4b183005557d73640d9df2cfd7f79", | |||
| 1422 | + | "license": "MIT", | |||
| 1423 | + | "interfaces": [ | |||
| 1424 | + | { | |||
| 1425 | + | "name": "zxdg_output_manager_v1", | |||
| 1426 | + | "version": 3 | |||
| 1427 | + | }, | |||
| 1428 | + | { | |||
| 1429 | + | "name": "zxdg_output_v1", | |||
| 1430 | + | "version": 3 | |||
| 1431 | + | } | |||
| 1432 | + | ], | |||
| 1433 | + | "deps": [ | |||
| 1434 | + | "wayland" | |||
| 1435 | + | ] | |||
| 1436 | + | }, | |||
| 1437 | + | { | |||
| 1438 | + | "package": "xdgsessionmanagement", | |||
| 1439 | + | "xml": "xdgsessionmanagement.xml", | |||
| 1440 | + | "source": "wayland-protocols", | |||
| 1441 | + | "path": "staging/xdg-session-management/xdg-session-management-v1.xml", | |||
| 1442 | + | "sha256": "3674591ca8e68f76297c535e8edd6783d84b59086c38ebe08ff5ff1f2dec5bae", | |||
| 1443 | + | "license": "MIT", | |||
| 1444 | + | "interfaces": [ | |||
| 1445 | + | { | |||
| 1446 | + | "name": "xdg_session_manager_v1", | |||
| 1447 | + | "version": 1 | |||
| 1448 | + | }, | |||
| 1449 | + | { | |||
| 1450 | + | "name": "xdg_session_v1", | |||
| 1451 | + | "version": 1 | |||
| 1452 | + | }, | |||
| 1453 | + | { | |||
| 1454 | + | "name": "xdg_toplevel_session_v1", | |||
| 1455 | + | "version": 1 | |||
| 1456 | + | } | |||
| 1457 | + | ], | |||
| 1458 | + | "deps": [ | |||
| 1459 | + | "xdgshell" | |||
| 1460 | + | ] | |||
| 1461 | + | }, | |||
| 1462 | + | { | |||
| 1463 | + | "package": "xdgshell", | |||
| 1464 | + | "xml": "xdgshell.xml", | |||
| 1465 | + | "source": "wayland-protocols", | |||
| 1466 | + | "path": "stable/xdg-shell/xdg-shell.xml", | |||
| 1467 | + | "sha256": "7ba7f9c8473deee674cb1f154a18abd0bb0cc072604fc055b0c15e459fc4c7df", | |||
| 1468 | + | "license": "MIT", | |||
| 1469 | + | "interfaces": [ | |||
| 1470 | + | { | |||
| 1471 | + | "name": "xdg_popup", | |||
| 1472 | + | "version": 7 | |||
| 1473 | + | }, | |||
| 1474 | + | { | |||
| 1475 | + | "name": "xdg_positioner", | |||
| 1476 | + | "version": 7 | |||
| 1477 | + | }, | |||
| 1478 | + | { | |||
| 1479 | + | "name": "xdg_surface", | |||
| 1480 | + | "version": 7 | |||
| 1481 | + | }, | |||
| 1482 | + | { | |||
| 1483 | + | "name": "xdg_toplevel", | |||
| 1484 | + | "version": 7 | |||
| 1485 | + | }, | |||
| 1486 | + | { | |||
| 1487 | + | "name": "xdg_wm_base", | |||
| 1488 | + | "version": 7 | |||
| 1489 | + | } | |||
| 1490 | + | ], | |||
| 1491 | + | "deps": [ | |||
| 1492 | + | "wayland" | |||
| 1493 | + | ] | |||
| 1494 | + | }, | |||
| 1495 | + | { | |||
| 1496 | + | "package": "xdgsystembell", | |||
| 1497 | + | "xml": "xdgsystembell.xml", | |||
| 1498 | + | "source": "wayland-protocols", | |||
| 1499 | + | "path": "staging/xdg-system-bell/xdg-system-bell-v1.xml", | |||
| 1500 | + | "sha256": "863c5efcb1a19961c019d23b9875ab84a158da802f5622f5ecc30522c6019330", | |||
| 1501 | + | "license": "MIT", | |||
| 1502 | + | "interfaces": [ | |||
| 1503 | + | { | |||
| 1504 | + | "name": "xdg_system_bell_v1", | |||
| 1505 | + | "version": 1 | |||
| 1506 | + | } | |||
| 1507 | + | ], | |||
| 1508 | + | "deps": [ | |||
| 1509 | + | "wayland" | |||
| 1510 | + | ] | |||
| 1511 | + | }, | |||
| 1512 | + | { | |||
| 1513 | + | "package": "xdgtopleveldrag", | |||
| 1514 | + | "xml": "xdgtopleveldrag.xml", | |||
| 1515 | + | "source": "wayland-protocols", | |||
| 1516 | + | "path": "staging/xdg-toplevel-drag/xdg-toplevel-drag-v1.xml", | |||
| 1517 | + | "sha256": "687d7a1db0ced0e2794dc2d5be1a80b1dc71c46a055aedd882838586345ee1dc", | |||
| 1518 | + | "license": "MIT", | |||
| 1519 | + | "interfaces": [ | |||
| 1520 | + | { | |||
| 1521 | + | "name": "xdg_toplevel_drag_manager_v1", | |||
| 1522 | + | "version": 1 | |||
| 1523 | + | }, | |||
| 1524 | + | { | |||
| 1525 | + | "name": "xdg_toplevel_drag_v1", | |||
| 1526 | + | "version": 1 | |||
| 1527 | + | } | |||
| 1528 | + | ], | |||
| 1529 | + | "deps": [ | |||
| 1530 | + | "wayland", | |||
| 1531 | + | "xdgshell" | |||
| 1532 | + | ] | |||
| 1533 | + | }, | |||
| 1534 | + | { | |||
| 1535 | + | "package": "xdgtoplevelicon", | |||
| 1536 | + | "xml": "xdgtoplevelicon.xml", | |||
| 1537 | + | "source": "wayland-protocols", | |||
| 1538 | + | "path": "staging/xdg-toplevel-icon/xdg-toplevel-icon-v1.xml", | |||
| 1539 | + | "sha256": "5e57a72fa9ccf1666c56d49cc86408f068c21e5e6a09ddd468ee65d08478f882", | |||
| 1540 | + | "license": "MIT", | |||
| 1541 | + | "interfaces": [ | |||
| 1542 | + | { | |||
| 1543 | + | "name": "xdg_toplevel_icon_manager_v1", | |||
| 1544 | + | "version": 1 | |||
| 1545 | + | }, | |||
| 1546 | + | { | |||
| 1547 | + | "name": "xdg_toplevel_icon_v1", | |||
| 1548 | + | "version": 1 | |||
| 1549 | + | } | |||
| 1550 | + | ], | |||
| 1551 | + | "deps": [ | |||
| 1552 | + | "wayland", | |||
| 1553 | + | "xdgshell" | |||
| 1554 | + | ] | |||
| 1555 | + | }, | |||
| 1556 | + | { | |||
| 1557 | + | "package": "xdgtopleveltag", | |||
| 1558 | + | "xml": "xdgtopleveltag.xml", | |||
| 1559 | + | "source": "wayland-protocols", | |||
| 1560 | + | "path": "staging/xdg-toplevel-tag/xdg-toplevel-tag-v1.xml", | |||
| 1561 | + | "sha256": "bde3615b434a237388c5592028345eef185ab1e7ade9023dd2413a4b2c56ab9f", | |||
| 1562 | + | "license": "MIT", | |||
| 1563 | + | "interfaces": [ | |||
| 1564 | + | { | |||
| 1565 | + | "name": "xdg_toplevel_tag_manager_v1", | |||
| 1566 | + | "version": 1 | |||
| 1567 | + | } | |||
| 1568 | + | ], | |||
| 1569 | + | "deps": [ | |||
| 1570 | + | "xdgshell" | |||
| 1571 | + | ] | |||
| 1572 | + | }, | |||
| 1573 | + | { | |||
| 1574 | + | "package": "xwaylandkeyboardgrab", | |||
| 1575 | + | "xml": "xwaylandkeyboardgrab.xml", | |||
| 1576 | + | "source": "wayland-protocols", | |||
| 1577 | + | "path": "unstable/xwayland-keyboard-grab/xwayland-keyboard-grab-unstable-v1.xml", | |||
| 1578 | + | "sha256": "fcc1e24ec465c209de576f75bf87438b8339e4da42051a3f26b48916292c7c6f", | |||
| 1579 | + | "license": "MIT", | |||
| 1580 | + | "interfaces": [ | |||
| 1581 | + | { | |||
| 1582 | + | "name": "zwp_xwayland_keyboard_grab_manager_v1", | |||
| 1583 | + | "version": 1 | |||
| 1584 | + | }, | |||
| 1585 | + | { | |||
| 1586 | + | "name": "zwp_xwayland_keyboard_grab_v1", | |||
| 1587 | + | "version": 1 | |||
| 1588 | + | } | |||
| 1589 | + | ], | |||
| 1590 | + | "deps": [ | |||
| 1591 | + | "wayland" | |||
| 1592 | + | ] | |||
| 1593 | + | }, | |||
| 1594 | + | { | |||
| 1595 | + | "package": "xwaylandshell", | |||
| 1596 | + | "xml": "xwaylandshell.xml", | |||
| 1597 | + | "source": "wayland-protocols", | |||
| 1598 | + | "path": "staging/xwayland-shell/xwayland-shell-v1.xml", | |||
| 1599 | + | "sha256": "a6589c3205d1f424cbd2708c1507daf143db2d355dcd931f6f79986c0dc205b6", | |||
| 1600 | + | "license": "MIT", | |||
| 1601 | + | "interfaces": [ | |||
| 1602 | + | { | |||
| 1603 | + | "name": "xwayland_shell_v1", | |||
| 1604 | + | "version": 1 | |||
| 1605 | + | }, | |||
| 1606 | + | { | |||
| 1607 | + | "name": "xwayland_surface_v1", | |||
| 1608 | + | "version": 1 | |||
| 1609 | + | } | |||
| 1610 | + | ], | |||
| 1611 | + | "deps": [ | |||
| 1612 | + | "wayland" | |||
| 1613 | + | ] | |||
| 1614 | + | } | |||
| 1615 | + | ] | |||
| 4 | } | 1616 | } | ||
A spec/naming_test.go +39 -0
| @@ -0,0 +1,39 @@ | |||||
| 1 | + | package spec | |||
| 2 | + | ||||
| 3 | + | import "testing" | |||
| 4 | + | ||||
| 5 | + | func TestPackageName(t *testing.T) { | |||
| 6 | + | tests := []struct{ in, want string }{ | |||
| 7 | + | {"wlr-layer-shell-unstable-v1.xml", "wlrlayershell"}, | |||
| 8 | + | {"tablet-v2.xml", "tablet"}, | |||
| 9 | + | {"presentation-time.xml", "presentationtime"}, | |||
| 10 | + | {"xdg-shell.xml", "xdgshell"}, | |||
| 11 | + | {"wayland.xml", "wayland"}, | |||
| 12 | + | {"ext-foreign-toplevel-list-v1.xml", "extforeigntoplevellist"}, | |||
| 13 | + | {"xdg-foreign-unstable-v2.xml", "xdgforeign"}, | |||
| 14 | + | {"stable/xdg-shell/xdg-shell.xml", "xdgshell"}, | |||
| 15 | + | {"server-decoration.xml", "serverdecoration"}, | |||
| 16 | + | } | |||
| 17 | + | for _, tt := range tests { | |||
| 18 | + | got := PackageName(tt.in) | |||
| 19 | + | if got != tt.want { | |||
| 20 | + | t.Errorf("PackageName(%q) = %q, want %q", tt.in, got, tt.want) | |||
| 21 | + | } | |||
| 22 | + | if !ValidPackageName(got) { | |||
| 23 | + | t.Errorf("PackageName(%q) = %q is not a valid Go package name", tt.in, got) | |||
| 24 | + | } | |||
| 25 | + | } | |||
| 26 | + | } | |||
| 27 | + | ||||
| 28 | + | func TestValidPackageName(t *testing.T) { | |||
| 29 | + | for _, name := range []string{"wayland", "xdgshell", "a1"} { | |||
| 30 | + | if !ValidPackageName(name) { | |||
| 31 | + | t.Errorf("ValidPackageName(%q) = false, want true", name) | |||
| 32 | + | } | |||
| 33 | + | } | |||
| 34 | + | for _, name := range []string{"", "_", "1a", "a-b", "func", "type", "a.b"} { | |||
| 35 | + | if ValidPackageName(name) { | |||
| 36 | + | t.Errorf("ValidPackageName(%q) = true, want false", name) | |||
| 37 | + | } | |||
| 38 | + | } | |||
| 39 | + | } | |||
A spec/protocol_test.go +185 -0
| @@ -0,0 +1,185 @@ | |||||
| 1 | + | package spec | |||
| 2 | + | ||||
| 3 | + | import ( | |||
| 4 | + | "os" | |||
| 5 | + | "reflect" | |||
| 6 | + | "strings" | |||
| 7 | + | "testing" | |||
| 8 | + | ) | |||
| 9 | + | ||||
| 10 | + | func readTestdata(t *testing.T, name string) []byte { | |||
| 11 | + | t.Helper() | |||
| 12 | + | b, err := os.ReadFile("testdata/" + name) | |||
| 13 | + | if err != nil { | |||
| 14 | + | t.Fatal(err) | |||
| 15 | + | } | |||
| 16 | + | return b | |||
| 17 | + | } | |||
| 18 | + | ||||
| 19 | + | func findInterface(t *testing.T, p *Protocol, name string) Interface { | |||
| 20 | + | t.Helper() | |||
| 21 | + | for _, it := range p.Interfaces { | |||
| 22 | + | if it.Name == name { | |||
| 23 | + | return it | |||
| 24 | + | } | |||
| 25 | + | } | |||
| 26 | + | t.Fatalf("interface %q not found", name) | |||
| 27 | + | return Interface{} | |||
| 28 | + | } | |||
| 29 | + | ||||
| 30 | + | func findMessage(t *testing.T, ms []Message, name string) Message { | |||
| 31 | + | t.Helper() | |||
| 32 | + | for _, m := range ms { | |||
| 33 | + | if m.Name == name { | |||
| 34 | + | return m | |||
| 35 | + | } | |||
| 36 | + | } | |||
| 37 | + | t.Fatalf("message %q not found", name) | |||
| 38 | + | return Message{} | |||
| 39 | + | } | |||
| 40 | + | ||||
| 41 | + | func findEnum(t *testing.T, it Interface, name string) Enum { | |||
| 42 | + | t.Helper() | |||
| 43 | + | for _, e := range it.Enums { | |||
| 44 | + | if e.Name == name { | |||
| 45 | + | return e | |||
| 46 | + | } | |||
| 47 | + | } | |||
| 48 | + | t.Fatalf("enum %q not found in %s", name, it.Name) | |||
| 49 | + | return Enum{} | |||
| 50 | + | } | |||
| 51 | + | ||||
| 52 | + | func TestParseWayland(t *testing.T) { | |||
| 53 | + | p, err := Parse(readTestdata(t, "wayland.xml")) | |||
| 54 | + | if err != nil { | |||
| 55 | + | t.Fatal(err) | |||
| 56 | + | } | |||
| 57 | + | if p.Name != "wayland" { | |||
| 58 | + | t.Errorf("Name = %q", p.Name) | |||
| 59 | + | } | |||
| 60 | + | if !strings.Contains(p.Copyright, "Kristian") { | |||
| 61 | + | t.Errorf("Copyright not preserved: %q", p.Copyright) | |||
| 62 | + | } | |||
| 63 | + | if len(p.Interfaces) != 23 { | |||
| 64 | + | t.Errorf("got %d interfaces, want 23", len(p.Interfaces)) | |||
| 65 | + | } | |||
| 66 | + | if got := findInterface(t, p, "wl_compositor").Version; got != 7 { | |||
| 67 | + | t.Errorf("wl_compositor version = %d, want 7", got) | |||
| 68 | + | } | |||
| 69 | + | ||||
| 70 | + | // since on a message. | |||
| 71 | + | release := findMessage(t, findInterface(t, p, "wl_pointer").Requests, "release") | |||
| 72 | + | if release.Type != "destructor" || release.Since != 3 { | |||
| 73 | + | t.Errorf("wl_pointer.release = type %q since %d", release.Type, release.Since) | |||
| 74 | + | } | |||
| 75 | + | if got := findMessage(t, findInterface(t, p, "wl_pointer").Requests, "set_cursor").SinceOrOne(); got != 1 { | |||
| 76 | + | t.Errorf("SinceOrOne of unversioned message = %d, want 1", got) | |||
| 77 | + | } | |||
| 78 | + | if got := release.SinceOrOne(); got != 3 { | |||
| 79 | + | t.Errorf("SinceOrOne = %d, want 3", got) | |||
| 80 | + | } | |||
| 81 | + | ||||
| 82 | + | // since on an enum. | |||
| 83 | + | if e := findEnum(t, findInterface(t, p, "wl_data_device_manager"), "dnd_action"); !e.Bitfield || e.Since != 3 { | |||
| 84 | + | t.Errorf("dnd_action = bitfield %v since %d, want true 3", e.Bitfield, e.Since) | |||
| 85 | + | } | |||
| 86 | + | ||||
| 87 | + | // bitfield. | |||
| 88 | + | seat := findInterface(t, p, "wl_seat") | |||
| 89 | + | if !findEnum(t, seat, "capability").Bitfield { | |||
| 90 | + | t.Error("wl_seat.capability should be a bitfield") | |||
| 91 | + | } | |||
| 92 | + | if findEnum(t, seat, "error").Bitfield { | |||
| 93 | + | t.Error("wl_seat.error should not be a bitfield") | |||
| 94 | + | } | |||
| 95 | + | if len(findEnum(t, seat, "capability").Entries) == 0 { | |||
| 96 | + | t.Error("capability has no entries") | |||
| 97 | + | } | |||
| 98 | + | ||||
| 99 | + | // allow-null and interface refs. | |||
| 100 | + | var nullArg, plainArg *Arg | |||
| 101 | + | for _, m := range findInterface(t, p, "wl_data_device").Requests { | |||
| 102 | + | for i := range m.Args { | |||
| 103 | + | a := &m.Args[i] | |||
| 104 | + | if m.Name == "set_selection" && a.Name == "source" { | |||
| 105 | + | nullArg = a | |||
| 106 | + | } | |||
| 107 | + | if m.Name == "start_drag" && a.Name == "origin" { | |||
| 108 | + | plainArg = a | |||
| 109 | + | } | |||
| 110 | + | } | |||
| 111 | + | } | |||
| 112 | + | if nullArg == nil || !nullArg.AllowNull || nullArg.Interface != "wl_data_source" || nullArg.Type != "object" { | |||
| 113 | + | t.Errorf("set_selection.source = %+v", nullArg) | |||
| 114 | + | } | |||
| 115 | + | if plainArg == nil || plainArg.AllowNull { | |||
| 116 | + | t.Errorf("start_drag.origin = %+v", plainArg) | |||
| 117 | + | } | |||
| 118 | + | ||||
| 119 | + | // enum refs, qualified and unqualified. | |||
| 120 | + | create := findMessage(t, findInterface(t, p, "wl_shm_pool").Requests, "create_buffer") | |||
| 121 | + | var enumRefs []string | |||
| 122 | + | for _, a := range create.Args { | |||
| 123 | + | if a.Enum != "" { | |||
| 124 | + | enumRefs = append(enumRefs, a.Enum) | |||
| 125 | + | } | |||
| 126 | + | } | |||
| 127 | + | if !reflect.DeepEqual(enumRefs, []string{"wl_shm.format"}) { | |||
| 128 | + | t.Errorf("create_buffer enum refs = %v", enumRefs) | |||
| 129 | + | } | |||
| 130 | + | var found bool | |||
| 131 | + | for _, a := range findMessage(t, findInterface(t, p, "wl_output").Events, "mode").Args { | |||
| 132 | + | if a.Name == "flags" && a.Enum == "mode" && a.Summary != "" { | |||
| 133 | + | found = true | |||
| 134 | + | } | |||
| 135 | + | } | |||
| 136 | + | if !found { | |||
| 137 | + | t.Error("wl_output.mode flags enum ref/summary not preserved") | |||
| 138 | + | } | |||
| 139 | + | ||||
| 140 | + | // Descriptions. | |||
| 141 | + | if d := findInterface(t, p, "wl_display").Description; d == nil || d.Summary == "" || strings.TrimSpace(d.Text) == "" { | |||
| 142 | + | t.Errorf("description not parsed: %+v", d) | |||
| 143 | + | } | |||
| 144 | + | } | |||
| 145 | + | ||||
| 146 | + | func TestParseFixture(t *testing.T) { | |||
| 147 | + | p, err := Parse(readTestdata(t, "protocol_fixture.xml")) | |||
| 148 | + | if err != nil { | |||
| 149 | + | t.Fatal(err) | |||
| 150 | + | } | |||
| 151 | + | if p.Name != "wlvision_fixture" || !strings.Contains(p.Copyright, "Synthetic protocol") { | |||
| 152 | + | t.Errorf("protocol = %q / %q", p.Name, p.Copyright) | |||
| 153 | + | } | |||
| 154 | + | if len(p.Interfaces) != 3 { | |||
| 155 | + | t.Fatalf("got %d interfaces", len(p.Interfaces)) | |||
| 156 | + | } | |||
| 157 | + | mgr := findInterface(t, p, "zwlr_fixture_manager_v1") | |||
| 158 | + | if mgr.Version != 2 || len(mgr.Requests) != 10 { | |||
| 159 | + | t.Errorf("manager version %d requests %d", mgr.Version, len(mgr.Requests)) | |||
| 160 | + | } | |||
| 161 | + | out := findMessage(t, mgr.Requests, "set_optional_output").Args[0] | |||
| 162 | + | if !out.AllowNull || out.Interface != "wl_output" { | |||
| 163 | + | t.Errorf("set_optional_output arg = %+v", out) | |||
| 164 | + | } | |||
| 165 | + | thing := findInterface(t, p, "zwlr_fixture_thing_v1") | |||
| 166 | + | if len(thing.Events) != 7 || len(thing.Enums) != 1 || thing.Enums[0].Entries[1].Value != "1" { | |||
| 167 | + | t.Errorf("thing = %d events, enums %+v", len(thing.Events), thing.Enums) | |||
| 168 | + | } | |||
| 169 | + | want := []string{"wl_seat", "zwlr_fixture_thing_v1", "wl_region", "wl_buffer", "wl_output", "zwlr_fixture_mode_v1", "wl_surface"} | |||
| 170 | + | if got := p.ReferencedInterfaces(); !reflect.DeepEqual(got, want) { | |||
| 171 | + | t.Errorf("ReferencedInterfaces = %v, want %v", got, want) | |||
| 172 | + | } | |||
| 173 | + | } | |||
| 174 | + | ||||
| 175 | + | func TestParseErrors(t *testing.T) { | |||
| 176 | + | for name, in := range map[string]string{ | |||
| 177 | + | "not xml": "nope", | |||
| 178 | + | "no name": `<protocol></protocol>`, | |||
| 179 | + | "wrong tag": `<other name="x"/>`, | |||
| 180 | + | } { | |||
| 181 | + | if _, err := Parse([]byte(in)); err == nil { | |||
| 182 | + | t.Errorf("%s: expected error", name) | |||
| 183 | + | } | |||
| 184 | + | } | |||
| 185 | + | } | |||
A spec/spec_test.go +157 -0
| @@ -0,0 +1,157 @@ | |||||
| 1 | + | package spec | |||
| 2 | + | ||||
| 3 | + | import ( | |||
| 4 | + | "crypto/sha256" | |||
| 5 | + | "encoding/hex" | |||
| 6 | + | "path" | |||
| 7 | + | "reflect" | |||
| 8 | + | "sort" | |||
| 9 | + | "strings" | |||
| 10 | + | "testing" | |||
| 11 | + | ) | |||
| 12 | + | ||||
| 13 | + | func TestManifestInvariants(t *testing.T) { | |||
| 14 | + | m, err := Load() | |||
| 15 | + | if err != nil { | |||
| 16 | + | t.Fatal(err) | |||
| 17 | + | } | |||
| 18 | + | if len(m.Protocols) == 0 { | |||
| 19 | + | t.Fatal("manifest has no protocols; run `go run ./cmd/wlbsync`") | |||
| 20 | + | } | |||
| 21 | + | if len(m.Sources) == 0 { | |||
| 22 | + | t.Fatal("manifest has no sources") | |||
| 23 | + | } | |||
| 24 | + | ||||
| 25 | + | sources := map[string]bool{} | |||
| 26 | + | for _, s := range m.Sources { | |||
| 27 | + | if s.ID == "" || s.URL == "" || s.Ref == "" || len(s.Commit) != 40 { | |||
| 28 | + | t.Errorf("incomplete source %+v", s) | |||
| 29 | + | } | |||
| 30 | + | sources[s.ID] = true | |||
| 31 | + | } | |||
| 32 | + | ||||
| 33 | + | owners := map[string]string{} | |||
| 34 | + | parsed := map[string]*Protocol{} | |||
| 35 | + | listed := map[string]bool{} | |||
| 36 | + | var pkgs []string | |||
| 37 | + | ||||
| 38 | + | for _, e := range m.Protocols { | |||
| 39 | + | pkgs = append(pkgs, e.Package) | |||
| 40 | + | listed[e.XML] = true | |||
| 41 | + | if !sources[e.Source] { | |||
| 42 | + | t.Errorf("%s: unknown source %q", e.Package, e.Source) | |||
| 43 | + | } | |||
| 44 | + | if !ValidPackageName(e.Package) { | |||
| 45 | + | t.Errorf("%s: invalid package name", e.Package) | |||
| 46 | + | } | |||
| 47 | + | if e.XML != e.Package+".xml" { | |||
| 48 | + | t.Errorf("%s: xml file %q, want %q", e.Package, e.XML, e.Package+".xml") | |||
| 49 | + | } | |||
| 50 | + | if e.Package != "wayland" && PackageName(path.Base(e.Path)) != e.Package { | |||
| 51 | + | t.Errorf("%s: PackageName(%q) = %q", e.Package, e.Path, PackageName(path.Base(e.Path))) | |||
| 52 | + | } | |||
| 53 | + | wantLicense := "MIT" | |||
| 54 | + | if e.Package == "serverdecoration" { | |||
| 55 | + | wantLicense = "LGPL-2.1-or-later" | |||
| 56 | + | } | |||
| 57 | + | if e.License != wantLicense { | |||
| 58 | + | t.Errorf("%s: license %q, want %q", e.Package, e.License, wantLicense) | |||
| 59 | + | } | |||
| 60 | + | ||||
| 61 | + | data, err := Open(e.Package) | |||
| 62 | + | if err != nil { | |||
| 63 | + | t.Errorf("%s: %v", e.Package, err) | |||
| 64 | + | continue | |||
| 65 | + | } | |||
| 66 | + | sum := sha256.Sum256(data) | |||
| 67 | + | if got := hex.EncodeToString(sum[:]); got != e.SHA256 { | |||
| 68 | + | t.Errorf("%s: sha256 %s, manifest has %s", e.Package, got, e.SHA256) | |||
| 69 | + | } | |||
| 70 | + | if !strings.Contains(string(data), "<copyright>") { | |||
| 71 | + | t.Errorf("%s: missing <copyright>", e.Package) | |||
| 72 | + | } | |||
| 73 | + | p, err := Parse(data) | |||
| 74 | + | if err != nil { | |||
| 75 | + | t.Errorf("%s: %v", e.Package, err) | |||
| 76 | + | continue | |||
| 77 | + | } | |||
| 78 | + | parsed[e.Package] = p | |||
| 79 | + | ||||
| 80 | + | var want []InterfaceEntry | |||
| 81 | + | for _, it := range p.Interfaces { | |||
| 82 | + | want = append(want, InterfaceEntry{Name: it.Name, Version: it.Version}) | |||
| 83 | + | if prev, dup := owners[it.Name]; dup { | |||
| 84 | + | t.Errorf("interface %s owned by both %s and %s", it.Name, prev, e.Package) | |||
| 85 | + | } | |||
| 86 | + | owners[it.Name] = e.Package | |||
| 87 | + | } | |||
| 88 | + | sort.Slice(want, func(i, j int) bool { return want[i].Name < want[j].Name }) | |||
| 89 | + | if !reflect.DeepEqual(e.Interfaces, want) { | |||
| 90 | + | t.Errorf("%s: manifest interfaces %v, XML has %v", e.Package, e.Interfaces, want) | |||
| 91 | + | } | |||
| 92 | + | } | |||
| 93 | + | if !sort.StringsAreSorted(pkgs) { | |||
| 94 | + | t.Error("manifest protocols are not sorted by package") | |||
| 95 | + | } | |||
| 96 | + | ||||
| 97 | + | for _, e := range m.Protocols { | |||
| 98 | + | p := parsed[e.Package] | |||
| 99 | + | if p == nil { | |||
| 100 | + | continue | |||
| 101 | + | } | |||
| 102 | + | depSet := map[string]bool{} | |||
| 103 | + | for _, ref := range p.ReferencedInterfaces() { | |||
| 104 | + | owner, ok := owners[ref] | |||
| 105 | + | if !ok { | |||
| 106 | + | t.Errorf("%s references unknown interface %s", e.Package, ref) | |||
| 107 | + | continue | |||
| 108 | + | } | |||
| 109 | + | if owner != e.Package { | |||
| 110 | + | depSet[owner] = true | |||
| 111 | + | } | |||
| 112 | + | } | |||
| 113 | + | want := []string{} | |||
| 114 | + | for d := range depSet { | |||
| 115 | + | want = append(want, d) | |||
| 116 | + | } | |||
| 117 | + | sort.Strings(want) | |||
| 118 | + | if !reflect.DeepEqual(e.Deps, want) { | |||
| 119 | + | t.Errorf("%s: deps %v, want %v", e.Package, e.Deps, want) | |||
| 120 | + | } | |||
| 121 | + | } | |||
| 122 | + | ||||
| 123 | + | entries, err := files.ReadDir("xml") | |||
| 124 | + | if err != nil { | |||
| 125 | + | t.Fatal(err) | |||
| 126 | + | } | |||
| 127 | + | for _, f := range entries { | |||
| 128 | + | if !listed[f.Name()] { | |||
| 129 | + | t.Errorf("spec/xml/%s is not in the manifest", f.Name()) | |||
| 130 | + | } | |||
| 131 | + | } | |||
| 132 | + | if len(entries) != len(m.Protocols) { | |||
| 133 | + | t.Errorf("%d files in spec/xml, %d manifest entries", len(entries), len(m.Protocols)) | |||
| 134 | + | } | |||
| 135 | + | } | |||
| 136 | + | ||||
| 137 | + | func TestManifestAPI(t *testing.T) { | |||
| 138 | + | m, err := Load() | |||
| 139 | + | if err != nil { | |||
| 140 | + | t.Fatal(err) | |||
| 141 | + | } | |||
| 142 | + | if pkg, ok := m.Lookup("wl_surface"); !ok || pkg != "wayland" { | |||
| 143 | + | t.Errorf("Lookup(wl_surface) = %q, %v", pkg, ok) | |||
| 144 | + | } | |||
| 145 | + | if pkg, ok := m.Lookup("xdg_wm_base"); !ok || pkg != "xdgshell" { | |||
| 146 | + | t.Errorf("Lookup(xdg_wm_base) = %q, %v", pkg, ok) | |||
| 147 | + | } | |||
| 148 | + | if _, ok := m.Lookup("nope"); ok { | |||
| 149 | + | t.Error("Lookup(nope) succeeded") | |||
| 150 | + | } | |||
| 151 | + | if _, err := Open("nope"); err == nil { | |||
| 152 | + | t.Error("Open(nope) succeeded") | |||
| 153 | + | } | |||
| 154 | + | if _, ok := m.Package("xdgshell"); !ok { | |||
| 155 | + | t.Error("Package(xdgshell) not found") | |||
| 156 | + | } | |||
| 157 | + | } | |||
A spec/xml/alphamodifier.xml +103 -0
| @@ -0,0 +1,103 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="alpha_modifier_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2024 Xaver Hugl | |||
| 5 | + | ||||
| 6 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 7 | + | copy of this software and associated documentation files (the "Software"), | |||
| 8 | + | to deal in the Software without restriction, including without limitation | |||
| 9 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 10 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 11 | + | Software is furnished to do so, subject to the following conditions: | |||
| 12 | + | ||||
| 13 | + | The above copyright notice and this permission notice (including the next | |||
| 14 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 15 | + | Software. | |||
| 16 | + | ||||
| 17 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 18 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 19 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 20 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 21 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 22 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 23 | + | DEALINGS IN THE SOFTWARE. | |||
| 24 | + | </copyright> | |||
| 25 | + | ||||
| 26 | + | <interface name="wp_alpha_modifier_v1" version="1"> | |||
| 27 | + | <description summary="surface alpha modifier manager"> | |||
| 28 | + | This interface allows a client to set a factor for the alpha values on a | |||
| 29 | + | surface, which can be used to offload such operations to the compositor, | |||
| 30 | + | which can in turn for example offload them to KMS. | |||
| 31 | + | ||||
| 32 | + | Warning! The protocol described in this file is currently in the testing | |||
| 33 | + | phase. Backward compatible changes may be added together with the | |||
| 34 | + | corresponding interface version bump. Backward incompatible changes can | |||
| 35 | + | only be done by creating a new major version of the extension. | |||
| 36 | + | </description> | |||
| 37 | + | ||||
| 38 | + | <request name="destroy" type="destructor"> | |||
| 39 | + | <description summary="destroy the alpha modifier manager object"> | |||
| 40 | + | Destroy the alpha modifier manager. This doesn't destroy objects | |||
| 41 | + | created with the manager. | |||
| 42 | + | </description> | |||
| 43 | + | </request> | |||
| 44 | + | ||||
| 45 | + | <enum name="error"> | |||
| 46 | + | <entry name="already_constructed" value="0" | |||
| 47 | + | summary="wl_surface already has a alpha modifier object"/> | |||
| 48 | + | </enum> | |||
| 49 | + | ||||
| 50 | + | <request name="get_surface"> | |||
| 51 | + | <description summary="create a new alpha modifier surface object"> | |||
| 52 | + | Create a new alpha modifier surface object associated with the | |||
| 53 | + | given wl_surface. If there is already such an object associated with | |||
| 54 | + | the wl_surface, the already_constructed error will be raised. | |||
| 55 | + | </description> | |||
| 56 | + | <arg name="id" type="new_id" interface="wp_alpha_modifier_surface_v1"/> | |||
| 57 | + | <arg name="surface" type="object" interface="wl_surface"/> | |||
| 58 | + | </request> | |||
| 59 | + | </interface> | |||
| 60 | + | ||||
| 61 | + | <interface name="wp_alpha_modifier_surface_v1" version="1"> | |||
| 62 | + | <description summary="alpha modifier object for a surface"> | |||
| 63 | + | This interface allows the client to set a factor for the alpha values on | |||
| 64 | + | a surface, which can be used to offload such operations to the compositor. | |||
| 65 | + | The default factor is UINT32_MAX. | |||
| 66 | + | ||||
| 67 | + | This object has to be destroyed before the associated wl_surface. Once the | |||
| 68 | + | wl_surface is destroyed, all request on this object will raise the | |||
| 69 | + | no_surface error. | |||
| 70 | + | </description> | |||
| 71 | + | ||||
| 72 | + | <enum name="error"> | |||
| 73 | + | <entry name="no_surface" value="0" summary="wl_surface was destroyed"/> | |||
| 74 | + | </enum> | |||
| 75 | + | ||||
| 76 | + | <request name="destroy" type="destructor"> | |||
| 77 | + | <description summary="destroy the alpha modifier object"> | |||
| 78 | + | This destroys the object, and is equivalent to set_multiplier with | |||
| 79 | + | a value of UINT32_MAX, with the same double-buffered semantics as | |||
| 80 | + | set_multiplier. | |||
| 81 | + | </description> | |||
| 82 | + | </request> | |||
| 83 | + | ||||
| 84 | + | <request name="set_multiplier"> | |||
| 85 | + | <description summary="specify the alpha multiplier"> | |||
| 86 | + | Sets the alpha multiplier for the surface. The alpha multiplier is | |||
| 87 | + | double-buffered state, see wl_surface.commit for details. | |||
| 88 | + | ||||
| 89 | + | This factor is applied in the compositor's blending space, as an | |||
| 90 | + | additional step after the processing of per-pixel alpha values for the | |||
| 91 | + | wl_surface. The exact meaning of the factor is thus undefined, unless | |||
| 92 | + | the blending space is specified in a different extension. | |||
| 93 | + | ||||
| 94 | + | This multiplier is applied even if the buffer attached to the | |||
| 95 | + | wl_surface doesn't have an alpha channel; in that case an alpha value | |||
| 96 | + | of one is used instead. | |||
| 97 | + | ||||
| 98 | + | Zero means completely transparent, UINT32_MAX means completely opaque. | |||
| 99 | + | </description> | |||
| 100 | + | <arg name="factor" type="uint"/> | |||
| 101 | + | </request> | |||
| 102 | + | </interface> | |||
| 103 | + | </protocol> | |||
A spec/xml/colormanagement.xml +1756 -0
| @@ -0,0 +1,1756 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="color_management_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright 2019 Sebastian Wick | |||
| 5 | + | Copyright 2019 Erwin Burema | |||
| 6 | + | Copyright 2020 AMD | |||
| 7 | + | Copyright 2020-2024 Collabora, Ltd. | |||
| 8 | + | Copyright 2024 Xaver Hugl | |||
| 9 | + | Copyright 2022-2025 Red Hat, Inc. | |||
| 10 | + | ||||
| 11 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 12 | + | copy of this software and associated documentation files (the "Software"), | |||
| 13 | + | to deal in the Software without restriction, including without limitation | |||
| 14 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 15 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 16 | + | Software is furnished to do so, subject to the following conditions: | |||
| 17 | + | ||||
| 18 | + | The above copyright notice and this permission notice (including the next | |||
| 19 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 20 | + | Software. | |||
| 21 | + | ||||
| 22 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 23 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 24 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 25 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 26 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 27 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 28 | + | DEALINGS IN THE SOFTWARE. | |||
| 29 | + | </copyright> | |||
| 30 | + | ||||
| 31 | + | <description summary="color management protocol"> | |||
| 32 | + | The aim of the color management extension is to allow clients to know | |||
| 33 | + | the color properties of outputs, and to tell the compositor about the color | |||
| 34 | + | properties of their content on surfaces. All surface contents must be | |||
| 35 | + | readily intended for some display, but not necessarily for the display at | |||
| 36 | + | hand. Doing this enables a compositor to perform automatic color management | |||
| 37 | + | of content for different outputs according to how content is intended to | |||
| 38 | + | look like. | |||
| 39 | + | ||||
| 40 | + | For an introduction, see the section "Color management" in the Wayland | |||
| 41 | + | documentation at https://wayland.freedesktop.org/docs/html/ . | |||
| 42 | + | ||||
| 43 | + | The color properties are represented as an image description object which | |||
| 44 | + | is immutable after it has been created. A wl_output always has an | |||
| 45 | + | associated image description that clients can observe. A wl_surface | |||
| 46 | + | always has an associated preferred image description as a hint chosen by | |||
| 47 | + | the compositor that clients can also observe. Clients can set an image | |||
| 48 | + | description on a wl_surface to denote the color characteristics of the | |||
| 49 | + | surface contents. | |||
| 50 | + | ||||
| 51 | + | An image description essentially defines a display and (indirectly) its | |||
| 52 | + | viewing environment. An image description includes SDR and HDR colorimetry | |||
| 53 | + | and encoding, HDR metadata, and some parameters related to the viewing | |||
| 54 | + | environment. An image description does not include the properties set | |||
| 55 | + | through color-representation extension. It is expected that the | |||
| 56 | + | color-representation extension is used in conjunction with the | |||
| 57 | + | color-management extension when necessary, particularly with the YUV family | |||
| 58 | + | of pixel formats. | |||
| 59 | + | ||||
| 60 | + | The normative appendix for this protocol is in the appendix.md file beside | |||
| 61 | + | this XML file. | |||
| 62 | + | ||||
| 63 | + | The color-and-hdr repository | |||
| 64 | + | (https://gitlab.freedesktop.org/pq/color-and-hdr) contains | |||
| 65 | + | background information on the protocol design and legacy color management. | |||
| 66 | + | It also contains a glossary, learning resources for digital color, tools, | |||
| 67 | + | samples and more. | |||
| 68 | + | ||||
| 69 | + | The terminology used in this protocol is based on common color science and | |||
| 70 | + | color encoding terminology where possible. The glossary in the color-and-hdr | |||
| 71 | + | repository shall be the authority on the definition of terms in this | |||
| 72 | + | protocol. | |||
| 73 | + | ||||
| 74 | + | Warning! The protocol described in this file is currently in the testing | |||
| 75 | + | phase. Backward compatible changes may be added together with the | |||
| 76 | + | corresponding interface version bump. Backward incompatible changes can | |||
| 77 | + | only be done by creating a new major version of the extension. | |||
| 78 | + | </description> | |||
| 79 | + | ||||
| 80 | + | <interface name="wp_color_manager_v1" version="3"> | |||
| 81 | + | <description summary="color manager singleton"> | |||
| 82 | + | A singleton global interface used for getting color management extensions | |||
| 83 | + | for wl_surface and wl_output objects, and for creating client defined | |||
| 84 | + | image description objects. The extension interfaces allow | |||
| 85 | + | getting the image description of outputs and setting the image | |||
| 86 | + | description of surfaces. | |||
| 87 | + | ||||
| 88 | + | Compositors should never remove this global. | |||
| 89 | + | </description> | |||
| 90 | + | ||||
| 91 | + | <request name="destroy" type="destructor"> | |||
| 92 | + | <description summary="destroy the color manager"> | |||
| 93 | + | Destroy the wp_color_manager_v1 object. This does not affect any other | |||
| 94 | + | objects in any way. | |||
| 95 | + | </description> | |||
| 96 | + | </request> | |||
| 97 | + | ||||
| 98 | + | <enum name="error"> | |||
| 99 | + | <entry name="unsupported_feature" value="0" | |||
| 100 | + | summary="request not supported"/> | |||
| 101 | + | <entry name="surface_exists" value="1" | |||
| 102 | + | summary="color management surface exists already"/> | |||
| 103 | + | </enum> | |||
| 104 | + | ||||
| 105 | + | <enum name="render_intent"> | |||
| 106 | + | <description summary="rendering intents"> | |||
| 107 | + | See the ICC.1:2022 specification from the International Color Consortium | |||
| 108 | + | for more details about rendering intents. | |||
| 109 | + | ||||
| 110 | + | The principles of ICC defined rendering intents apply with all types of | |||
| 111 | + | image descriptions, not only those with ICC file profiles. | |||
| 112 | + | ||||
| 113 | + | Compositors must support the perceptual rendering intent. Other | |||
| 114 | + | rendering intents are optional. | |||
| 115 | + | </description> | |||
| 116 | + | ||||
| 117 | + | <entry name="perceptual" value="0" | |||
| 118 | + | summary="perceptual"/> | |||
| 119 | + | <entry name="relative" value="1" | |||
| 120 | + | summary="media-relative colorimetric"/> | |||
| 121 | + | <entry name="saturation" value="2" | |||
| 122 | + | summary="saturation"/> | |||
| 123 | + | <entry name="absolute" value="3" | |||
| 124 | + | summary="ICC-absolute colorimetric"/> | |||
| 125 | + | <entry name="relative_bpc" value="4" | |||
| 126 | + | summary="media-relative colorimetric + black point compensation"/> | |||
| 127 | + | <entry name="absolute_no_adaptation" value="5" since="2"> | |||
| 128 | + | <description summary="ICC-absolute colorimetric without adaptation"> | |||
| 129 | + | This rendering intent is a modified absolute rendering intent that | |||
| 130 | + | assumes the viewer is not adapted to the display white point, so no | |||
| 131 | + | chromatic adaptation between surface and display is done. | |||
| 132 | + | This can be useful for color proofing applications. | |||
| 133 | + | </description> | |||
| 134 | + | </entry> | |||
| 135 | + | </enum> | |||
| 136 | + | ||||
| 137 | + | <enum name="feature"> | |||
| 138 | + | <description summary="compositor supported features"/> | |||
| 139 | + | ||||
| 140 | + | <entry name="icc_v2_v4" value="0" | |||
| 141 | + | summary="create_icc_creator request"/> | |||
| 142 | + | <entry name="parametric" value="1" | |||
| 143 | + | summary="create_parametric_creator request"/> | |||
| 144 | + | <entry name="set_primaries" value="2" | |||
| 145 | + | summary="parametric set_primaries request"/> | |||
| 146 | + | <entry name="set_tf_power" value="3" | |||
| 147 | + | summary="parametric set_tf_power request"/> | |||
| 148 | + | <entry name="set_luminances" value="4" | |||
| 149 | + | summary="parametric set_luminances request"/> | |||
| 150 | + | <entry name="set_mastering_display_primaries" value="5"> | |||
| 151 | + | <description summary="parametric set_mastering_display_primaries request"> | |||
| 152 | + | The compositor supports set_mastering_display_primaries request with a | |||
| 153 | + | target color volume fully contained inside the primary color volume. | |||
| 154 | + | </description> | |||
| 155 | + | </entry> | |||
| 156 | + | <entry name="extended_target_volume" value="6"> | |||
| 157 | + | <description summary="parametric target exceeds primary color volume"> | |||
| 158 | + | The compositor additionally supports target color volumes that | |||
| 159 | + | extend outside of the primary color volume. | |||
| 160 | + | ||||
| 161 | + | This can only be advertised if feature set_mastering_display_primaries | |||
| 162 | + | is supported as well. | |||
| 163 | + | </description> | |||
| 164 | + | </entry> | |||
| 165 | + | <entry name="windows_scrgb" value="7" | |||
| 166 | + | summary="create_windows_scrgb request"/> | |||
| 167 | + | <entry name="windows_bt2100" value="8" | |||
| 168 | + | summary="create_windows_bt2100 request"/> | |||
| 169 | + | </enum> | |||
| 170 | + | ||||
| 171 | + | <enum name="primaries"> | |||
| 172 | + | <description summary="named color primaries"> | |||
| 173 | + | Named color primaries used to encode well-known sets of primaries. | |||
| 174 | + | ||||
| 175 | + | A value of 0 is invalid and will never be present in the list of enums. | |||
| 176 | + | </description> | |||
| 177 | + | ||||
| 178 | + | <entry name="srgb" value="1"> | |||
| 179 | + | <description summary="Color primaries for the sRGB color space as defined by the BT.709 standard"> | |||
| 180 | + | Color primaries as defined by | |||
| 181 | + | - Rec. ITU-R BT.709-6 | |||
| 182 | + | - Rec. ITU-R BT.1361-0 conventional colour gamut system and extended | |||
| 183 | + | colour gamut system (historical) | |||
| 184 | + | - IEC 61966-2-1 sRGB or sYCC | |||
| 185 | + | - IEC 61966-2-4 | |||
| 186 | + | - Society of Motion Picture and Television Engineers (SMPTE) RP 177 | |||
| 187 | + | (1993) Annex B | |||
| 188 | + | </description> | |||
| 189 | + | </entry> | |||
| 190 | + | <entry name="pal_m" value="2"> | |||
| 191 | + | <description summary="Color primaries for PAL-M as defined by the BT.470 standard"> | |||
| 192 | + | Color primaries as defined by | |||
| 193 | + | - Rec. ITU-R BT.470-6 System M (historical) | |||
| 194 | + | - United States National Television System Committee 1953 | |||
| 195 | + | Recommendation for transmission standards for color television | |||
| 196 | + | - United States Federal Communications Commission (2003) Title 47 Code | |||
| 197 | + | of Federal Regulations 73.682 (a)(20) | |||
| 198 | + | </description> | |||
| 199 | + | </entry> | |||
| 200 | + | <entry name="pal" value="3"> | |||
| 201 | + | <description summary="Color primaries for PAL as defined by the BT.601 standard"> | |||
| 202 | + | Color primaries as defined by | |||
| 203 | + | - Rec. ITU-R BT.470-6 System B, G (historical) | |||
| 204 | + | - Rec. ITU-R BT.601-7 625 | |||
| 205 | + | - Rec. ITU-R BT.1358-0 625 (historical) | |||
| 206 | + | - Rec. ITU-R BT.1700-0 625 PAL and 625 SECAM | |||
| 207 | + | </description> | |||
| 208 | + | </entry> | |||
| 209 | + | <entry name="ntsc" value="4"> | |||
| 210 | + | <description summary="Color primaries for NTSC as defined by the BT.601 standard"> | |||
| 211 | + | Color primaries as defined by | |||
| 212 | + | - Rec. ITU-R BT.601-7 525 | |||
| 213 | + | - Rec. ITU-R BT.1358-1 525 or 625 (historical) | |||
| 214 | + | - Rec. ITU-R BT.1700-0 NTSC | |||
| 215 | + | - SMPTE 170M (2004) | |||
| 216 | + | - SMPTE 240M (1999) (historical) | |||
| 217 | + | </description> | |||
| 218 | + | </entry> | |||
| 219 | + | <entry name="generic_film" value="5"> | |||
| 220 | + | <description summary="Generic film with colour filters using Illuminant C"> | |||
| 221 | + | Color primaries as defined by Recommendation ITU-T H.273 | |||
| 222 | + | "Coding-independent code points for video signal type identification" | |||
| 223 | + | for "generic film". | |||
| 224 | + | </description> | |||
| 225 | + | </entry> | |||
| 226 | + | <entry name="bt2020" value="6"> | |||
| 227 | + | <description summary="Color primaries as defined by the BT.2020 and BT.2100 standard"> | |||
| 228 | + | Color primaries as defined by | |||
| 229 | + | - Rec. ITU-R BT.2020-2 | |||
| 230 | + | - Rec. ITU-R BT.2100-0 | |||
| 231 | + | </description> | |||
| 232 | + | </entry> | |||
| 233 | + | <entry name="cie1931_xyz" value="7"> | |||
| 234 | + | <description summary="Color primaries of the full CIE 1931 XYZ color space"> | |||
| 235 | + | Color primaries as defined as the maximum of the CIE 1931 XYZ color | |||
| 236 | + | space by | |||
| 237 | + | - SMPTE ST 428-1 | |||
| 238 | + | - (CIE 1931 XYZ as in ISO 11664-1) | |||
| 239 | + | </description> | |||
| 240 | + | </entry> | |||
| 241 | + | <entry name="dci_p3" value="8"> | |||
| 242 | + | <description summary="Color primaries of the DCI P3 color space as defined by the SMPTE RP 431 standard"> | |||
| 243 | + | Color primaries as defined by Digital Cinema System and published in | |||
| 244 | + | SMPTE RP 431-2 (2011). | |||
| 245 | + | </description> | |||
| 246 | + | </entry> | |||
| 247 | + | <entry name="display_p3" value="9"> | |||
| 248 | + | <description summary="Color primaries of Display P3 variant of the DCI-P3 color space as defined by the SMPTE EG 432 standard"> | |||
| 249 | + | Color primaries as defined by Digital Cinema System and published in | |||
| 250 | + | SMPTE EG 432-1 (2010). | |||
| 251 | + | </description> | |||
| 252 | + | </entry> | |||
| 253 | + | <entry name="adobe_rgb" value="10"> | |||
| 254 | + | <description summary="Color primaries of the Adobe RGB color space as defined by the ISO 12640 standard"> | |||
| 255 | + | Color primaries as defined by Adobe as "Adobe RGB" and later published | |||
| 256 | + | by ISO 12640-4 (2011). | |||
| 257 | + | </description> | |||
| 258 | + | </entry> | |||
| 259 | + | </enum> | |||
| 260 | + | ||||
| 261 | + | <enum name="transfer_function"> | |||
| 262 | + | <description summary="named transfer functions"> | |||
| 263 | + | Named transfer functions used to represent well-known transfer | |||
| 264 | + | characteristics of displays. | |||
| 265 | + | ||||
| 266 | + | A value of 0 is invalid and will never be present in the list of enums. | |||
| 267 | + | ||||
| 268 | + | See appendix.md for the formulae. | |||
| 269 | + | </description> | |||
| 270 | + | ||||
| 271 | + | <entry name="bt1886" value="1"> | |||
| 272 | + | <description summary="BT.1886 display transfer characteristic"> | |||
| 273 | + | Rec. ITU-R BT.1886 is the display transfer characteristic assumed by | |||
| 274 | + | - Rec. ITU-R BT.601-7 525 and 625 | |||
| 275 | + | - Rec. ITU-R BT.709-6 | |||
| 276 | + | - Rec. ITU-R BT.2020-2 | |||
| 277 | + | ||||
| 278 | + | This TF implies these default luminances from Rec. ITU-R BT.2035: | |||
| 279 | + | - primary color volume minimum: 0.01 cd/m² | |||
| 280 | + | - primary color volume maximum: 100 cd/m² | |||
| 281 | + | - reference white: 100 cd/m² | |||
| 282 | + | </description> | |||
| 283 | + | </entry> | |||
| 284 | + | <entry name="gamma22" value="2"> | |||
| 285 | + | <description summary="Assumed display gamma 2.2 transfer function"> | |||
| 286 | + | Transfer characteristics as defined by | |||
| 287 | + | - Rec. ITU-R BT.470-6 System M (historical) | |||
| 288 | + | - United States National Television System Committee 1953 | |||
| 289 | + | Recommendation for transmission standards for color television | |||
| 290 | + | - United States Federal Communications Commission (2003) Title 47 Code | |||
| 291 | + | of Federal Regulations 73.682 (a) (20) | |||
| 292 | + | - Rec. ITU-R BT.1700-0 625 PAL and 625 SECAM | |||
| 293 | + | - IEC 61966-2-1 (reference display) | |||
| 294 | + | </description> | |||
| 295 | + | </entry> | |||
| 296 | + | <entry name="gamma28" value="3"> | |||
| 297 | + | <description summary="Assumed display gamma 2.8 transfer function"> | |||
| 298 | + | Transfer characteristics as defined by | |||
| 299 | + | - Rec. ITU-R BT.470-6 System B, G (historical) | |||
| 300 | + | </description> | |||
| 301 | + | </entry> | |||
| 302 | + | <entry name="st240" value="4"> | |||
| 303 | + | <description summary="SMPTE ST 240 transfer function"> | |||
| 304 | + | Transfer characteristics as defined by | |||
| 305 | + | - SMPTE ST 240 (1999) | |||
| 306 | + | </description> | |||
| 307 | + | </entry> | |||
| 308 | + | <entry name="ext_linear" value="5"> | |||
| 309 | + | <description summary="extended linear transfer function"> | |||
| 310 | + | Linear transfer function defined over all real numbers. | |||
| 311 | + | Normalised electrical values are equal the normalised optical values. | |||
| 312 | + | </description> | |||
| 313 | + | </entry> | |||
| 314 | + | <entry name="log_100" value="6"> | |||
| 315 | + | <description summary="logarithmic 100:1 transfer function"> | |||
| 316 | + | Logarithmic transfer characteristic (100:1 range). | |||
| 317 | + | </description> | |||
| 318 | + | </entry> | |||
| 319 | + | <entry name="log_316" value="7"> | |||
| 320 | + | <description summary="logarithmic (100*Sqrt(10) : 1) transfer function"> | |||
| 321 | + | Logarithmic transfer characteristic (100 * Sqrt(10) : 1 range). | |||
| 322 | + | </description> | |||
| 323 | + | </entry> | |||
| 324 | + | <entry name="xvycc" value="8"> | |||
| 325 | + | <description summary="IEC 61966-2-4 transfer function"> | |||
| 326 | + | Transfer characteristics as defined by | |||
| 327 | + | - IEC 61966-2-4 | |||
| 328 | + | </description> | |||
| 329 | + | </entry> | |||
| 330 | + | <entry name="srgb" value="9" deprecated-since="2"> | |||
| 331 | + | <description summary="Deprecated (ambiguous sRGB transfer function)"> | |||
| 332 | + | Transfer characteristics as defined by | |||
| 333 | + | - IEC 61966-2-1 sRGB | |||
| 334 | + | ||||
| 335 | + | As a rule of thumb, use gamma22 for video, motion picture and | |||
| 336 | + | computer graphics, or compound_power_2_4 for ICC calibrated print | |||
| 337 | + | workflows. | |||
| 338 | + | </description> | |||
| 339 | + | </entry> | |||
| 340 | + | <entry name="ext_srgb" value="10" deprecated-since="2"> | |||
| 341 | + | <description summary="Deprecated (Extended sRGB piece-wise transfer function)"> | |||
| 342 | + | Transfer characteristics as defined by | |||
| 343 | + | - IEC 61966-2-1 sYCC | |||
| 344 | + | </description> | |||
| 345 | + | </entry> | |||
| 346 | + | <entry name="st2084_pq" value="11"> | |||
| 347 | + | <description summary="perceptual quantizer transfer function"> | |||
| 348 | + | Transfer characteristics as defined by | |||
| 349 | + | - SMPTE ST 2084 (2014) for 10-, 12-, 14- and 16-bit systems | |||
| 350 | + | - Rec. ITU-R BT.2100-2 perceptual quantization (PQ) system | |||
| 351 | + | ||||
| 352 | + | This TF implies these default luminances | |||
| 353 | + | - primary color volume minimum: 0.005 cd/m² | |||
| 354 | + | - primary color volume maximum: 10000 cd/m² | |||
| 355 | + | - reference white: 203 cd/m² | |||
| 356 | + | ||||
| 357 | + | The difference between the primary color volume minimum and maximum | |||
| 358 | + | must be approximately 10000 cd/m² as that is the swing of the EOTF | |||
| 359 | + | defined by ST 2084 and BT.2100. The default value for the | |||
| 360 | + | reference white is a protocol addition: it is suggested by | |||
| 361 | + | Report ITU-R BT.2408-7 and is not part of ST 2084 or BT.2100. | |||
| 362 | + | </description> | |||
| 363 | + | </entry> | |||
| 364 | + | <entry name="st428" value="12"> | |||
| 365 | + | <description summary="SMPTE ST 428 transfer function"> | |||
| 366 | + | Transfer characteristics as defined by | |||
| 367 | + | - SMPTE ST 428-1 (2019) | |||
| 368 | + | </description> | |||
| 369 | + | </entry> | |||
| 370 | + | <entry name="hlg" value="13"> | |||
| 371 | + | <description summary="hybrid log-gamma transfer function"> | |||
| 372 | + | Transfer characteristics as defined by | |||
| 373 | + | - ARIB STD-B67 (2015) | |||
| 374 | + | - Rec. ITU-R BT.2100-2 hybrid log-gamma (HLG) system | |||
| 375 | + | ||||
| 376 | + | This TF implies these default luminances | |||
| 377 | + | - primary color volume minimum: 0.005 cd/m² | |||
| 378 | + | - primary color volume maximum: 1000 cd/m² | |||
| 379 | + | - reference white: 203 cd/m² | |||
| 380 | + | ||||
| 381 | + | HLG is a relative display-referred signal with a specified | |||
| 382 | + | non-linear mapping to the display peak luminance (the HLG OOTF). | |||
| 383 | + | All absolute luminance values used here for HLG assume a 1000 cd/m² | |||
| 384 | + | peak display. | |||
| 385 | + | ||||
| 386 | + | The default value for the reference white is a protocol addition: | |||
| 387 | + | it is suggested by Report ITU-R BT.2408-7 and is not part of | |||
| 388 | + | ARIB STD-B67 or BT.2100. | |||
| 389 | + | </description> | |||
| 390 | + | </entry> | |||
| 391 | + | <entry name="compound_power_2_4" value="14" since="2"> | |||
| 392 | + | <description summary="IEC 61966-2-1 encoding function"> | |||
| 393 | + | Encoding characteristics as defined by IEC 61966-2-1, for displays | |||
| 394 | + | that invert the encoding function. | |||
| 395 | + | </description> | |||
| 396 | + | </entry> | |||
| 397 | + | </enum> | |||
| 398 | + | ||||
| 399 | + | <request name="get_output"> | |||
| 400 | + | <description summary="create a color management interface for a wl_output"> | |||
| 401 | + | This creates a new wp_color_management_output_v1 object for the | |||
| 402 | + | given wl_output. | |||
| 403 | + | ||||
| 404 | + | See the wp_color_management_output_v1 interface for more details. | |||
| 405 | + | </description> | |||
| 406 | + | ||||
| 407 | + | <arg name="id" type="new_id" interface="wp_color_management_output_v1"/> | |||
| 408 | + | <arg name="output" type="object" interface="wl_output"/> | |||
| 409 | + | </request> | |||
| 410 | + | ||||
| 411 | + | <request name="get_surface"> | |||
| 412 | + | <description summary="create a color management interface for a wl_surface"> | |||
| 413 | + | If a wp_color_management_surface_v1 object already exists for the given | |||
| 414 | + | wl_surface, the protocol error surface_exists is raised. | |||
| 415 | + | ||||
| 416 | + | This creates a new color wp_color_management_surface_v1 object for the | |||
| 417 | + | given wl_surface. | |||
| 418 | + | ||||
| 419 | + | See the wp_color_management_surface_v1 interface for more details. | |||
| 420 | + | </description> | |||
| 421 | + | ||||
| 422 | + | <arg name="id" type="new_id" interface="wp_color_management_surface_v1"/> | |||
| 423 | + | <arg name="surface" type="object" interface="wl_surface"/> | |||
| 424 | + | </request> | |||
| 425 | + | ||||
| 426 | + | <request name="get_surface_feedback"> | |||
| 427 | + | <description summary="create a color management feedback interface"> | |||
| 428 | + | This creates a new color wp_color_management_surface_feedback_v1 object | |||
| 429 | + | for the given wl_surface. | |||
| 430 | + | ||||
| 431 | + | See the wp_color_management_surface_feedback_v1 interface for more | |||
| 432 | + | details. | |||
| 433 | + | </description> | |||
| 434 | + | ||||
| 435 | + | <arg name="id" type="new_id" | |||
| 436 | + | interface="wp_color_management_surface_feedback_v1"/> | |||
| 437 | + | <arg name="surface" type="object" interface="wl_surface"/> | |||
| 438 | + | </request> | |||
| 439 | + | ||||
| 440 | + | <request name="create_icc_creator"> | |||
| 441 | + | <description summary="make a new ICC-based image description creator object"> | |||
| 442 | + | Makes a new ICC-based image description creator object with all | |||
| 443 | + | properties initially unset. The client can then use the object's | |||
| 444 | + | interface to define all the required properties for an image description | |||
| 445 | + | and finally create a wp_image_description_v1 object. | |||
| 446 | + | ||||
| 447 | + | This request can be used when the compositor advertises | |||
| 448 | + | wp_color_manager_v1.feature.icc_v2_v4. | |||
| 449 | + | Otherwise this request raises the protocol error unsupported_feature. | |||
| 450 | + | </description> | |||
| 451 | + | ||||
| 452 | + | <arg name="obj" | |||
| 453 | + | type="new_id" interface="wp_image_description_creator_icc_v1" | |||
| 454 | + | summary="the new creator object"/> | |||
| 455 | + | </request> | |||
| 456 | + | ||||
| 457 | + | <request name="create_parametric_creator"> | |||
| 458 | + | <description summary="make a new parametric image description creator object"> | |||
| 459 | + | Makes a new parametric image description creator object with all | |||
| 460 | + | properties initially unset. The client can then use the object's | |||
| 461 | + | interface to define all the required properties for an image description | |||
| 462 | + | and finally create a wp_image_description_v1 object. | |||
| 463 | + | ||||
| 464 | + | This request can be used when the compositor advertises | |||
| 465 | + | wp_color_manager_v1.feature.parametric. | |||
| 466 | + | Otherwise this request raises the protocol error unsupported_feature. | |||
| 467 | + | </description> | |||
| 468 | + | ||||
| 469 | + | <arg name="obj" | |||
| 470 | + | type="new_id" interface="wp_image_description_creator_params_v1" | |||
| 471 | + | summary="the new creator object"/> | |||
| 472 | + | </request> | |||
| 473 | + | ||||
| 474 | + | <request name="create_windows_scrgb"> | |||
| 475 | + | <description summary="create Windows-scRGB image description object"> | |||
| 476 | + | This creates a pre-defined image description for the so-called | |||
| 477 | + | Windows-scRGB stimulus encoding. This comes from the Windows 10 handling | |||
| 478 | + | of its own definition of an scRGB color space for an HDR screen | |||
| 479 | + | driven in BT.2100/PQ signalling mode. | |||
| 480 | + | ||||
| 481 | + | Windows-scRGB uses sRGB (BT.709) color primaries and white point. | |||
| 482 | + | The transfer characteristic is extended linear. | |||
| 483 | + | ||||
| 484 | + | The nominal color channel value range is extended, meaning it includes | |||
| 485 | + | negative and greater than 1.0 values. Negative values are used to | |||
| 486 | + | escape the sRGB color gamut boundaries. To make use of the extended | |||
| 487 | + | range, the client needs to use a pixel format that can represent those | |||
| 488 | + | values, e.g. floating-point 16 bits per channel. | |||
| 489 | + | ||||
| 490 | + | Nominal color value R=G=B=0.0 corresponds to BT.2100/PQ system | |||
| 491 | + | 0 cd/m², and R=G=B=1.0 corresponds to BT.2100/PQ system 80 cd/m². | |||
| 492 | + | The maximum is R=G=B=125.0 corresponding to 10k cd/m². | |||
| 493 | + | ||||
| 494 | + | Windows-scRGB is displayed by Windows 10 by converting it to | |||
| 495 | + | BT.2100/PQ, maintaining the CIE 1931 chromaticity and mapping the | |||
| 496 | + | luminance as above. No adjustment is made to the signal to account | |||
| 497 | + | for the viewing conditions. | |||
| 498 | + | ||||
| 499 | + | The reference white level of Windows-scRGB is unknown. If a | |||
| 500 | + | reference white level must be assumed for compositor processing, it | |||
| 501 | + | should be R=G=B=2.5375 corresponding to 203 cd/m² of Report ITU-R | |||
| 502 | + | BT.2408-7. | |||
| 503 | + | ||||
| 504 | + | The target color volume of Windows-scRGB is unknown. The color gamut | |||
| 505 | + | may be anything between sRGB and BT.2100. | |||
| 506 | + | ||||
| 507 | + | Note: EGL_EXT_gl_colorspace_scrgb_linear definition differs from | |||
| 508 | + | Windows-scRGB by using R=G=B=1.0 as the reference white level, while | |||
| 509 | + | Windows-scRGB reference white level is unknown or varies. However, | |||
| 510 | + | it seems probable that Windows implements both | |||
| 511 | + | EGL_EXT_gl_colorspace_scrgb_linear and Vulkan | |||
| 512 | + | VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT as Windows-scRGB. | |||
| 513 | + | ||||
| 514 | + | This request can be used when the compositor advertises | |||
| 515 | + | wp_color_manager_v1.feature.windows_scrgb. | |||
| 516 | + | Otherwise this request raises the protocol error unsupported_feature. | |||
| 517 | + | ||||
| 518 | + | The resulting image description object does not allow get_information | |||
| 519 | + | request. The wp_image_description_v1.ready event shall be sent. | |||
| 520 | + | </description> | |||
| 521 | + | ||||
| 522 | + | <arg name="image_description" | |||
| 523 | + | type="new_id" interface="wp_image_description_v1"/> | |||
| 524 | + | </request> | |||
| 525 | + | ||||
| 526 | + | <event name="supported_intent"> | |||
| 527 | + | <description summary="supported rendering intent"> | |||
| 528 | + | When this object is created, it shall immediately send this event once | |||
| 529 | + | for each rendering intent the compositor supports. | |||
| 530 | + | ||||
| 531 | + | A compositor must not advertise intents that are deprecated in the | |||
| 532 | + | bound version of the interface. | |||
| 533 | + | </description> | |||
| 534 | + | ||||
| 535 | + | <arg name="render_intent" type="uint" enum="render_intent" | |||
| 536 | + | summary="rendering intent"/> | |||
| 537 | + | </event> | |||
| 538 | + | ||||
| 539 | + | <event name="supported_feature"> | |||
| 540 | + | <description summary="supported features"> | |||
| 541 | + | When this object is created, it shall immediately send this event once | |||
| 542 | + | for each compositor supported feature listed in the enumeration. | |||
| 543 | + | ||||
| 544 | + | A compositor must not advertise features that are deprecated in the | |||
| 545 | + | bound version of the interface. | |||
| 546 | + | </description> | |||
| 547 | + | ||||
| 548 | + | <arg name="feature" type="uint" enum="feature" | |||
| 549 | + | summary="supported feature"/> | |||
| 550 | + | </event> | |||
| 551 | + | ||||
| 552 | + | <event name="supported_tf_named"> | |||
| 553 | + | <description summary="supported named transfer characteristic"> | |||
| 554 | + | When this object is created, it shall immediately send this event once | |||
| 555 | + | for each named transfer function the compositor supports with the | |||
| 556 | + | parametric image description creator. | |||
| 557 | + | ||||
| 558 | + | A compositor must not advertise transfer functions that are deprecated | |||
| 559 | + | in the bound version of the interface. | |||
| 560 | + | </description> | |||
| 561 | + | ||||
| 562 | + | <arg name="tf" type="uint" enum="transfer_function" | |||
| 563 | + | summary="Named transfer function"/> | |||
| 564 | + | </event> | |||
| 565 | + | ||||
| 566 | + | <event name="supported_primaries_named"> | |||
| 567 | + | <description summary="supported named primaries"> | |||
| 568 | + | When this object is created, it shall immediately send this event once | |||
| 569 | + | for each named set of primaries the compositor supports with the | |||
| 570 | + | parametric image description creator. | |||
| 571 | + | ||||
| 572 | + | A compositor must not advertise names that are deprecated in the | |||
| 573 | + | bound version of the interface. | |||
| 574 | + | </description> | |||
| 575 | + | ||||
| 576 | + | <arg name="primaries" type="uint" enum="primaries" | |||
| 577 | + | summary="Named color primaries"/> | |||
| 578 | + | </event> | |||
| 579 | + | ||||
| 580 | + | <event name="done"> | |||
| 581 | + | <description summary="all features have been sent"> | |||
| 582 | + | This event is sent when all supported rendering intents, features, | |||
| 583 | + | transfer functions and named primaries have been sent. | |||
| 584 | + | </description> | |||
| 585 | + | </event> | |||
| 586 | + | ||||
| 587 | + | <request name="get_image_description" since="2"> | |||
| 588 | + | <description summary="create an image description from a reference"> | |||
| 589 | + | This request retrieves the image description backing a reference. | |||
| 590 | + | ||||
| 591 | + | The get_information request can be used if and only if the request that | |||
| 592 | + | creates the reference allows it. | |||
| 593 | + | </description> | |||
| 594 | + | ||||
| 595 | + | <arg name="image_description" | |||
| 596 | + | type="new_id" interface="wp_image_description_v1"/> | |||
| 597 | + | <arg name="reference" | |||
| 598 | + | type="object" interface="wp_image_description_reference_v1"/> | |||
| 599 | + | </request> | |||
| 600 | + | ||||
| 601 | + | <request name="create_windows_bt2100" since="3"> | |||
| 602 | + | <description summary="create Windows-BT.2100 image description object"> | |||
| 603 | + | This creates a pre-defined image description for the so-called | |||
| 604 | + | Windows-BT.2100 stimulus encoding. This comes from the Windows 10 | |||
| 605 | + | handling of its own definition of a BT.2100 color space for an HDR | |||
| 606 | + | screen driven in BT.2100/PQ signalling mode. | |||
| 607 | + | ||||
| 608 | + | Windows-BT.2100 uses BT.2020 color primaries and white point. | |||
| 609 | + | The transfer characteristic is st2084_pq. | |||
| 610 | + | ||||
| 611 | + | Windows-BT.2100 is generally displayed by Windows 10 without any | |||
| 612 | + | adjustments to the signal to account for viewing conditions. | |||
| 613 | + | ||||
| 614 | + | The reference white level of Windows-BT.2100 is unknown. If a | |||
| 615 | + | reference white level must be assumed for compositor processing, it | |||
| 616 | + | should be 203 cd/m² of Report ITU-R BT.2408-7. | |||
| 617 | + | ||||
| 618 | + | The target color volume of Windows-BT.2100 is unknown. The color gamut | |||
| 619 | + | may be anything up to BT.2100. | |||
| 620 | + | ||||
| 621 | + | This request can be used when the compositor advertises | |||
| 622 | + | wp_color_manager_v1.feature.windows_bt2100. | |||
| 623 | + | Otherwise this request raises the protocol error unsupported_feature. | |||
| 624 | + | ||||
| 625 | + | The resulting image description object does not allow get_information | |||
| 626 | + | request. The wp_image_description_v1.ready event shall be sent. | |||
| 627 | + | </description> | |||
| 628 | + | ||||
| 629 | + | <arg name="image_description" | |||
| 630 | + | type="new_id" interface="wp_image_description_v1"/> | |||
| 631 | + | </request> | |||
| 632 | + | </interface> | |||
| 633 | + | ||||
| 634 | + | <interface name="wp_color_management_output_v1" version="3"> | |||
| 635 | + | <description summary="output color properties"> | |||
| 636 | + | A wp_color_management_output_v1 describes the color properties of an | |||
| 637 | + | output. | |||
| 638 | + | ||||
| 639 | + | The wp_color_management_output_v1 is associated with the wl_output global | |||
| 640 | + | underlying the wl_output object. Therefore the client destroying the | |||
| 641 | + | wl_output object has no impact, but the compositor removing the output | |||
| 642 | + | global makes the wp_color_management_output_v1 object inert. | |||
| 643 | + | </description> | |||
| 644 | + | ||||
| 645 | + | <request name="destroy" type="destructor"> | |||
| 646 | + | <description summary="destroy the color management output"> | |||
| 647 | + | Destroy the color wp_color_management_output_v1 object. This does not | |||
| 648 | + | affect any remaining protocol objects. | |||
| 649 | + | </description> | |||
| 650 | + | </request> | |||
| 651 | + | ||||
| 652 | + | <event name="image_description_changed"> | |||
| 653 | + | <description summary="image description changed"> | |||
| 654 | + | This event is sent whenever the image description of the output changed, | |||
| 655 | + | followed by one wl_output.done event common to output events across all | |||
| 656 | + | extensions. | |||
| 657 | + | ||||
| 658 | + | If the client wants to use the updated image description, it needs to do | |||
| 659 | + | get_image_description again, because image description objects are | |||
| 660 | + | immutable. | |||
| 661 | + | </description> | |||
| 662 | + | </event> | |||
| 663 | + | ||||
| 664 | + | <request name="get_image_description"> | |||
| 665 | + | <description summary="get the image description of the output"> | |||
| 666 | + | This creates a new wp_image_description_v1 object for the current image | |||
| 667 | + | description of the output. There always is exactly one image description | |||
| 668 | + | active for an output so the client should destroy the image description | |||
| 669 | + | created by earlier invocations of this request. This request is usually | |||
| 670 | + | sent as a reaction to the image_description_changed event or when | |||
| 671 | + | creating a wp_color_management_output_v1 object. | |||
| 672 | + | ||||
| 673 | + | The image description of an output represents the color encoding the | |||
| 674 | + | output expects. There might be performance and power advantages, as well | |||
| 675 | + | as improved color reproduction, if a content update matches the image | |||
| 676 | + | description of the output it is being shown on. If a content update is | |||
| 677 | + | shown on any other output than the one it matches the image description | |||
| 678 | + | of, then the color reproduction on those outputs might be considerably | |||
| 679 | + | worse. | |||
| 680 | + | ||||
| 681 | + | The created wp_image_description_v1 object preserves the image | |||
| 682 | + | description of the output from the time the object was created. | |||
| 683 | + | ||||
| 684 | + | The resulting image description object allows get_information request. | |||
| 685 | + | ||||
| 686 | + | If this protocol object is inert, the resulting image description object | |||
| 687 | + | shall immediately deliver the wp_image_description_v1.failed event with | |||
| 688 | + | the no_output cause. | |||
| 689 | + | ||||
| 690 | + | If the interface version is inadequate for the output's image | |||
| 691 | + | description, meaning that the client does not support all the events | |||
| 692 | + | needed to deliver the crucial information, the resulting image | |||
| 693 | + | description object shall immediately deliver the | |||
| 694 | + | wp_image_description_v1.failed event with the low_version cause. | |||
| 695 | + | ||||
| 696 | + | Otherwise the object shall immediately deliver the ready event. | |||
| 697 | + | </description> | |||
| 698 | + | ||||
| 699 | + | <arg name="image_description" | |||
| 700 | + | type="new_id" interface="wp_image_description_v1"/> | |||
| 701 | + | </request> | |||
| 702 | + | </interface> | |||
| 703 | + | ||||
| 704 | + | <interface name="wp_color_management_surface_v1" version="3"> | |||
| 705 | + | <description summary="color management extension to a surface"> | |||
| 706 | + | A wp_color_management_surface_v1 allows the client to set the color | |||
| 707 | + | space and HDR properties of a surface. | |||
| 708 | + | ||||
| 709 | + | If the wl_surface associated with the wp_color_management_surface_v1 is | |||
| 710 | + | destroyed, the wp_color_management_surface_v1 object becomes inert. | |||
| 711 | + | </description> | |||
| 712 | + | ||||
| 713 | + | <request name="destroy" type="destructor"> | |||
| 714 | + | <description summary="destroy the color management interface for a surface"> | |||
| 715 | + | Destroy the wp_color_management_surface_v1 object and do the same as | |||
| 716 | + | unset_image_description. | |||
| 717 | + | </description> | |||
| 718 | + | </request> | |||
| 719 | + | ||||
| 720 | + | <enum name="error"> | |||
| 721 | + | <description summary="protocol errors"/> | |||
| 722 | + | <entry name="render_intent" value="0" | |||
| 723 | + | summary="unsupported rendering intent"/> | |||
| 724 | + | <entry name="image_description" value="1" | |||
| 725 | + | summary="invalid image description"/> | |||
| 726 | + | <entry name="inert" value="2" | |||
| 727 | + | summary="forbidden request on inert object"/> | |||
| 728 | + | </enum> | |||
| 729 | + | ||||
| 730 | + | <request name="set_image_description"> | |||
| 731 | + | <description summary="set the surface image description"> | |||
| 732 | + | If this protocol object is inert, the protocol error inert is raised. | |||
| 733 | + | ||||
| 734 | + | Set the image description of the underlying surface. The image | |||
| 735 | + | description and rendering intent are double-buffered state, see | |||
| 736 | + | wl_surface.commit. | |||
| 737 | + | ||||
| 738 | + | It is the client's responsibility to understand the image description | |||
| 739 | + | it sets on a surface, and to provide content that matches that image | |||
| 740 | + | description. Compositors might convert images to match their own or any | |||
| 741 | + | other image descriptions. | |||
| 742 | + | ||||
| 743 | + | Image descriptions which are not ready (see wp_image_description_v1) | |||
| 744 | + | are forbidden in this request, and in such case the protocol error | |||
| 745 | + | image_description is raised. | |||
| 746 | + | ||||
| 747 | + | All image descriptions which are ready (see wp_image_description_v1) | |||
| 748 | + | are allowed and must always be accepted by the compositor. | |||
| 749 | + | ||||
| 750 | + | When an image description is set on a surface, it establishes an | |||
| 751 | + | explicit link between surface pixel values and surface colorimetry. | |||
| 752 | + | This link may be undefined for some pixel values, see the image | |||
| 753 | + | description creator interfaces for the conditions. Non-finite | |||
| 754 | + | floating-point values (NaN, Inf) always have an undefined colorimetry. | |||
| 755 | + | ||||
| 756 | + | A rendering intent provides the client's preference on how surface | |||
| 757 | + | colorimetry should be mapped to each output. The render_intent value | |||
| 758 | + | must be one advertised by the compositor with | |||
| 759 | + | wp_color_manager_v1.render_intent event, otherwise the protocol error | |||
| 760 | + | render_intent is raised. | |||
| 761 | + | ||||
| 762 | + | By default, a surface does not have an associated image description | |||
| 763 | + | nor a rendering intent. The handling of color on such surfaces is | |||
| 764 | + | compositor implementation defined. Compositors should handle such | |||
| 765 | + | surfaces as sRGB, but may handle them differently if they have specific | |||
| 766 | + | requirements. | |||
| 767 | + | ||||
| 768 | + | Setting the image description has copy semantics; after this request, | |||
| 769 | + | the image description can be immediately destroyed without affecting | |||
| 770 | + | the pending state of the surface. | |||
| 771 | + | </description> | |||
| 772 | + | ||||
| 773 | + | <arg name="image_description" | |||
| 774 | + | type="object" interface="wp_image_description_v1"/> | |||
| 775 | + | <arg name="render_intent" | |||
| 776 | + | type="uint" enum="wp_color_manager_v1.render_intent" | |||
| 777 | + | summary="rendering intent"/> | |||
| 778 | + | </request> | |||
| 779 | + | ||||
| 780 | + | <request name="unset_image_description"> | |||
| 781 | + | <description summary="remove the surface image description"> | |||
| 782 | + | If this protocol object is inert, the protocol error inert is raised. | |||
| 783 | + | ||||
| 784 | + | This request removes any image description from the surface. See | |||
| 785 | + | set_image_description for how a compositor handles a surface without | |||
| 786 | + | an image description. This is double-buffered state, see | |||
| 787 | + | wl_surface.commit. | |||
| 788 | + | </description> | |||
| 789 | + | </request> | |||
| 790 | + | </interface> | |||
| 791 | + | ||||
| 792 | + | <interface name="wp_color_management_surface_feedback_v1" version="3"> | |||
| 793 | + | <description summary="color management extension to a surface"> | |||
| 794 | + | A wp_color_management_surface_feedback_v1 allows the client to get the | |||
| 795 | + | preferred image description of a surface. | |||
| 796 | + | ||||
| 797 | + | If the wl_surface associated with this object is destroyed, the | |||
| 798 | + | wp_color_management_surface_feedback_v1 object becomes inert. | |||
| 799 | + | </description> | |||
| 800 | + | ||||
| 801 | + | <request name="destroy" type="destructor"> | |||
| 802 | + | <description summary="destroy the color management interface for a surface"> | |||
| 803 | + | Destroy the wp_color_management_surface_feedback_v1 object. | |||
| 804 | + | </description> | |||
| 805 | + | </request> | |||
| 806 | + | ||||
| 807 | + | <enum name="error"> | |||
| 808 | + | <description summary="protocol errors"/> | |||
| 809 | + | <entry name="inert" value="0" | |||
| 810 | + | summary="forbidden request on inert object"/> | |||
| 811 | + | <entry name="unsupported_feature" value="1" | |||
| 812 | + | summary="attempted to use an unsupported feature"/> | |||
| 813 | + | </enum> | |||
| 814 | + | ||||
| 815 | + | <event name="preferred_changed" deprecated-since="2"> | |||
| 816 | + | <description summary="the preferred image description changed (32-bit)"> | |||
| 817 | + | Starting from interface version 2, 'preferred_changed2' is sent instead | |||
| 818 | + | of this event. See the 'preferred_changed2' event for the definition. | |||
| 819 | + | </description> | |||
| 820 | + | ||||
| 821 | + | <arg name="identity" type="uint" | |||
| 822 | + | summary="the 32-bit image description id number"/> | |||
| 823 | + | </event> | |||
| 824 | + | ||||
| 825 | + | <request name="get_preferred"> | |||
| 826 | + | <description summary="get the preferred image description"> | |||
| 827 | + | If this protocol object is inert, the protocol error inert is raised. | |||
| 828 | + | ||||
| 829 | + | The preferred image description represents the compositor's preferred | |||
| 830 | + | color encoding for this wl_surface at the current time. There might be | |||
| 831 | + | performance and power advantages, as well as improved color | |||
| 832 | + | reproduction, if the image description of a content update matches the | |||
| 833 | + | preferred image description. | |||
| 834 | + | ||||
| 835 | + | This creates a new wp_image_description_v1 object for the currently | |||
| 836 | + | preferred image description for the wl_surface. The client should | |||
| 837 | + | stop using and destroy the image descriptions created by earlier | |||
| 838 | + | invocations of this request for the associated wl_surface. | |||
| 839 | + | This request is usually sent as a reaction to the preferred_changed | |||
| 840 | + | event or when creating a wp_color_management_surface_feedback_v1 object | |||
| 841 | + | if the client is capable of adapting to image descriptions. | |||
| 842 | + | ||||
| 843 | + | The created wp_image_description_v1 object preserves the preferred image | |||
| 844 | + | description of the wl_surface from the time the object was created. | |||
| 845 | + | ||||
| 846 | + | The resulting image description object allows get_information request. | |||
| 847 | + | ||||
| 848 | + | If the image description is parametric, the client should set it on its | |||
| 849 | + | wl_surface only if the image description is an exact match with the | |||
| 850 | + | client content. Particularly if everything else matches, but the target | |||
| 851 | + | color volume is greater than what the client needs, the client should | |||
| 852 | + | create its own parameric image description with its exact parameters. | |||
| 853 | + | ||||
| 854 | + | If the interface version is inadequate for the preferred image | |||
| 855 | + | description, meaning that the client does not support all the | |||
| 856 | + | events needed to deliver the crucial information, the resulting image | |||
| 857 | + | description object shall immediately deliver the | |||
| 858 | + | wp_image_description_v1.failed event with the low_version cause, | |||
| 859 | + | otherwise the object shall immediately deliver the ready event. | |||
| 860 | + | </description> | |||
| 861 | + | ||||
| 862 | + | <arg name="image_description" | |||
| 863 | + | type="new_id" interface="wp_image_description_v1"/> | |||
| 864 | + | </request> | |||
| 865 | + | ||||
| 866 | + | <request name="get_preferred_parametric"> | |||
| 867 | + | <description summary="get the preferred image description"> | |||
| 868 | + | The same description as for get_preferred applies, except the returned | |||
| 869 | + | image description is guaranteed to be parametric. This is meant for | |||
| 870 | + | clients that can only deal with parametric image descriptions. | |||
| 871 | + | ||||
| 872 | + | If the compositor doesn't support parametric image descriptions, the | |||
| 873 | + | unsupported_feature error is emitted. | |||
| 874 | + | </description> | |||
| 875 | + | ||||
| 876 | + | <arg name="image_description" | |||
| 877 | + | type="new_id" interface="wp_image_description_v1"/> | |||
| 878 | + | </request> | |||
| 879 | + | ||||
| 880 | + | <!-- Version 2 additions --> | |||
| 881 | + | ||||
| 882 | + | <event name="preferred_changed2" since="2"> | |||
| 883 | + | <description summary="the preferred image description changed"> | |||
| 884 | + | The preferred image description is the one which likely has the most | |||
| 885 | + | performance and/or quality benefits for the compositor if used by the | |||
| 886 | + | client for its wl_surface contents. This event is sent whenever the | |||
| 887 | + | compositor changes the wl_surface's preferred image description. | |||
| 888 | + | ||||
| 889 | + | This event sends the identity of the new preferred state as the argument, | |||
| 890 | + | so clients who are aware of the image description already can reuse it. | |||
| 891 | + | Otherwise, if the client client wants to know what the preferred image | |||
| 892 | + | description is, it shall use the get_preferred request. | |||
| 893 | + | ||||
| 894 | + | The preferred image description is not automatically used for anything. | |||
| 895 | + | It is only a hint, and clients may set any valid image description with | |||
| 896 | + | set_image_description, but there might be performance and color accuracy | |||
| 897 | + | improvements by providing the wl_surface contents in the preferred | |||
| 898 | + | image description. Therefore clients that can, should render according | |||
| 899 | + | to the preferred image description | |||
| 900 | + | </description> | |||
| 901 | + | ||||
| 902 | + | <arg name="identity_hi" type="uint" | |||
| 903 | + | summary="high 32 bits of the 64-bit image description id number"/> | |||
| 904 | + | <arg name="identity_lo" type="uint" | |||
| 905 | + | summary="low 32 bits of the 64-bit image description id number"/> | |||
| 906 | + | </event> | |||
| 907 | + | ||||
| 908 | + | </interface> | |||
| 909 | + | ||||
| 910 | + | <interface name="wp_image_description_creator_icc_v1" version="3"> | |||
| 911 | + | <description summary="holder of image description ICC information"> | |||
| 912 | + | This type of object is used for collecting all the information required | |||
| 913 | + | to create a wp_image_description_v1 object from an ICC file. A complete | |||
| 914 | + | set of required parameters consists of these properties: | |||
| 915 | + | - ICC file | |||
| 916 | + | ||||
| 917 | + | Each required property must be set exactly once if the client is to create | |||
| 918 | + | an image description. The set requests verify that a property was not | |||
| 919 | + | already set. The create request verifies that all required properties are | |||
| 920 | + | set. There may be several alternative requests for setting each property, | |||
| 921 | + | and in that case the client must choose one of them. | |||
| 922 | + | ||||
| 923 | + | Once all properties have been set, the create request must be used to | |||
| 924 | + | create the image description object, destroying the creator in the | |||
| 925 | + | process. | |||
| 926 | + | ||||
| 927 | + | The link between a pixel value (a device value in ICC) and its respective | |||
| 928 | + | colorimetry is defined by the details of the particular ICC profile. | |||
| 929 | + | Those details also determine when colorimetry becomes undefined. | |||
| 930 | + | </description> | |||
| 931 | + | ||||
| 932 | + | <enum name="error"> | |||
| 933 | + | <description summary="protocol errors"/> | |||
| 934 | + | ||||
| 935 | + | <entry name="incomplete_set" value="0" | |||
| 936 | + | summary="incomplete parameter set"/> | |||
| 937 | + | <entry name="already_set" value="1" | |||
| 938 | + | summary="property already set"/> | |||
| 939 | + | <entry name="bad_fd" value="2" | |||
| 940 | + | summary="fd not seekable and readable"/> | |||
| 941 | + | <entry name="bad_size" value="3" | |||
| 942 | + | summary="no or too much data"/> | |||
| 943 | + | <entry name="out_of_file" value="4" | |||
| 944 | + | summary="offset + length exceeds file size"/> | |||
| 945 | + | </enum> | |||
| 946 | + | ||||
| 947 | + | <request name="create" type="destructor"> | |||
| 948 | + | <description summary="Create the image description object from ICC data"> | |||
| 949 | + | Create an image description object based on the ICC information | |||
| 950 | + | previously set on this object. A compositor must parse the ICC data in | |||
| 951 | + | some undefined but finite amount of time. | |||
| 952 | + | ||||
| 953 | + | The completeness of the parameter set is verified. If the set is not | |||
| 954 | + | complete, the protocol error incomplete_set is raised. For the | |||
| 955 | + | definition of a complete set, see the description of this interface. | |||
| 956 | + | ||||
| 957 | + | If the particular combination of the information is not supported | |||
| 958 | + | by the compositor, the resulting image description object shall | |||
| 959 | + | immediately deliver the wp_image_description_v1.failed event with the | |||
| 960 | + | 'unsupported' cause. If a valid image description was created from the | |||
| 961 | + | information, the wp_image_description_v1.ready event will eventually | |||
| 962 | + | be sent instead. | |||
| 963 | + | ||||
| 964 | + | This request destroys the wp_image_description_creator_icc_v1 object. | |||
| 965 | + | ||||
| 966 | + | The resulting image description object does not allow get_information | |||
| 967 | + | request. | |||
| 968 | + | </description> | |||
| 969 | + | ||||
| 970 | + | <arg name="image_description" | |||
| 971 | + | type="new_id" interface="wp_image_description_v1"/> | |||
| 972 | + | </request> | |||
| 973 | + | ||||
| 974 | + | <request name="set_icc_file"> | |||
| 975 | + | <description summary="set the ICC profile file"> | |||
| 976 | + | Sets the ICC profile file to be used as the basis of the image | |||
| 977 | + | description. | |||
| 978 | + | ||||
| 979 | + | The data shall be found through the given fd at the given offset, having | |||
| 980 | + | the given length. The fd must be seekable and readable. Violating these | |||
| 981 | + | requirements raises the bad_fd protocol error. | |||
| 982 | + | ||||
| 983 | + | If reading the data fails due to an error independent of the client, the | |||
| 984 | + | compositor shall send the wp_image_description_v1.failed event on the | |||
| 985 | + | created wp_image_description_v1 with the 'operating_system' cause. | |||
| 986 | + | ||||
| 987 | + | The maximum size of the ICC profile is 32 MB. If length is greater than | |||
| 988 | + | that or zero, the protocol error bad_size is raised. If offset + length | |||
| 989 | + | exceeds the file size, the protocol error out_of_file is raised. | |||
| 990 | + | ||||
| 991 | + | A compositor may read the file at any time starting from this request | |||
| 992 | + | and only until whichever happens first: | |||
| 993 | + | - If create request was issued, the wp_image_description_v1 object | |||
| 994 | + | delivers either failed or ready event; or | |||
| 995 | + | - if create request was not issued, this | |||
| 996 | + | wp_image_description_creator_icc_v1 object is destroyed. | |||
| 997 | + | ||||
| 998 | + | A compositor shall not modify the contents of the file, and the fd may | |||
| 999 | + | be sealed for writes and size changes. The client must ensure to its | |||
| 1000 | + | best ability that the data does not change while the compositor is | |||
| 1001 | + | reading it. | |||
| 1002 | + | ||||
| 1003 | + | The data must represent a valid ICC profile. The ICC profile version | |||
| 1004 | + | must be 2 or 4, it must be a 3 channel profile and the class must be | |||
| 1005 | + | Display or ColorSpace. Violating these requirements will not result in a | |||
| 1006 | + | protocol error, but will eventually send the | |||
| 1007 | + | wp_image_description_v1.failed event on the created | |||
| 1008 | + | wp_image_description_v1 with the 'unsupported' cause. | |||
| 1009 | + | ||||
| 1010 | + | See the International Color Consortium specification ICC.1:2022 for more | |||
| 1011 | + | details about ICC profiles. | |||
| 1012 | + | ||||
| 1013 | + | If ICC file has already been set on this object, the protocol error | |||
| 1014 | + | already_set is raised. | |||
| 1015 | + | </description> | |||
| 1016 | + | ||||
| 1017 | + | <arg name="icc_profile" type="fd" | |||
| 1018 | + | summary="ICC profile"/> | |||
| 1019 | + | <arg name="offset" type="uint" | |||
| 1020 | + | summary="byte offset in fd to start of ICC data"/> | |||
| 1021 | + | <arg name="length" type="uint" | |||
| 1022 | + | summary="length of ICC data in bytes"/> | |||
| 1023 | + | </request> | |||
| 1024 | + | </interface> | |||
| 1025 | + | ||||
| 1026 | + | <interface name="wp_image_description_creator_params_v1" version="3"> | |||
| 1027 | + | <description summary="holder of image description parameters"> | |||
| 1028 | + | This type of object is used for collecting all the parameters required | |||
| 1029 | + | to create a wp_image_description_v1 object. A complete set of required | |||
| 1030 | + | parameters consists of these properties: | |||
| 1031 | + | - transfer characteristic function (tf) | |||
| 1032 | + | - chromaticities of primaries and white point (primary color volume) | |||
| 1033 | + | ||||
| 1034 | + | The following properties are optional and have a well-defined default | |||
| 1035 | + | if not explicitly set: | |||
| 1036 | + | - primary color volume luminance range | |||
| 1037 | + | - reference white luminance level | |||
| 1038 | + | - mastering display primaries and white point (target color volume) | |||
| 1039 | + | - mastering luminance range | |||
| 1040 | + | ||||
| 1041 | + | The following properties are optional and will be ignored | |||
| 1042 | + | if not explicitly set: | |||
| 1043 | + | - maximum content light level | |||
| 1044 | + | - maximum frame-average light level | |||
| 1045 | + | ||||
| 1046 | + | Each required property must be set exactly once if the client is to create | |||
| 1047 | + | an image description. The set requests verify that a property was not | |||
| 1048 | + | already set. The create request verifies that all required properties are | |||
| 1049 | + | set. There may be several alternative requests for setting each property, | |||
| 1050 | + | and in that case the client must choose one of them. | |||
| 1051 | + | ||||
| 1052 | + | Once all properties have been set, the create request must be used to | |||
| 1053 | + | create the image description object, destroying the creator in the | |||
| 1054 | + | process. | |||
| 1055 | + | ||||
| 1056 | + | A viewer, who is viewing the display defined by the resulting image | |||
| 1057 | + | description (the viewing environment included), is assumed to be fully | |||
| 1058 | + | adapted to the primary color volume's white point. | |||
| 1059 | + | ||||
| 1060 | + | Any of the following conditions will cause the colorimetry of a pixel | |||
| 1061 | + | to become undefined: | |||
| 1062 | + | - Values outside of the defined range of the transfer characteristic. | |||
| 1063 | + | - Tristimulus that exceeds the target color volume. | |||
| 1064 | + | - If extended_target_volume is not supported: tristimulus that exceeds | |||
| 1065 | + | the primary color volume. | |||
| 1066 | + | ||||
| 1067 | + | The closest correspondence to an image description created through this | |||
| 1068 | + | interface is the Display class of profiles in ICC. | |||
| 1069 | + | </description> | |||
| 1070 | + | ||||
| 1071 | + | <enum name="error"> | |||
| 1072 | + | <description summary="protocol errors"/> | |||
| 1073 | + | ||||
| 1074 | + | <entry name="incomplete_set" value="0" | |||
| 1075 | + | summary="incomplete parameter set"/> | |||
| 1076 | + | <entry name="already_set" value="1" | |||
| 1077 | + | summary="property already set"/> | |||
| 1078 | + | <entry name="unsupported_feature" value="2" | |||
| 1079 | + | summary="request not supported"/> | |||
| 1080 | + | <entry name="invalid_tf" value="3" | |||
| 1081 | + | summary="invalid transfer characteristic"/> | |||
| 1082 | + | <entry name="invalid_primaries_named" value="4" | |||
| 1083 | + | summary="invalid primaries named"/> | |||
| 1084 | + | <entry name="invalid_luminance" value="5" | |||
| 1085 | + | summary="invalid luminance value or range"/> | |||
| 1086 | + | </enum> | |||
| 1087 | + | ||||
| 1088 | + | <request name="create" type="destructor"> | |||
| 1089 | + | <description summary="Create the image description object using params"> | |||
| 1090 | + | Create an image description object based on the parameters previously | |||
| 1091 | + | set on this object. | |||
| 1092 | + | ||||
| 1093 | + | The completeness of the parameter set is verified. If the set is not | |||
| 1094 | + | complete, the protocol error incomplete_set is raised. For the | |||
| 1095 | + | definition of a complete set, see the description of this interface. | |||
| 1096 | + | ||||
| 1097 | + | When both max_cll and max_fall are set, max_fall must be less or equal | |||
| 1098 | + | to max_cll otherwise the invalid_luminance protocol error is raised. | |||
| 1099 | + | ||||
| 1100 | + | In version 1, these following conditions also result in the | |||
| 1101 | + | invalid_luminance protocol error. Version 2 and later do not have this | |||
| 1102 | + | requirement. | |||
| 1103 | + | - When max_cll is set, it must be greater than min L and less or equal | |||
| 1104 | + | to max L of the mastering luminance range. | |||
| 1105 | + | - When max_fall is set, it must be greater than min L and less or equal | |||
| 1106 | + | to max L of the mastering luminance range. | |||
| 1107 | + | ||||
| 1108 | + | If the particular combination of the parameter set is not supported | |||
| 1109 | + | by the compositor, the resulting image description object shall | |||
| 1110 | + | immediately deliver the wp_image_description_v1.failed event with the | |||
| 1111 | + | 'unsupported' cause. If a valid image description was created from the | |||
| 1112 | + | parameter set, the wp_image_description_v1.ready event will eventually | |||
| 1113 | + | be sent instead. | |||
| 1114 | + | ||||
| 1115 | + | This request destroys the wp_image_description_creator_params_v1 | |||
| 1116 | + | object. | |||
| 1117 | + | ||||
| 1118 | + | The resulting image description object does not allow get_information | |||
| 1119 | + | request. | |||
| 1120 | + | </description> | |||
| 1121 | + | ||||
| 1122 | + | <arg name="image_description" | |||
| 1123 | + | type="new_id" interface="wp_image_description_v1"/> | |||
| 1124 | + | </request> | |||
| 1125 | + | ||||
| 1126 | + | <request name="set_tf_named"> | |||
| 1127 | + | <description summary="named transfer characteristic"> | |||
| 1128 | + | Sets the transfer characteristic using explicitly enumerated named | |||
| 1129 | + | functions. | |||
| 1130 | + | ||||
| 1131 | + | When the resulting image description is attached to an image, the | |||
| 1132 | + | content should be decoded according to the industry standard | |||
| 1133 | + | practices for the transfer characteristic. | |||
| 1134 | + | ||||
| 1135 | + | Only names advertised with wp_color_manager_v1 event supported_tf_named | |||
| 1136 | + | are allowed. Other values shall raise the protocol error invalid_tf. | |||
| 1137 | + | ||||
| 1138 | + | If transfer characteristic has already been set on this object, the | |||
| 1139 | + | protocol error already_set is raised. | |||
| 1140 | + | </description> | |||
| 1141 | + | ||||
| 1142 | + | <arg name="tf" type="uint" enum="wp_color_manager_v1.transfer_function" | |||
| 1143 | + | summary="named transfer function"/> | |||
| 1144 | + | </request> | |||
| 1145 | + | ||||
| 1146 | + | <request name="set_tf_power"> | |||
| 1147 | + | <description summary="transfer characteristic as a power curve"> | |||
| 1148 | + | Sets the color component transfer characteristic to a power curve with | |||
| 1149 | + | the given exponent. Negative values are handled by mirroring the | |||
| 1150 | + | positive half of the curve through the origin. The valid domain and | |||
| 1151 | + | range of the curve are all finite real numbers. This curve represents | |||
| 1152 | + | the conversion from electrical to optical color channel values. | |||
| 1153 | + | ||||
| 1154 | + | The curve exponent shall be multiplied by 10000 to get the argument eexp | |||
| 1155 | + | value to carry the precision of 4 decimals. | |||
| 1156 | + | ||||
| 1157 | + | The curve exponent must be at least 1.0 and at most 10.0. Otherwise the | |||
| 1158 | + | protocol error invalid_tf is raised. | |||
| 1159 | + | ||||
| 1160 | + | If transfer characteristic has already been set on this object, the | |||
| 1161 | + | protocol error already_set is raised. | |||
| 1162 | + | ||||
| 1163 | + | This request can be used when the compositor advertises | |||
| 1164 | + | wp_color_manager_v1.feature.set_tf_power. Otherwise this request raises | |||
| 1165 | + | the protocol error unsupported_feature. | |||
| 1166 | + | </description> | |||
| 1167 | + | ||||
| 1168 | + | <arg name="eexp" type="uint" summary="the exponent * 10000"/> | |||
| 1169 | + | </request> | |||
| 1170 | + | ||||
| 1171 | + | <request name="set_primaries_named"> | |||
| 1172 | + | <description summary="named primaries"> | |||
| 1173 | + | Sets the color primaries and white point using explicitly named sets. | |||
| 1174 | + | This describes the primary color volume which is the basis for color | |||
| 1175 | + | value encoding. | |||
| 1176 | + | ||||
| 1177 | + | Only names advertised with wp_color_manager_v1 event | |||
| 1178 | + | supported_primaries_named are allowed. Other values shall raise the | |||
| 1179 | + | protocol error invalid_primaries_named. | |||
| 1180 | + | ||||
| 1181 | + | If primaries have already been set on this object, the protocol error | |||
| 1182 | + | already_set is raised. | |||
| 1183 | + | </description> | |||
| 1184 | + | ||||
| 1185 | + | <arg name="primaries" type="uint" enum="wp_color_manager_v1.primaries" | |||
| 1186 | + | summary="named primaries"/> | |||
| 1187 | + | </request> | |||
| 1188 | + | ||||
| 1189 | + | <request name="set_primaries"> | |||
| 1190 | + | <description summary="primaries as chromaticity coordinates"> | |||
| 1191 | + | Sets the color primaries and white point using CIE 1931 xy chromaticity | |||
| 1192 | + | coordinates. This describes the primary color volume which is the basis | |||
| 1193 | + | for color value encoding. | |||
| 1194 | + | ||||
| 1195 | + | Each coordinate value is multiplied by 1 million to get the argument | |||
| 1196 | + | value to carry precision of 6 decimals. | |||
| 1197 | + | ||||
| 1198 | + | If primaries have already been set on this object, the protocol error | |||
| 1199 | + | already_set is raised. | |||
| 1200 | + | ||||
| 1201 | + | This request can be used if the compositor advertises | |||
| 1202 | + | wp_color_manager_v1.feature.set_primaries. Otherwise this request raises | |||
| 1203 | + | the protocol error unsupported_feature. | |||
| 1204 | + | </description> | |||
| 1205 | + | ||||
| 1206 | + | <arg name="r_x" type="int" summary="Red x * 1M"/> | |||
| 1207 | + | <arg name="r_y" type="int" summary="Red y * 1M"/> | |||
| 1208 | + | <arg name="g_x" type="int" summary="Green x * 1M"/> | |||
| 1209 | + | <arg name="g_y" type="int" summary="Green y * 1M"/> | |||
| 1210 | + | <arg name="b_x" type="int" summary="Blue x * 1M"/> | |||
| 1211 | + | <arg name="b_y" type="int" summary="Blue y * 1M"/> | |||
| 1212 | + | <arg name="w_x" type="int" summary="White x * 1M"/> | |||
| 1213 | + | <arg name="w_y" type="int" summary="White y * 1M"/> | |||
| 1214 | + | </request> | |||
| 1215 | + | ||||
| 1216 | + | <request name="set_luminances"> | |||
| 1217 | + | <description summary="primary color volume luminance range and reference white"> | |||
| 1218 | + | Sets the primary color volume luminance range and the reference white | |||
| 1219 | + | luminance level. These values include the minimum display emission, but | |||
| 1220 | + | not external flare. The minimum display emission is assumed to have | |||
| 1221 | + | the chromaticity of the primary color volume white point. | |||
| 1222 | + | ||||
| 1223 | + | The default luminances from | |||
| 1224 | + | https://www.color.org/chardata/rgb/srgb.xalter are | |||
| 1225 | + | - primary color volume minimum: 0.2 cd/m² | |||
| 1226 | + | - primary color volume maximum: 80 cd/m² | |||
| 1227 | + | - reference white: 80 cd/m² | |||
| 1228 | + | ||||
| 1229 | + | Setting a named transfer characteristic can imply other default | |||
| 1230 | + | luminances. | |||
| 1231 | + | ||||
| 1232 | + | The default luminances get overwritten when this request is used. | |||
| 1233 | + | With transfer_function.st2084_pq the given 'max_lum' value is ignored, | |||
| 1234 | + | and 'max_lum' is taken as 'min_lum' + 10000 cd/m². | |||
| 1235 | + | ||||
| 1236 | + | 'min_lum' and 'max_lum' specify the minimum and maximum luminances of | |||
| 1237 | + | the primary color volume as reproduced by the targeted display. | |||
| 1238 | + | ||||
| 1239 | + | 'reference_lum' specifies the luminance of the reference white as | |||
| 1240 | + | reproduced by the targeted display, and reflects the targeted viewing | |||
| 1241 | + | environment. | |||
| 1242 | + | ||||
| 1243 | + | Compositors should make sure that all content is anchored, meaning that | |||
| 1244 | + | an input signal level of 'reference_lum' on one image description and | |||
| 1245 | + | another input signal level of 'reference_lum' on another image | |||
| 1246 | + | description should produce the same output level, even though the | |||
| 1247 | + | 'reference_lum' on both image representations can be different. | |||
| 1248 | + | ||||
| 1249 | + | 'reference_lum' may be higher than 'max_lum'. In that case reaching | |||
| 1250 | + | the reference white output level in image content requires the | |||
| 1251 | + | 'extended_target_volume' feature support. | |||
| 1252 | + | ||||
| 1253 | + | If 'max_lum' or 'reference_lum' are less than or equal to 'min_lum', | |||
| 1254 | + | the protocol error invalid_luminance is raised. | |||
| 1255 | + | ||||
| 1256 | + | The minimum luminance is multiplied by 10000 to get the argument | |||
| 1257 | + | 'min_lum' value and carries precision of 4 decimals. The maximum | |||
| 1258 | + | luminance and reference white luminance values are unscaled. | |||
| 1259 | + | ||||
| 1260 | + | If the primary color volume luminance range and the reference white | |||
| 1261 | + | luminance level have already been set on this object, the protocol error | |||
| 1262 | + | already_set is raised. | |||
| 1263 | + | ||||
| 1264 | + | This request can be used if the compositor advertises | |||
| 1265 | + | wp_color_manager_v1.feature.set_luminances. Otherwise this request | |||
| 1266 | + | raises the protocol error unsupported_feature. | |||
| 1267 | + | </description> | |||
| 1268 | + | ||||
| 1269 | + | <arg name="min_lum" type="uint" | |||
| 1270 | + | summary="minimum luminance (cd/m²) * 10000"/> | |||
| 1271 | + | <arg name="max_lum" type="uint" | |||
| 1272 | + | summary="maximum luminance (cd/m²)"/> | |||
| 1273 | + | <arg name="reference_lum" type="uint" | |||
| 1274 | + | summary="reference white luminance (cd/m²)"/> | |||
| 1275 | + | </request> | |||
| 1276 | + | ||||
| 1277 | + | <request name="set_mastering_display_primaries"> | |||
| 1278 | + | <description summary="mastering display primaries as chromaticity coordinates"> | |||
| 1279 | + | Provides the color primaries and white point of the mastering display | |||
| 1280 | + | using CIE 1931 xy chromaticity coordinates. This is compatible with the | |||
| 1281 | + | SMPTE ST 2086 definition of HDR static metadata. | |||
| 1282 | + | ||||
| 1283 | + | The mastering display primaries and mastering display luminances define | |||
| 1284 | + | the target color volume. | |||
| 1285 | + | ||||
| 1286 | + | If mastering display primaries are not explicitly set, the target color | |||
| 1287 | + | volume is assumed to have the same primaries as the primary color volume. | |||
| 1288 | + | ||||
| 1289 | + | The target color volume is defined by all tristimulus values between 0.0 | |||
| 1290 | + | and 1.0 (inclusive) of the color space defined by the given mastering | |||
| 1291 | + | display primaries and white point. The colorimetry is identical between | |||
| 1292 | + | the container color space and the mastering display color space, | |||
| 1293 | + | including that no chromatic adaptation is applied even if the white | |||
| 1294 | + | points differ. | |||
| 1295 | + | ||||
| 1296 | + | The target color volume can exceed the primary color volume to allow for | |||
| 1297 | + | a greater color volume with an existing color space definition (for | |||
| 1298 | + | example scRGB). It can be smaller than the primary color volume to | |||
| 1299 | + | minimize gamut and tone mapping distances for big color spaces (HDR | |||
| 1300 | + | metadata). | |||
| 1301 | + | ||||
| 1302 | + | To make use of the entire target color volume a suitable pixel format | |||
| 1303 | + | has to be chosen (e.g. floating point to exceed the primary color | |||
| 1304 | + | volume, or abusing limited quantization range as with xvYCC). | |||
| 1305 | + | ||||
| 1306 | + | Each coordinate value is multiplied by 1 million to get the argument | |||
| 1307 | + | value to carry precision of 6 decimals. | |||
| 1308 | + | ||||
| 1309 | + | If mastering display primaries have already been set on this object, the | |||
| 1310 | + | protocol error already_set is raised. | |||
| 1311 | + | ||||
| 1312 | + | This request can be used if the compositor advertises | |||
| 1313 | + | wp_color_manager_v1.feature.set_mastering_display_primaries. Otherwise | |||
| 1314 | + | this request raises the protocol error unsupported_feature. The | |||
| 1315 | + | advertisement implies support only for target color volumes fully | |||
| 1316 | + | contained within the primary color volume. | |||
| 1317 | + | ||||
| 1318 | + | If a compositor additionally supports target color volume exceeding the | |||
| 1319 | + | primary color volume, it must advertise | |||
| 1320 | + | wp_color_manager_v1.feature.extended_target_volume. If a client uses | |||
| 1321 | + | target color volume exceeding the primary color volume and the | |||
| 1322 | + | compositor does not support it, the result is implementation defined. | |||
| 1323 | + | Compositors are recommended to detect this case and fail the image | |||
| 1324 | + | description gracefully, but it may as well result in color artifacts. | |||
| 1325 | + | </description> | |||
| 1326 | + | ||||
| 1327 | + | <arg name="r_x" type="int" summary="Red x * 1M"/> | |||
| 1328 | + | <arg name="r_y" type="int" summary="Red y * 1M"/> | |||
| 1329 | + | <arg name="g_x" type="int" summary="Green x * 1M"/> | |||
| 1330 | + | <arg name="g_y" type="int" summary="Green y * 1M"/> | |||
| 1331 | + | <arg name="b_x" type="int" summary="Blue x * 1M"/> | |||
| 1332 | + | <arg name="b_y" type="int" summary="Blue y * 1M"/> | |||
| 1333 | + | <arg name="w_x" type="int" summary="White x * 1M"/> | |||
| 1334 | + | <arg name="w_y" type="int" summary="White y * 1M"/> | |||
| 1335 | + | </request> | |||
| 1336 | + | ||||
| 1337 | + | <request name="set_mastering_luminance"> | |||
| 1338 | + | <description summary="display mastering luminance range"> | |||
| 1339 | + | Sets the luminance range that was used during the content mastering | |||
| 1340 | + | process as the minimum and maximum absolute luminance L. These values | |||
| 1341 | + | include the minimum display emission and ambient flare luminances, | |||
| 1342 | + | assumed to be optically additive and have the chromaticity of the | |||
| 1343 | + | primary color volume white point. This should be | |||
| 1344 | + | compatible with the SMPTE ST 2086 definition of HDR static metadata. | |||
| 1345 | + | ||||
| 1346 | + | The mastering display primaries and mastering display luminances define | |||
| 1347 | + | the target color volume. | |||
| 1348 | + | ||||
| 1349 | + | If mastering luminances are not explicitly set, the target color volume | |||
| 1350 | + | is assumed to have the same min and max luminances as the primary color | |||
| 1351 | + | volume. | |||
| 1352 | + | ||||
| 1353 | + | If max L is less than or equal to min L, the protocol error | |||
| 1354 | + | invalid_luminance is raised. | |||
| 1355 | + | ||||
| 1356 | + | Min L value is multiplied by 10000 to get the argument min_lum value | |||
| 1357 | + | and carry precision of 4 decimals. Max L value is unscaled for max_lum. | |||
| 1358 | + | ||||
| 1359 | + | This request can be used if the compositor advertises | |||
| 1360 | + | wp_color_manager_v1.feature.set_mastering_display_primaries. Otherwise | |||
| 1361 | + | this request raises the protocol error unsupported_feature. The | |||
| 1362 | + | advertisement implies support only for target color volumes fully | |||
| 1363 | + | contained within the primary color volume. | |||
| 1364 | + | ||||
| 1365 | + | If a compositor additionally supports target color volume exceeding the | |||
| 1366 | + | primary color volume, it must advertise | |||
| 1367 | + | wp_color_manager_v1.feature.extended_target_volume. If a client uses | |||
| 1368 | + | target color volume exceeding the primary color volume and the | |||
| 1369 | + | compositor does not support it, the result is implementation defined. | |||
| 1370 | + | Compositors are recommended to detect this case and fail the image | |||
| 1371 | + | description gracefully, but it may as well result in color artifacts. | |||
| 1372 | + | </description> | |||
| 1373 | + | ||||
| 1374 | + | <arg name="min_lum" type="uint" summary="min L (cd/m²) * 10000"/> | |||
| 1375 | + | <arg name="max_lum" type="uint" summary="max L (cd/m²)"/> | |||
| 1376 | + | </request> | |||
| 1377 | + | ||||
| 1378 | + | <request name="set_max_cll"> | |||
| 1379 | + | <description summary="maximum content light level"> | |||
| 1380 | + | Sets the maximum content light level (max_cll) as defined by CTA-861-H. | |||
| 1381 | + | ||||
| 1382 | + | max_cll is undefined by default. | |||
| 1383 | + | </description> | |||
| 1384 | + | ||||
| 1385 | + | <arg name="max_cll" type="uint" summary="Maximum content light level (cd/m²)"/> | |||
| 1386 | + | </request> | |||
| 1387 | + | ||||
| 1388 | + | <request name="set_max_fall"> | |||
| 1389 | + | <description summary="maximum frame-average light level"> | |||
| 1390 | + | Sets the maximum frame-average light level (max_fall) as defined by | |||
| 1391 | + | CTA-861-H. | |||
| 1392 | + | ||||
| 1393 | + | max_fall is undefined by default. | |||
| 1394 | + | </description> | |||
| 1395 | + | ||||
| 1396 | + | <arg name="max_fall" type="uint" summary="Maximum frame-average light level (cd/m²)"/> | |||
| 1397 | + | </request> | |||
| 1398 | + | </interface> | |||
| 1399 | + | ||||
| 1400 | + | <interface name="wp_image_description_v1" version="3"> | |||
| 1401 | + | <description summary="Colorimetric image description"> | |||
| 1402 | + | An image description carries information about the pixel color encoding | |||
| 1403 | + | and its intended display and viewing environment. The image description is | |||
| 1404 | + | attached to a wl_surface via | |||
| 1405 | + | wp_color_management_surface_v1.set_image_description. A compositor can use | |||
| 1406 | + | this information to decode pixel values into colorimetrically meaningful | |||
| 1407 | + | quantities, which allows the compositor to transform the surface contents | |||
| 1408 | + | to become suitable for various displays and viewing environments. | |||
| 1409 | + | ||||
| 1410 | + | Note, that the wp_image_description_v1 object is not ready to be used | |||
| 1411 | + | immediately after creation. The object eventually delivers either the | |||
| 1412 | + | 'ready' or the 'failed' event, specified in all requests creating it. The | |||
| 1413 | + | object is deemed "ready" after receiving the 'ready' event. | |||
| 1414 | + | ||||
| 1415 | + | An object which is not ready is illegal to use, it can only be destroyed. | |||
| 1416 | + | Any other request in this interface shall result in the 'not_ready' | |||
| 1417 | + | protocol error. Attempts to use an object which is not ready through other | |||
| 1418 | + | interfaces shall raise protocol errors defined there. | |||
| 1419 | + | ||||
| 1420 | + | Once created and regardless of how it was created, a | |||
| 1421 | + | wp_image_description_v1 object always refers to one fixed image | |||
| 1422 | + | description. It cannot change after creation. | |||
| 1423 | + | </description> | |||
| 1424 | + | ||||
| 1425 | + | <request name="destroy" type="destructor"> | |||
| 1426 | + | <description summary="destroy the image description"> | |||
| 1427 | + | Destroy this object. It is safe to destroy an object which is not ready. | |||
| 1428 | + | ||||
| 1429 | + | Destroying a wp_image_description_v1 object has no side-effects, not | |||
| 1430 | + | even if a wp_color_management_surface_v1.set_image_description has not | |||
| 1431 | + | yet been followed by a wl_surface.commit. | |||
| 1432 | + | </description> | |||
| 1433 | + | </request> | |||
| 1434 | + | ||||
| 1435 | + | <enum name="error"> | |||
| 1436 | + | <description summary="protocol errors"/> | |||
| 1437 | + | ||||
| 1438 | + | <entry name="not_ready" value="0" | |||
| 1439 | + | summary="attempted to use an object which is not ready"/> | |||
| 1440 | + | <entry name="no_information" value="1" | |||
| 1441 | + | summary="get_information not allowed"/> | |||
| 1442 | + | </enum> | |||
| 1443 | + | ||||
| 1444 | + | <enum name="cause"> | |||
| 1445 | + | <description summary="generic reason for failure"/> | |||
| 1446 | + | ||||
| 1447 | + | <entry name="low_version" value="0" | |||
| 1448 | + | summary="interface version too low"/> | |||
| 1449 | + | <entry name="unsupported" value="1" | |||
| 1450 | + | summary="unsupported image description data"/> | |||
| 1451 | + | <entry name="operating_system" value="2" | |||
| 1452 | + | summary="error independent of the client"/> | |||
| 1453 | + | <entry name="no_output" value="3" | |||
| 1454 | + | summary="the relevant output no longer exists"/> | |||
| 1455 | + | </enum> | |||
| 1456 | + | ||||
| 1457 | + | <event name="failed"> | |||
| 1458 | + | <description summary="graceful error on creating the image description"> | |||
| 1459 | + | If creating a wp_image_description_v1 object fails for a reason that is | |||
| 1460 | + | not defined as a protocol error, this event is sent. | |||
| 1461 | + | ||||
| 1462 | + | The requests that create image description objects define whether and | |||
| 1463 | + | when this can occur. Only such creation requests can trigger this event. | |||
| 1464 | + | This event cannot be triggered after the image description was | |||
| 1465 | + | successfully formed. | |||
| 1466 | + | ||||
| 1467 | + | Once this event has been sent, the wp_image_description_v1 object will | |||
| 1468 | + | never become ready and it can only be destroyed. | |||
| 1469 | + | </description> | |||
| 1470 | + | ||||
| 1471 | + | <arg name="cause" type="uint" enum="cause" | |||
| 1472 | + | summary="generic reason"/> | |||
| 1473 | + | <arg name="msg" type="string" | |||
| 1474 | + | summary="ad hoc human-readable explanation"/> | |||
| 1475 | + | </event> | |||
| 1476 | + | ||||
| 1477 | + | <event name="ready" deprecated-since="2"> | |||
| 1478 | + | <description summary="the object is ready to be used (32-bit)"> | |||
| 1479 | + | Starting from interface version 2, the 'ready2' event is sent instead | |||
| 1480 | + | of this event. | |||
| 1481 | + | ||||
| 1482 | + | For the definition of this event, see the 'ready2' event. The | |||
| 1483 | + | difference to this event is as follows. | |||
| 1484 | + | ||||
| 1485 | + | The id number is valid only as long as the protocol object is alive. If | |||
| 1486 | + | all protocol objects referring to the same image description record are | |||
| 1487 | + | destroyed, the id number may be recycled for a different image | |||
| 1488 | + | description record. | |||
| 1489 | + | </description> | |||
| 1490 | + | ||||
| 1491 | + | <arg name="identity" type="uint" | |||
| 1492 | + | summary="the 32-bit image description id number"/> | |||
| 1493 | + | </event> | |||
| 1494 | + | ||||
| 1495 | + | <request name="get_information"> | |||
| 1496 | + | <description summary="get information about the image description"> | |||
| 1497 | + | Creates a wp_image_description_info_v1 object which delivers the | |||
| 1498 | + | information that makes up the image description. | |||
| 1499 | + | ||||
| 1500 | + | Not all image description protocol objects allow get_information | |||
| 1501 | + | request. Whether it is allowed or not is defined by the request that | |||
| 1502 | + | created the object. If get_information is not allowed, the protocol | |||
| 1503 | + | error no_information is raised. | |||
| 1504 | + | </description> | |||
| 1505 | + | ||||
| 1506 | + | <arg name="information" | |||
| 1507 | + | type="new_id" interface="wp_image_description_info_v1"/> | |||
| 1508 | + | </request> | |||
| 1509 | + | ||||
| 1510 | + | <!-- Version 2 additions --> | |||
| 1511 | + | ||||
| 1512 | + | <event name="ready2" since="2"> | |||
| 1513 | + | <description summary="the object is ready to be used"> | |||
| 1514 | + | Once this event has been sent, the wp_image_description_v1 object is | |||
| 1515 | + | deemed "ready". Ready objects can be used to send requests and can be | |||
| 1516 | + | used through other interfaces. | |||
| 1517 | + | ||||
| 1518 | + | Every ready wp_image_description_v1 protocol object refers to an | |||
| 1519 | + | underlying image description record in the compositor. Multiple protocol | |||
| 1520 | + | objects may end up referring to the same record. Clients may identify | |||
| 1521 | + | these "copies" by comparing their id numbers: if the numbers from two | |||
| 1522 | + | protocol objects are identical, the protocol objects refer to the same | |||
| 1523 | + | image description record. Two different image description records | |||
| 1524 | + | cannot have the same id number simultaneously. The id number does not | |||
| 1525 | + | change during the lifetime of the image description record. | |||
| 1526 | + | ||||
| 1527 | + | Image description id number is not a protocol object id. Zero is | |||
| 1528 | + | reserved as an invalid id number. It shall not be possible for a client | |||
| 1529 | + | to refer to an image description by its id number in protocol. The id | |||
| 1530 | + | numbers might not be portable between Wayland connections. A compositor | |||
| 1531 | + | shall not send an invalid id number. | |||
| 1532 | + | ||||
| 1533 | + | Compositors must not recycle image description id numbers. | |||
| 1534 | + | ||||
| 1535 | + | This identity allows clients to de-duplicate image description records | |||
| 1536 | + | and avoid get_information request if they already have the image | |||
| 1537 | + | description information. | |||
| 1538 | + | </description> | |||
| 1539 | + | ||||
| 1540 | + | <arg name="identity_hi" type="uint" | |||
| 1541 | + | summary="high 32 bits of the 64-bit image description id number"/> | |||
| 1542 | + | <arg name="identity_lo" type="uint" | |||
| 1543 | + | summary="low 32 bits of the 64-bit image description id number"/> | |||
| 1544 | + | </event> | |||
| 1545 | + | </interface> | |||
| 1546 | + | ||||
| 1547 | + | <interface name="wp_image_description_info_v1" version="3"> | |||
| 1548 | + | <description summary="Colorimetric image description information"> | |||
| 1549 | + | Sends all matching events describing an image description object exactly | |||
| 1550 | + | once and finally sends the 'done' event. | |||
| 1551 | + | ||||
| 1552 | + | This means | |||
| 1553 | + | - if the image description is parametric, it must send | |||
| 1554 | + | - primaries | |||
| 1555 | + | - named_primaries, if applicable | |||
| 1556 | + | - at least one of tf_power and tf_named, as applicable | |||
| 1557 | + | - luminances | |||
| 1558 | + | - target_primaries | |||
| 1559 | + | - target_luminance | |||
| 1560 | + | - if the image description is parametric, it may send, if applicable, | |||
| 1561 | + | - target_max_cll | |||
| 1562 | + | - target_max_fall | |||
| 1563 | + | - if the image description contains an ICC profile, it must send the | |||
| 1564 | + | icc_file event | |||
| 1565 | + | ||||
| 1566 | + | Once a wp_image_description_info_v1 object has delivered a 'done' event it | |||
| 1567 | + | is automatically destroyed. | |||
| 1568 | + | ||||
| 1569 | + | Every wp_image_description_info_v1 created from the same | |||
| 1570 | + | wp_image_description_v1 shall always return the exact same data. | |||
| 1571 | + | </description> | |||
| 1572 | + | ||||
| 1573 | + | <event name="done" type="destructor"> | |||
| 1574 | + | <description summary="end of information"> | |||
| 1575 | + | Signals the end of information events and destroys the object. | |||
| 1576 | + | </description> | |||
| 1577 | + | </event> | |||
| 1578 | + | ||||
| 1579 | + | <event name="icc_file"> | |||
| 1580 | + | <description summary="ICC profile matching the image description"> | |||
| 1581 | + | The icc argument provides a file descriptor to the client which may be | |||
| 1582 | + | memory-mapped to provide the ICC profile matching the image description. | |||
| 1583 | + | The fd is read-only, and if mapped then it must be mapped with | |||
| 1584 | + | MAP_PRIVATE by the client. | |||
| 1585 | + | ||||
| 1586 | + | The ICC profile version and other details are determined by the | |||
| 1587 | + | compositor. There is no provision for a client to ask for a specific | |||
| 1588 | + | kind of a profile. | |||
| 1589 | + | </description> | |||
| 1590 | + | ||||
| 1591 | + | <arg name="icc" type="fd" summary="ICC profile file descriptor"/> | |||
| 1592 | + | <arg name="icc_size" type="uint" summary="ICC profile size, in bytes"/> | |||
| 1593 | + | <!-- Offset always 0, compositor must not expose unnecessary data. --> | |||
| 1594 | + | </event> | |||
| 1595 | + | ||||
| 1596 | + | <event name="primaries"> | |||
| 1597 | + | <description summary="primaries as chromaticity coordinates"> | |||
| 1598 | + | Delivers the primary color volume primaries and white point using CIE | |||
| 1599 | + | 1931 xy chromaticity coordinates. | |||
| 1600 | + | ||||
| 1601 | + | Each coordinate value is multiplied by 1 million to get the argument | |||
| 1602 | + | value to carry precision of 6 decimals. | |||
| 1603 | + | </description> | |||
| 1604 | + | ||||
| 1605 | + | <arg name="r_x" type="int" summary="Red x * 1M"/> | |||
| 1606 | + | <arg name="r_y" type="int" summary="Red y * 1M"/> | |||
| 1607 | + | <arg name="g_x" type="int" summary="Green x * 1M"/> | |||
| 1608 | + | <arg name="g_y" type="int" summary="Green y * 1M"/> | |||
| 1609 | + | <arg name="b_x" type="int" summary="Blue x * 1M"/> | |||
| 1610 | + | <arg name="b_y" type="int" summary="Blue y * 1M"/> | |||
| 1611 | + | <arg name="w_x" type="int" summary="White x * 1M"/> | |||
| 1612 | + | <arg name="w_y" type="int" summary="White y * 1M"/> | |||
| 1613 | + | </event> | |||
| 1614 | + | ||||
| 1615 | + | <event name="primaries_named"> | |||
| 1616 | + | <description summary="named primaries"> | |||
| 1617 | + | Delivers the primary color volume primaries and white point using an | |||
| 1618 | + | explicitly enumerated named set. | |||
| 1619 | + | </description> | |||
| 1620 | + | ||||
| 1621 | + | <arg name="primaries" type="uint" enum="wp_color_manager_v1.primaries" | |||
| 1622 | + | summary="named primaries"/> | |||
| 1623 | + | </event> | |||
| 1624 | + | ||||
| 1625 | + | <event name="tf_power"> | |||
| 1626 | + | <description summary="transfer characteristic as a power curve"> | |||
| 1627 | + | The color component transfer characteristic of this image description is | |||
| 1628 | + | a pure power curve. This event provides the exponent of the power | |||
| 1629 | + | function. This curve represents the conversion from electrical to | |||
| 1630 | + | optical pixel or color values. | |||
| 1631 | + | ||||
| 1632 | + | The curve exponent has been multiplied by 10000 to get the argument eexp | |||
| 1633 | + | value to carry the precision of 4 decimals. | |||
| 1634 | + | </description> | |||
| 1635 | + | ||||
| 1636 | + | <arg name="eexp" type="uint" summary="the exponent * 10000"/> | |||
| 1637 | + | </event> | |||
| 1638 | + | ||||
| 1639 | + | <event name="tf_named"> | |||
| 1640 | + | <description summary="named transfer characteristic"> | |||
| 1641 | + | Delivers the transfer characteristic using an explicitly enumerated | |||
| 1642 | + | named function. | |||
| 1643 | + | </description> | |||
| 1644 | + | ||||
| 1645 | + | <arg name="tf" type="uint" enum="wp_color_manager_v1.transfer_function" | |||
| 1646 | + | summary="named transfer function"/> | |||
| 1647 | + | </event> | |||
| 1648 | + | ||||
| 1649 | + | <event name="luminances"> | |||
| 1650 | + | <description summary="primary color volume luminance range and reference white"> | |||
| 1651 | + | Delivers the primary color volume luminance range and the reference | |||
| 1652 | + | white luminance level. These values include the minimum display emission | |||
| 1653 | + | and ambient flare luminances, assumed to be optically additive and have | |||
| 1654 | + | the chromaticity of the primary color volume white point. | |||
| 1655 | + | ||||
| 1656 | + | The minimum luminance is multiplied by 10000 to get the argument | |||
| 1657 | + | 'min_lum' value and carries precision of 4 decimals. The maximum | |||
| 1658 | + | luminance and reference white luminance values are unscaled. | |||
| 1659 | + | </description> | |||
| 1660 | + | ||||
| 1661 | + | <arg name="min_lum" type="uint" | |||
| 1662 | + | summary="minimum luminance (cd/m²) * 10000"/> | |||
| 1663 | + | <arg name="max_lum" type="uint" | |||
| 1664 | + | summary="maximum luminance (cd/m²)"/> | |||
| 1665 | + | <arg name="reference_lum" type="uint" | |||
| 1666 | + | summary="reference white luminance (cd/m²)"/> | |||
| 1667 | + | </event> | |||
| 1668 | + | ||||
| 1669 | + | <event name="target_primaries"> | |||
| 1670 | + | <description summary="target primaries as chromaticity coordinates"> | |||
| 1671 | + | Provides the color primaries and white point of the target color volume | |||
| 1672 | + | using CIE 1931 xy chromaticity coordinates. This is compatible with the | |||
| 1673 | + | SMPTE ST 2086 definition of HDR static metadata for mastering displays. | |||
| 1674 | + | ||||
| 1675 | + | While primary color volume is about how color is encoded, the target | |||
| 1676 | + | color volume is the actually displayable color volume. | |||
| 1677 | + | ||||
| 1678 | + | Each coordinate value is multiplied by 1 million to get the argument | |||
| 1679 | + | value to carry precision of 6 decimals. | |||
| 1680 | + | </description> | |||
| 1681 | + | ||||
| 1682 | + | <arg name="r_x" type="int" summary="Red x * 1M"/> | |||
| 1683 | + | <arg name="r_y" type="int" summary="Red y * 1M"/> | |||
| 1684 | + | <arg name="g_x" type="int" summary="Green x * 1M"/> | |||
| 1685 | + | <arg name="g_y" type="int" summary="Green y * 1M"/> | |||
| 1686 | + | <arg name="b_x" type="int" summary="Blue x * 1M"/> | |||
| 1687 | + | <arg name="b_y" type="int" summary="Blue y * 1M"/> | |||
| 1688 | + | <arg name="w_x" type="int" summary="White x * 1M"/> | |||
| 1689 | + | <arg name="w_y" type="int" summary="White y * 1M"/> | |||
| 1690 | + | </event> | |||
| 1691 | + | ||||
| 1692 | + | <event name="target_luminance"> | |||
| 1693 | + | <description summary="target luminance range"> | |||
| 1694 | + | Provides the luminance range that the image description is targeting as | |||
| 1695 | + | the minimum and maximum absolute luminance L. These values include the | |||
| 1696 | + | minimum display emission and ambient flare luminances, assumed to be | |||
| 1697 | + | optically additive and have the chromaticity of the primary color | |||
| 1698 | + | volume white point. This should be compatible with the SMPTE ST 2086 | |||
| 1699 | + | definition of HDR static metadata. | |||
| 1700 | + | ||||
| 1701 | + | This luminance range is only theoretical and may not correspond to the | |||
| 1702 | + | luminance of light emitted on an actual display. | |||
| 1703 | + | ||||
| 1704 | + | Min L value is multiplied by 10000 to get the argument min_lum value and | |||
| 1705 | + | carry precision of 4 decimals. Max L value is unscaled for max_lum. | |||
| 1706 | + | </description> | |||
| 1707 | + | ||||
| 1708 | + | <arg name="min_lum" type="uint" summary="min L (cd/m²) * 10000"/> | |||
| 1709 | + | <arg name="max_lum" type="uint" summary="max L (cd/m²)"/> | |||
| 1710 | + | </event> | |||
| 1711 | + | ||||
| 1712 | + | <event name="target_max_cll"> | |||
| 1713 | + | <description summary="target maximum content light level"> | |||
| 1714 | + | Provides the targeted max_cll of the image description. max_cll is | |||
| 1715 | + | defined by CTA-861-H. | |||
| 1716 | + | ||||
| 1717 | + | This luminance is only theoretical and may not correspond to the | |||
| 1718 | + | luminance of light emitted on an actual display. | |||
| 1719 | + | </description> | |||
| 1720 | + | ||||
| 1721 | + | <arg name="max_cll" type="uint" | |||
| 1722 | + | summary="Maximum content light-level (cd/m²)"/> | |||
| 1723 | + | </event> | |||
| 1724 | + | ||||
| 1725 | + | <event name="target_max_fall"> | |||
| 1726 | + | <description summary="target maximum frame-average light level"> | |||
| 1727 | + | Provides the targeted max_fall of the image description. max_fall is | |||
| 1728 | + | defined by CTA-861-H. | |||
| 1729 | + | ||||
| 1730 | + | This luminance is only theoretical and may not correspond to the | |||
| 1731 | + | luminance of light emitted on an actual display. | |||
| 1732 | + | </description> | |||
| 1733 | + | ||||
| 1734 | + | <arg name="max_fall" type="uint" | |||
| 1735 | + | summary="Maximum frame-average light level (cd/m²)"/> | |||
| 1736 | + | </event> | |||
| 1737 | + | </interface> | |||
| 1738 | + | ||||
| 1739 | + | <interface name="wp_image_description_reference_v1" version="1" frozen="true"> | |||
| 1740 | + | <description summary="Reference to an image description"> | |||
| 1741 | + | This object is a reference to an image description. This interface is | |||
| 1742 | + | frozen at version 1 to allow other protocols to create | |||
| 1743 | + | wp_image_description_v1 objects. | |||
| 1744 | + | ||||
| 1745 | + | The wp_color_manager_v1.get_image_description request can be used to | |||
| 1746 | + | retrieve the underlying image description. | |||
| 1747 | + | </description> | |||
| 1748 | + | ||||
| 1749 | + | <request name="destroy" type="destructor"> | |||
| 1750 | + | <description summary="destroy the reference"> | |||
| 1751 | + | Destroy this object. This has no effect on the referenced image | |||
| 1752 | + | description. | |||
| 1753 | + | </description> | |||
| 1754 | + | </request> | |||
| 1755 | + | </interface> | |||
| 1756 | + | </protocol> | |||
A spec/xml/colorrepresentation.xml +433 -0
| @@ -0,0 +1,433 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="color_representation_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright 2022 Simon Ser | |||
| 5 | + | Copyright 2022 Red Hat, Inc. | |||
| 6 | + | Copyright 2022 Collabora, Ltd. | |||
| 7 | + | Copyright 2022-2025 Red Hat, Inc. | |||
| 8 | + | ||||
| 9 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 10 | + | copy of this software and associated documentation files (the "Software"), | |||
| 11 | + | to deal in the Software without restriction, including without limitation | |||
| 12 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 13 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 14 | + | Software is furnished to do so, subject to the following conditions: | |||
| 15 | + | ||||
| 16 | + | The above copyright notice and this permission notice (including the next | |||
| 17 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 18 | + | Software. | |||
| 19 | + | ||||
| 20 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 21 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 22 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 23 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 24 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 25 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 26 | + | DEALINGS IN THE SOFTWARE. | |||
| 27 | + | </copyright> | |||
| 28 | + | ||||
| 29 | + | <description summary="color representation protocol extension"> | |||
| 30 | + | This protocol extension delivers the metadata required to define alpha mode, | |||
| 31 | + | the color model, sub-sampling and quantization range used when interpreting | |||
| 32 | + | buffer contents. The main use case is defining how the YCbCr family of pixel | |||
| 33 | + | formats convert to RGB. | |||
| 34 | + | ||||
| 35 | + | Note that this protocol does not define the colorimetry of the resulting RGB | |||
| 36 | + | channels / tristimulus values. Without the help of other extensions the | |||
| 37 | + | resulting colorimetry is therefore implementation defined. | |||
| 38 | + | ||||
| 39 | + | If this extension is not used, the color representation used is compositor | |||
| 40 | + | implementation defined. | |||
| 41 | + | ||||
| 42 | + | Recommendation ITU-T H.273 | |||
| 43 | + | "Coding-independent code points for video signal type identification" | |||
| 44 | + | shall be referred to as simply H.273 here. | |||
| 45 | + | </description> | |||
| 46 | + | ||||
| 47 | + | <interface name="wp_color_representation_manager_v1" version="1"> | |||
| 48 | + | <description summary="color representation manager singleton"> | |||
| 49 | + | A singleton global interface used for getting color representation | |||
| 50 | + | extensions for wl_surface. The extension interfaces allow setting the | |||
| 51 | + | color representation of surfaces. | |||
| 52 | + | ||||
| 53 | + | Compositors should never remove this global. | |||
| 54 | + | </description> | |||
| 55 | + | ||||
| 56 | + | <enum name="error"> | |||
| 57 | + | <description summary="protocol errors"/> | |||
| 58 | + | <entry name="surface_exists" value="1" | |||
| 59 | + | summary="color representation surface exists already"/> | |||
| 60 | + | </enum> | |||
| 61 | + | ||||
| 62 | + | <request name="destroy" type="destructor"> | |||
| 63 | + | <description summary="destroy the manager"> | |||
| 64 | + | Destroy the wp_color_representation_manager_v1 object. This does not | |||
| 65 | + | affect any other objects in any way. | |||
| 66 | + | </description> | |||
| 67 | + | ||||
| 68 | + | </request> | |||
| 69 | + | ||||
| 70 | + | <request name="get_surface"> | |||
| 71 | + | <description summary="create a color representation interface for a wl_surface"> | |||
| 72 | + | If a wp_color_representation_surface_v1 object already exists for the | |||
| 73 | + | given wl_surface, the protocol error surface_exists is raised. | |||
| 74 | + | ||||
| 75 | + | This creates a new color wp_color_representation_surface_v1 object for | |||
| 76 | + | the given wl_surface. | |||
| 77 | + | ||||
| 78 | + | See the wp_color_representation_surface_v1 interface for more details. | |||
| 79 | + | </description> | |||
| 80 | + | <arg name="id" | |||
| 81 | + | type="new_id" interface="wp_color_representation_surface_v1"/> | |||
| 82 | + | <arg name="surface" | |||
| 83 | + | type="object" interface="wl_surface"/> | |||
| 84 | + | </request> | |||
| 85 | + | ||||
| 86 | + | <event name="supported_alpha_mode"> | |||
| 87 | + | <description summary="supported alpha modes"> | |||
| 88 | + | When this object is created, it shall immediately send this event once | |||
| 89 | + | for each alpha mode the compositor supports. | |||
| 90 | + | ||||
| 91 | + | For the definition of the supported values, see the | |||
| 92 | + | wp_color_representation_surface_v1::alpha_mode enum. | |||
| 93 | + | </description> | |||
| 94 | + | <arg name="alpha_mode" | |||
| 95 | + | type="uint" enum="wp_color_representation_surface_v1.alpha_mode" | |||
| 96 | + | summary="supported alpha mode"/> | |||
| 97 | + | </event> | |||
| 98 | + | ||||
| 99 | + | <event name="supported_coefficients_and_ranges"> | |||
| 100 | + | <description summary="supported matrix coefficients and ranges"> | |||
| 101 | + | When this object is created, it shall immediately send this event once | |||
| 102 | + | for each matrix coefficient and color range combination the compositor | |||
| 103 | + | supports. | |||
| 104 | + | ||||
| 105 | + | For the definition of the supported values, see the | |||
| 106 | + | wp_color_representation_surface_v1::coefficients and | |||
| 107 | + | wp_color_representation_surface_v1::range enums. | |||
| 108 | + | </description> | |||
| 109 | + | <arg name="coefficients" | |||
| 110 | + | type="uint" enum="wp_color_representation_surface_v1.coefficients" | |||
| 111 | + | summary="supported matrix coefficients"/> | |||
| 112 | + | <arg name="range" | |||
| 113 | + | type="uint" enum="wp_color_representation_surface_v1.range" | |||
| 114 | + | summary="full range flag"/> | |||
| 115 | + | </event> | |||
| 116 | + | ||||
| 117 | + | <event name="done"> | |||
| 118 | + | <description summary="all features have been sent"> | |||
| 119 | + | This event is sent when all supported features have been sent. | |||
| 120 | + | </description> | |||
| 121 | + | </event> | |||
| 122 | + | </interface> | |||
| 123 | + | ||||
| 124 | + | <interface name="wp_color_representation_surface_v1" version="1"> | |||
| 125 | + | <description summary="color representation extension to a surface"> | |||
| 126 | + | A wp_color_representation_surface_v1 allows the client to set the color | |||
| 127 | + | representation metadata of a surface. | |||
| 128 | + | ||||
| 129 | + | By default, a surface does not have any color representation metadata set. | |||
| 130 | + | The reconstruction of R, G, B signals on such surfaces is compositor | |||
| 131 | + | implementation defined. The alpha mode is assumed to be | |||
| 132 | + | premultiplied_electrical when the alpha mode is unset. | |||
| 133 | + | ||||
| 134 | + | If the wl_surface associated with the wp_color_representation_surface_v1 | |||
| 135 | + | is destroyed, the wp_color_representation_surface_v1 object becomes inert. | |||
| 136 | + | </description> | |||
| 137 | + | ||||
| 138 | + | <enum name="error"> | |||
| 139 | + | <description summary="protocol errors"/> | |||
| 140 | + | <entry name="alpha_mode" value="1" | |||
| 141 | + | summary="unsupported alpha mode"/> | |||
| 142 | + | <entry name="coefficients" value="2" | |||
| 143 | + | summary="unsupported coefficients"/> | |||
| 144 | + | <entry name="pixel_format" value="3" | |||
| 145 | + | summary="the pixel format and a set value are incompatible"/> | |||
| 146 | + | <entry name="inert" value="4" | |||
| 147 | + | summary="forbidden request on inert object"/> | |||
| 148 | + | <entry name="chroma_location" value="5" | |||
| 149 | + | summary="invalid chroma location"/> | |||
| 150 | + | </enum> | |||
| 151 | + | ||||
| 152 | + | <request name="destroy" type="destructor"> | |||
| 153 | + | <description summary="destroy the color representation"> | |||
| 154 | + | Destroy the wp_color_representation_surface_v1 object. | |||
| 155 | + | ||||
| 156 | + | Destroying this object unsets all the color representation metadata from | |||
| 157 | + | the surface. See the wp_color_representation_surface_v1 interface | |||
| 158 | + | description for how a compositor handles a surface without color | |||
| 159 | + | representation metadata. Unsetting is double-buffered state, see | |||
| 160 | + | wl_surface.commit. | |||
| 161 | + | </description> | |||
| 162 | + | </request> | |||
| 163 | + | ||||
| 164 | + | <enum name="alpha_mode"> | |||
| 165 | + | <description summary="alpha mode"> | |||
| 166 | + | Specifies how the alpha channel affects the color channels. | |||
| 167 | + | </description> | |||
| 168 | + | <entry name="premultiplied_electrical" value="0"> | |||
| 169 | + | <description summary="premultiplied alpha in electrical values"> | |||
| 170 | + | Electrical color channel values (after transfer function encoding) | |||
| 171 | + | are already multiplied with the alpha channel value. | |||
| 172 | + | </description> | |||
| 173 | + | </entry> | |||
| 174 | + | <entry name="premultiplied_optical" value="1"> | |||
| 175 | + | <description summary="premultiplied alpha in optical values"> | |||
| 176 | + | Optical color channel values (before transfer function encoding) | |||
| 177 | + | are already multiplied with the alpha channel value. | |||
| 178 | + | </description> | |||
| 179 | + | </entry> | |||
| 180 | + | <entry name="straight" value="2"> | |||
| 181 | + | <description summary="straight alpha"> | |||
| 182 | + | Alpha channel has not been pre-multiplied into color channels. | |||
| 183 | + | </description> | |||
| 184 | + | </entry> | |||
| 185 | + | </enum> | |||
| 186 | + | ||||
| 187 | + | <enum name="coefficients"> | |||
| 188 | + | <description summary="named coefficients"> | |||
| 189 | + | Named matrix coefficients used to encode well-known sets of | |||
| 190 | + | coefficients. H.273 is the authority, when it comes to the exact values | |||
| 191 | + | of coefficients and authoritative specifications, where an equivalent | |||
| 192 | + | code point exists. | |||
| 193 | + | ||||
| 194 | + | A value of 0 is invalid and will never be present in the list of enums. | |||
| 195 | + | ||||
| 196 | + | Descriptions do list the specifications for convenience. | |||
| 197 | + | </description> | |||
| 198 | + | <entry name="identity" value="1"> | |||
| 199 | + | <description summary="The identity matrix"> | |||
| 200 | + | Coefficients as defined by | |||
| 201 | + | - IEC 61966-2-1 sRGB | |||
| 202 | + | - SMPTE ST 428-1 (2019) | |||
| 203 | + | ||||
| 204 | + | Equivalent to H.273 MatrixCoefficients code point 0. | |||
| 205 | + | Compatible with pixel formats of the RGB family. | |||
| 206 | + | </description> | |||
| 207 | + | </entry> | |||
| 208 | + | <entry name="bt709" value="2"> | |||
| 209 | + | <description summary="BT.709 matrix coefficients"> | |||
| 210 | + | Coefficients as defined by | |||
| 211 | + | - Rec. ITU-R BT.709-6 | |||
| 212 | + | - Rec. ITU-R BT.1361-0 conventional colour gamut system (historical) | |||
| 213 | + | - Rec. ITU-R BT.1361-0 conventional colour gamut system and extended | |||
| 214 | + | colour gamut system (historical) | |||
| 215 | + | - IEC 61966-2-4 xvYCC709 | |||
| 216 | + | - SMPTE RP 177 (1993) Annex B | |||
| 217 | + | ||||
| 218 | + | Equivalent to H.273 MatrixCoefficients code point 1. | |||
| 219 | + | Compatible with pixel formats of the YCbCr family. | |||
| 220 | + | </description> | |||
| 221 | + | </entry> | |||
| 222 | + | <entry name="fcc" value="3"> | |||
| 223 | + | <description summary="FCC matrix coefficients"> | |||
| 224 | + | Coefficients as defined by | |||
| 225 | + | - United States Federal Communications Commission (2003) Title 47 | |||
| 226 | + | Code of Federal Regulations 73.682 (a) (20) | |||
| 227 | + | ||||
| 228 | + | Equivalent to H.273 MatrixCoefficients code point 4. | |||
| 229 | + | Compatible with pixel formats of the YCbCr family. | |||
| 230 | + | </description> | |||
| 231 | + | </entry> | |||
| 232 | + | <entry name="bt601" value="4"> | |||
| 233 | + | <description summary="BT.601-7 matrix coefficients"> | |||
| 234 | + | Coefficients as defined by | |||
| 235 | + | - Rec. ITU-R BT.470-6 System B, G (historical) | |||
| 236 | + | - Rec. ITU-R BT.601-7 625 | |||
| 237 | + | - Rec. ITU-R BT.601-7 525 | |||
| 238 | + | - Rec. ITU-R BT.1358-0 625 (historical) | |||
| 239 | + | - Rec. ITU-R BT.1358-1 525 or 625 (historical) | |||
| 240 | + | - Rec. ITU-R BT.1700-0 625 PAL and 625 SECAM | |||
| 241 | + | - Rec. ITU-R BT.1700-0 NTSC | |||
| 242 | + | - IEC 61966-2-1 sYCC | |||
| 243 | + | - IEC 61966-2-4 xvYCC601 | |||
| 244 | + | - SMPTE ST 170 (2004) | |||
| 245 | + | ||||
| 246 | + | Equivalent to H.273 MatrixCoefficients code point 5, 6. | |||
| 247 | + | Compatible with pixel formats of the YCbCr family. | |||
| 248 | + | </description> | |||
| 249 | + | </entry> | |||
| 250 | + | <entry name="smpte240" value="5"> | |||
| 251 | + | <description summary="SMPTE ST 240 matrix coefficients"> | |||
| 252 | + | Coefficients as defined by | |||
| 253 | + | - SMPTE ST 240 (1999) | |||
| 254 | + | ||||
| 255 | + | Equivalent to H.273 MatrixCoefficients code point 7. | |||
| 256 | + | Compatible with pixel formats of the YCbCr family. | |||
| 257 | + | </description> | |||
| 258 | + | </entry> | |||
| 259 | + | <entry name="bt2020" value="6"> | |||
| 260 | + | <description summary="BT.2020 and BT.2100 YCbCr matrix coefficients"> | |||
| 261 | + | Coefficients as defined by | |||
| 262 | + | - Rec. ITU-R BT.2020-2 (non-constant luminance) | |||
| 263 | + | - Rec. ITU-R BT.2100-2 Y′CbCr | |||
| 264 | + | ||||
| 265 | + | Equivalent to H.273 MatrixCoefficients code point 9. | |||
| 266 | + | Compatible with pixel formats of the YCbCr family. | |||
| 267 | + | </description> | |||
| 268 | + | </entry> | |||
| 269 | + | <entry name="bt2020_cl" value="7"> | |||
| 270 | + | <description summary="BT.2020 matrix coefficients for constant luminance"> | |||
| 271 | + | Coefficients as defined by | |||
| 272 | + | - Rec. ITU-R BT.2020-2 (constant luminance) | |||
| 273 | + | ||||
| 274 | + | Equivalent to H.273 MatrixCoefficients code point 10. | |||
| 275 | + | Compatible with pixel formats of the YCbCr family. | |||
| 276 | + | </description> | |||
| 277 | + | </entry> | |||
| 278 | + | <entry name="ictcp" value="8"> | |||
| 279 | + | <description summary="BT.2100 ICtCp matrix coefficients"> | |||
| 280 | + | Coefficients as defined by | |||
| 281 | + | - Rec. ITU-R BT.2100-2 ICTCP | |||
| 282 | + | ||||
| 283 | + | Equivalent to H.273 MatrixCoefficients code point 14. | |||
| 284 | + | Compatible with pixel formats of the YCbCr family. | |||
| 285 | + | </description> | |||
| 286 | + | </entry> | |||
| 287 | + | </enum> | |||
| 288 | + | ||||
| 289 | + | <enum name="range"> | |||
| 290 | + | <description summary="Color range values"> | |||
| 291 | + | Possible color range values. | |||
| 292 | + | ||||
| 293 | + | A value of 0 is invalid and will never be present in the list of enums. | |||
| 294 | + | </description> | |||
| 295 | + | <entry name="full" value="1" summary="Full color range"/> | |||
| 296 | + | <entry name="limited" value="2" summary="Limited color range"/> | |||
| 297 | + | </enum> | |||
| 298 | + | ||||
| 299 | + | <enum name="chroma_location"> | |||
| 300 | + | <description summary="Chroma sample location for 4:2:0 YCbCr"> | |||
| 301 | + | Chroma sample location as defined by H.273 Chroma420SampleLocType. | |||
| 302 | + | ||||
| 303 | + | A value of 0 is invalid and will never be present in the list of enums. | |||
| 304 | + | ||||
| 305 | + | The descriptions list the matching Vulkan VkChromaLocation combinations | |||
| 306 | + | for convenience. | |||
| 307 | + | </description> | |||
| 308 | + | <entry name="type_0" value="1"> | |||
| 309 | + | <description summary="Horizontal offset of 0, vertical offset of 0.5"> | |||
| 310 | + | Corresponding to VkChromaLocations: | |||
| 311 | + | - xChromaOffset: VK_CHROMA_LOCATION_COSITED_EVEN | |||
| 312 | + | - yChromaOffset: VK_CHROMA_LOCATION_MIDPOINT | |||
| 313 | + | ||||
| 314 | + | Equivalent to H.273 Chroma420SampleLocType 0. | |||
| 315 | + | </description> | |||
| 316 | + | </entry> | |||
| 317 | + | <entry name="type_1" value="2"> | |||
| 318 | + | <description summary="Horizontal offset of 0.5, vertical offset of 0.5"> | |||
| 319 | + | Corresponding to VkChromaLocations: | |||
| 320 | + | - xChromaOffset: VK_CHROMA_LOCATION_MIDPOINT | |||
| 321 | + | - yChromaOffset: VK_CHROMA_LOCATION_MIDPOINT | |||
| 322 | + | ||||
| 323 | + | Equivalent to H.273 Chroma420SampleLocType 1. | |||
| 324 | + | </description> | |||
| 325 | + | </entry> | |||
| 326 | + | <entry name="type_2" value="3"> | |||
| 327 | + | <description summary="Horizontal offset of 0, vertical offset of 0"> | |||
| 328 | + | Corresponding to VkChromaLocations: | |||
| 329 | + | - xChromaOffset: VK_CHROMA_LOCATION_COSITED_EVEN | |||
| 330 | + | - yChromaOffset: VK_CHROMA_LOCATION_COSITED_EVEN | |||
| 331 | + | ||||
| 332 | + | Equivalent to H.273 Chroma420SampleLocType 2. | |||
| 333 | + | </description> | |||
| 334 | + | </entry> | |||
| 335 | + | <entry name="type_3" value="4"> | |||
| 336 | + | <description summary="Horizontal offset of 0.5, vertical offset of 0"> | |||
| 337 | + | Corresponding to VkChromaLocations: | |||
| 338 | + | - xChromaOffset: VK_CHROMA_LOCATION_MIDPOINT | |||
| 339 | + | - yChromaOffset: VK_CHROMA_LOCATION_COSITED_EVEN | |||
| 340 | + | ||||
| 341 | + | Equivalent to H.273 Chroma420SampleLocType 3. | |||
| 342 | + | </description> | |||
| 343 | + | </entry> | |||
| 344 | + | <entry name="type_4" value="5"> | |||
| 345 | + | <description summary="Horizontal offset of 0, vertical offset of 1"> | |||
| 346 | + | Equivalent to H.273 Chroma420SampleLocType 4. | |||
| 347 | + | </description> | |||
| 348 | + | </entry> | |||
| 349 | + | <entry name="type_5" value="6"> | |||
| 350 | + | <description summary="Horizontal offset of 0.5, vertical offset of 1"> | |||
| 351 | + | Equivalent to H.273 Chroma420SampleLocType 5. | |||
| 352 | + | </description> | |||
| 353 | + | </entry> | |||
| 354 | + | </enum> | |||
| 355 | + | ||||
| 356 | + | <request name="set_alpha_mode"> | |||
| 357 | + | <description summary="set the surface alpha mode"> | |||
| 358 | + | If this protocol object is inert, the protocol error inert is raised. | |||
| 359 | + | ||||
| 360 | + | Assuming an alpha channel exists, it is always linear. The alpha mode | |||
| 361 | + | determines whether and how the color channels include pre-multiplied | |||
| 362 | + | alpha. Using straight alpha might have performance benefits. | |||
| 363 | + | ||||
| 364 | + | Only alpha modes advertised by the compositor are allowed to be used as | |||
| 365 | + | argument for this request. The "alpha_mode" protocol error is raised | |||
| 366 | + | otherwise. | |||
| 367 | + | ||||
| 368 | + | Alpha mode is double buffered, see wl_surface.commit. | |||
| 369 | + | </description> | |||
| 370 | + | <arg name="alpha_mode" type="uint" enum="alpha_mode" | |||
| 371 | + | summary="alpha mode"/> | |||
| 372 | + | </request> | |||
| 373 | + | ||||
| 374 | + | <request name="set_coefficients_and_range"> | |||
| 375 | + | <description summary="set the matrix coefficients and range"> | |||
| 376 | + | If this protocol object is inert, the protocol error inert is raised. | |||
| 377 | + | ||||
| 378 | + | Set the matrix coefficients and video range which defines the formula | |||
| 379 | + | and the related constants used to derive red, green and blue signals. | |||
| 380 | + | Usually coefficients correspond to MatrixCoefficients code points in | |||
| 381 | + | H.273. | |||
| 382 | + | ||||
| 383 | + | Only combinations advertised by the compositor are allowed to be used as | |||
| 384 | + | argument for this request. The "coefficients" protocol error is raised | |||
| 385 | + | otherwise. | |||
| 386 | + | ||||
| 387 | + | A call to wl_surface.commit verifies that the pixel format and the | |||
| 388 | + | coefficients-range combination in the committed surface contents are | |||
| 389 | + | compatible, if contents exist. The "pixel_format" protocol error is | |||
| 390 | + | raised otherwise. | |||
| 391 | + | ||||
| 392 | + | A pixel format is compatible with the coefficients-range combination if | |||
| 393 | + | the related equations and conventions as defined in H.273 can produce | |||
| 394 | + | the color channels (RGB or YCbCr) of the pixel format. | |||
| 395 | + | ||||
| 396 | + | For the definition of the supported combination, see the | |||
| 397 | + | wp_color_representation_surface_v1::coefficients and | |||
| 398 | + | wp_color_representation_surface_v1::range enums. | |||
| 399 | + | ||||
| 400 | + | The coefficients-range combination is double-buffered, see | |||
| 401 | + | wl_surface.commit. | |||
| 402 | + | </description> | |||
| 403 | + | <arg name="coefficients" type="uint" enum="coefficients" | |||
| 404 | + | summary="matrix coefficients"/> | |||
| 405 | + | <arg name="range" type="uint" enum="range" | |||
| 406 | + | summary="range"/> | |||
| 407 | + | </request> | |||
| 408 | + | ||||
| 409 | + | <request name="set_chroma_location"> | |||
| 410 | + | <description summary="set the chroma location"> | |||
| 411 | + | If this protocol object is inert, the protocol error inert is raised. | |||
| 412 | + | ||||
| 413 | + | Set the chroma location type which defines the position of downsampled | |||
| 414 | + | chroma samples, corresponding to Chroma420SampleLocType code points in | |||
| 415 | + | H.273. | |||
| 416 | + | ||||
| 417 | + | An invalid chroma location enum value raises the "chroma_location" | |||
| 418 | + | protocol error. | |||
| 419 | + | ||||
| 420 | + | A call to wl_surface.commit verifies that the pixel format and chroma | |||
| 421 | + | location type in the committed surface contents are compatible, if | |||
| 422 | + | contents exist. The "pixel_format" protocol error is raised otherwise. | |||
| 423 | + | ||||
| 424 | + | For the definition of the supported chroma location types, see the | |||
| 425 | + | wp_color_representation_surface_v1::chroma_location enum. | |||
| 426 | + | ||||
| 427 | + | The chroma location type is double-buffered, see wl_surface.commit. | |||
| 428 | + | </description> | |||
| 429 | + | <arg name="chroma_location" type="uint" enum="chroma_location" | |||
| 430 | + | summary="chroma sample location"/> | |||
| 431 | + | </request> | |||
| 432 | + | </interface> | |||
| 433 | + | </protocol> | |||
A spec/xml/committiming.xml +124 -0
| @@ -0,0 +1,124 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="commit_timing_v1"> | |||
| 3 | + | ||||
| 4 | + | <copyright> | |||
| 5 | + | Copyright © 2023 Valve Corporation | |||
| 6 | + | ||||
| 7 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 8 | + | copy of this software and associated documentation files (the "Software"), | |||
| 9 | + | to deal in the Software without restriction, including without limitation | |||
| 10 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 11 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 12 | + | Software is furnished to do so, subject to the following conditions: | |||
| 13 | + | ||||
| 14 | + | The above copyright notice and this permission notice (including the next | |||
| 15 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 16 | + | Software. | |||
| 17 | + | ||||
| 18 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 19 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 20 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 21 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 22 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 23 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 24 | + | DEALINGS IN THE SOFTWARE. | |||
| 25 | + | </copyright> | |||
| 26 | + | ||||
| 27 | + | <interface name="wp_commit_timing_manager_v1" version="1"> | |||
| 28 | + | <description summary="commit timing"> | |||
| 29 | + | When a compositor latches on to new content updates it will check for | |||
| 30 | + | any number of requirements of the available content updates (such as | |||
| 31 | + | fences of all buffers being signalled) to consider the update ready. | |||
| 32 | + | ||||
| 33 | + | This protocol provides a method for adding a time constraint to surface | |||
| 34 | + | content. This constraint indicates to the compositor that a content | |||
| 35 | + | update should be presented as closely as possible to, but not before, | |||
| 36 | + | a specified time. | |||
| 37 | + | ||||
| 38 | + | This protocol does not change the Wayland property that content | |||
| 39 | + | updates are applied in the order they are received, even when some | |||
| 40 | + | content updates contain timestamps and others do not. | |||
| 41 | + | ||||
| 42 | + | To provide timestamps, this global factory interface must be used to | |||
| 43 | + | acquire a wp_commit_timing_v1 object for a surface, which may then be | |||
| 44 | + | used to provide timestamp information for commits. | |||
| 45 | + | ||||
| 46 | + | Warning! The protocol described in this file is currently in the testing | |||
| 47 | + | phase. Backward compatible changes may be added together with the | |||
| 48 | + | corresponding interface version bump. Backward incompatible changes can | |||
| 49 | + | only be done by creating a new major version of the extension. | |||
| 50 | + | </description> | |||
| 51 | + | <enum name="error"> | |||
| 52 | + | <entry name="commit_timer_exists" value="0" | |||
| 53 | + | summary="commit timer already exists for surface"/> | |||
| 54 | + | </enum> | |||
| 55 | + | ||||
| 56 | + | <request name="destroy" type="destructor"> | |||
| 57 | + | <description summary="unbind from the commit timing interface"> | |||
| 58 | + | Informs the server that the client will no longer be using | |||
| 59 | + | this protocol object. Existing objects created by this object | |||
| 60 | + | are not affected. | |||
| 61 | + | </description> | |||
| 62 | + | </request> | |||
| 63 | + | ||||
| 64 | + | <request name="get_timer"> | |||
| 65 | + | <description summary="request commit timer interface for surface"> | |||
| 66 | + | Establish a timing controller for a surface. | |||
| 67 | + | ||||
| 68 | + | Only one commit timer can be created for a surface, or a | |||
| 69 | + | commit_timer_exists protocol error will be generated. | |||
| 70 | + | </description> | |||
| 71 | + | <arg name="id" type="new_id" interface="wp_commit_timer_v1"/> | |||
| 72 | + | <arg name="surface" type="object" interface="wl_surface"/> | |||
| 73 | + | </request> | |||
| 74 | + | </interface> | |||
| 75 | + | ||||
| 76 | + | <interface name="wp_commit_timer_v1" version="1"> | |||
| 77 | + | <description summary="Surface commit timer"> | |||
| 78 | + | An object to set a time constraint for a content update on a surface. | |||
| 79 | + | </description> | |||
| 80 | + | ||||
| 81 | + | <enum name="error"> | |||
| 82 | + | <entry name="invalid_timestamp" value="0" | |||
| 83 | + | summary="timestamp contains an invalid value"/> | |||
| 84 | + | <entry name="timestamp_exists" value="1" | |||
| 85 | + | summary="timestamp exists"/> | |||
| 86 | + | <entry name="surface_destroyed" value="2" | |||
| 87 | + | summary="the associated surface no longer exists"/> | |||
| 88 | + | </enum> | |||
| 89 | + | ||||
| 90 | + | <request name="set_timestamp"> | |||
| 91 | + | <description summary="Specify time the following commit takes effect"> | |||
| 92 | + | Provide a timing constraint for a surface content update. | |||
| 93 | + | ||||
| 94 | + | A set_timestamp request may be made before a wl_surface.commit to | |||
| 95 | + | tell the compositor that the content is intended to be presented | |||
| 96 | + | as closely as possible to, but not before, the specified time. | |||
| 97 | + | The time is in the domain of the compositor's presentation clock. | |||
| 98 | + | ||||
| 99 | + | An invalid_timestamp error will be generated for invalid tv_nsec. | |||
| 100 | + | ||||
| 101 | + | If a timestamp already exists on the surface, a timestamp_exists | |||
| 102 | + | error is generated. | |||
| 103 | + | ||||
| 104 | + | Requesting set_timestamp after the commit_timer object's surface is | |||
| 105 | + | destroyed will generate a "surface_destroyed" error. | |||
| 106 | + | </description> | |||
| 107 | + | <arg name="tv_sec_hi" type="uint" | |||
| 108 | + | summary="high 32 bits of the seconds part of target time"/> | |||
| 109 | + | <arg name="tv_sec_lo" type="uint" | |||
| 110 | + | summary="low 32 bits of the seconds part of target time"/> | |||
| 111 | + | <arg name="tv_nsec" type="uint" | |||
| 112 | + | summary="nanoseconds part of target time"/> | |||
| 113 | + | </request> | |||
| 114 | + | ||||
| 115 | + | <request name="destroy" type="destructor"> | |||
| 116 | + | <description summary="Destroy the timer"> | |||
| 117 | + | Informs the server that the client will no longer be using | |||
| 118 | + | this protocol object. | |||
| 119 | + | ||||
| 120 | + | Existing timing constraints are not affected by the destruction. | |||
| 121 | + | </description> | |||
| 122 | + | </request> | |||
| 123 | + | </interface> | |||
| 124 | + | </protocol> | |||
A spec/xml/contenttype.xml +128 -0
| @@ -0,0 +1,128 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="content_type_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2021 Emmanuel Gil Peyrot | |||
| 5 | + | Copyright © 2022 Xaver Hugl | |||
| 6 | + | ||||
| 7 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 8 | + | copy of this software and associated documentation files (the "Software"), | |||
| 9 | + | to deal in the Software without restriction, including without limitation | |||
| 10 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 11 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 12 | + | Software is furnished to do so, subject to the following conditions: | |||
| 13 | + | ||||
| 14 | + | The above copyright notice and this permission notice (including the next | |||
| 15 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 16 | + | Software. | |||
| 17 | + | ||||
| 18 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 19 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 20 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 21 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 22 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 23 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 24 | + | DEALINGS IN THE SOFTWARE. | |||
| 25 | + | </copyright> | |||
| 26 | + | ||||
| 27 | + | <interface name="wp_content_type_manager_v1" version="1"> | |||
| 28 | + | <description summary="surface content type manager"> | |||
| 29 | + | This interface allows a client to describe the kind of content a surface | |||
| 30 | + | will display, to allow the compositor to optimize its behavior for it. | |||
| 31 | + | ||||
| 32 | + | Warning! The protocol described in this file is currently in the testing | |||
| 33 | + | phase. Backward compatible changes may be added together with the | |||
| 34 | + | corresponding interface version bump. Backward incompatible changes can | |||
| 35 | + | only be done by creating a new major version of the extension. | |||
| 36 | + | </description> | |||
| 37 | + | ||||
| 38 | + | <request name="destroy" type="destructor"> | |||
| 39 | + | <description summary="destroy the content type manager object"> | |||
| 40 | + | Destroy the content type manager. This doesn't destroy objects created | |||
| 41 | + | with the manager. | |||
| 42 | + | </description> | |||
| 43 | + | </request> | |||
| 44 | + | ||||
| 45 | + | <enum name="error"> | |||
| 46 | + | <entry name="already_constructed" value="0" | |||
| 47 | + | summary="wl_surface already has a content type object"/> | |||
| 48 | + | </enum> | |||
| 49 | + | ||||
| 50 | + | <request name="get_surface_content_type"> | |||
| 51 | + | <description summary="create a new content type object"> | |||
| 52 | + | Create a new content type object associated with the given surface. | |||
| 53 | + | ||||
| 54 | + | Creating a wp_content_type_v1 from a wl_surface which already has one | |||
| 55 | + | attached is a client error: already_constructed. | |||
| 56 | + | </description> | |||
| 57 | + | <arg name="id" type="new_id" interface="wp_content_type_v1"/> | |||
| 58 | + | <arg name="surface" type="object" interface="wl_surface"/> | |||
| 59 | + | </request> | |||
| 60 | + | </interface> | |||
| 61 | + | ||||
| 62 | + | <interface name="wp_content_type_v1" version="1"> | |||
| 63 | + | <description summary="content type object for a surface"> | |||
| 64 | + | The content type object allows the compositor to optimize for the kind | |||
| 65 | + | of content shown on the surface. A compositor may for example use it to | |||
| 66 | + | set relevant drm properties like "content type". | |||
| 67 | + | ||||
| 68 | + | The client may request to switch to another content type at any time. | |||
| 69 | + | When the associated surface gets destroyed, this object becomes inert and | |||
| 70 | + | the client should destroy it. | |||
| 71 | + | </description> | |||
| 72 | + | ||||
| 73 | + | <request name="destroy" type="destructor"> | |||
| 74 | + | <description summary="destroy the content type object"> | |||
| 75 | + | Switch back to not specifying the content type of this surface. This is | |||
| 76 | + | equivalent to setting the content type to none, including double | |||
| 77 | + | buffering semantics. See set_content_type for details. | |||
| 78 | + | </description> | |||
| 79 | + | </request> | |||
| 80 | + | ||||
| 81 | + | <enum name="type"> | |||
| 82 | + | <description summary="possible content types"> | |||
| 83 | + | These values describe the available content types for a surface. | |||
| 84 | + | </description> | |||
| 85 | + | <entry name="none" value="0"> | |||
| 86 | + | <description summary="no content type applies"> | |||
| 87 | + | The content type none means that either the application has no data | |||
| 88 | + | about the content type, or that the content doesn't fit into one of | |||
| 89 | + | the other categories. | |||
| 90 | + | </description> | |||
| 91 | + | </entry> | |||
| 92 | + | <entry name="photo" value="1"> | |||
| 93 | + | <description summary="photo content type"> | |||
| 94 | + | The content type photo describes content derived from digital still | |||
| 95 | + | pictures and may be presented with minimal processing. | |||
| 96 | + | </description> | |||
| 97 | + | </entry> | |||
| 98 | + | <entry name="video" value="2"> | |||
| 99 | + | <description summary="video content type"> | |||
| 100 | + | The content type video describes a video or animation and may be | |||
| 101 | + | presented with more accurate timing to avoid stutter. Where scaling | |||
| 102 | + | is needed, scaling methods more appropriate for video may be used. | |||
| 103 | + | </description> | |||
| 104 | + | </entry> | |||
| 105 | + | <entry name="game" value="3"> | |||
| 106 | + | <description summary="game content type"> | |||
| 107 | + | The content type game describes a running game. Its content may be | |||
| 108 | + | presented with reduced latency. | |||
| 109 | + | </description> | |||
| 110 | + | </entry> | |||
| 111 | + | </enum> | |||
| 112 | + | ||||
| 113 | + | <request name="set_content_type"> | |||
| 114 | + | <description summary="specify the content type"> | |||
| 115 | + | Set the surface content type. This informs the compositor that the | |||
| 116 | + | client believes it is displaying buffers matching this content type. | |||
| 117 | + | ||||
| 118 | + | This is purely a hint for the compositor, which can be used to adjust | |||
| 119 | + | its behavior or hardware settings to fit the presented content best. | |||
| 120 | + | ||||
| 121 | + | The content type is double-buffered state, see wl_surface.commit for | |||
| 122 | + | details. | |||
| 123 | + | </description> | |||
| 124 | + | <arg name="content_type" type="uint" enum="type" | |||
| 125 | + | summary="the content type"/> | |||
| 126 | + | </request> | |||
| 127 | + | </interface> | |||
| 128 | + | </protocol> | |||
A spec/xml/cursorshape.xml +162 -0
| @@ -0,0 +1,162 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="cursor_shape_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright 2018 The Chromium Authors | |||
| 5 | + | Copyright 2023 Simon Ser | |||
| 6 | + | ||||
| 7 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 8 | + | copy of this software and associated documentation files (the "Software"), | |||
| 9 | + | to deal in the Software without restriction, including without limitation | |||
| 10 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 11 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 12 | + | Software is furnished to do so, subject to the following conditions: | |||
| 13 | + | The above copyright notice and this permission notice (including the next | |||
| 14 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 15 | + | Software. | |||
| 16 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 17 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 18 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 19 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 20 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 21 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 22 | + | DEALINGS IN THE SOFTWARE. | |||
| 23 | + | </copyright> | |||
| 24 | + | ||||
| 25 | + | <interface name="wp_cursor_shape_manager_v1" version="2"> | |||
| 26 | + | <description summary="cursor shape manager"> | |||
| 27 | + | This global offers an alternative, optional way to set cursor images. This | |||
| 28 | + | new way uses enumerated cursors instead of a wl_surface like | |||
| 29 | + | wl_pointer.set_cursor does. | |||
| 30 | + | ||||
| 31 | + | Warning! The protocol described in this file is currently in the testing | |||
| 32 | + | phase. Backward compatible changes may be added together with the | |||
| 33 | + | corresponding interface version bump. Backward incompatible changes can | |||
| 34 | + | only be done by creating a new major version of the extension. | |||
| 35 | + | </description> | |||
| 36 | + | ||||
| 37 | + | <request name="destroy" type="destructor"> | |||
| 38 | + | <description summary="destroy the manager"> | |||
| 39 | + | Destroy the cursor shape manager. | |||
| 40 | + | </description> | |||
| 41 | + | </request> | |||
| 42 | + | ||||
| 43 | + | <request name="get_pointer"> | |||
| 44 | + | <description summary="manage the cursor shape of a pointer device"> | |||
| 45 | + | Obtain a wp_cursor_shape_device_v1 for a wl_pointer object. | |||
| 46 | + | ||||
| 47 | + | When the pointer capability is removed from the wl_seat, the | |||
| 48 | + | wp_cursor_shape_device_v1 object becomes inert. | |||
| 49 | + | </description> | |||
| 50 | + | <arg name="cursor_shape_device" type="new_id" interface="wp_cursor_shape_device_v1"/> | |||
| 51 | + | <arg name="pointer" type="object" interface="wl_pointer"/> | |||
| 52 | + | </request> | |||
| 53 | + | ||||
| 54 | + | <request name="get_tablet_tool_v2"> | |||
| 55 | + | <description summary="manage the cursor shape of a tablet tool device"> | |||
| 56 | + | Obtain a wp_cursor_shape_device_v1 for a zwp_tablet_tool_v2 object. | |||
| 57 | + | ||||
| 58 | + | When the zwp_tablet_tool_v2 is removed, the wp_cursor_shape_device_v1 | |||
| 59 | + | object becomes inert. | |||
| 60 | + | </description> | |||
| 61 | + | <arg name="cursor_shape_device" type="new_id" interface="wp_cursor_shape_device_v1"/> | |||
| 62 | + | <arg name="tablet_tool" type="object" interface="zwp_tablet_tool_v2"/> | |||
| 63 | + | </request> | |||
| 64 | + | </interface> | |||
| 65 | + | ||||
| 66 | + | <interface name="wp_cursor_shape_device_v1" version="2"> | |||
| 67 | + | <description summary="cursor shape for a device"> | |||
| 68 | + | This interface allows clients to set the cursor shape. | |||
| 69 | + | </description> | |||
| 70 | + | ||||
| 71 | + | <enum name="shape"> | |||
| 72 | + | <description summary="cursor shapes"> | |||
| 73 | + | This enum describes cursor shapes. | |||
| 74 | + | ||||
| 75 | + | The names are taken from the CSS W3C specification: | |||
| 76 | + | https://w3c.github.io/csswg-drafts/css-ui/#cursor | |||
| 77 | + | with a few additions. | |||
| 78 | + | ||||
| 79 | + | Note that there are some groups of cursor shapes that are related: | |||
| 80 | + | The first group is drag-and-drop cursors which are used to indicate | |||
| 81 | + | the selected action during dnd operations. The second group is resize | |||
| 82 | + | cursors which are used to indicate resizing and moving possibilities | |||
| 83 | + | on window borders. It is recommended that the shapes in these groups | |||
| 84 | + | should use visually compatible images and metaphors. | |||
| 85 | + | </description> | |||
| 86 | + | <entry name="default" value="1" summary="default cursor"/> | |||
| 87 | + | <entry name="context_menu" value="2" summary="a context menu is available for the object under the cursor"/> | |||
| 88 | + | <entry name="help" value="3" summary="help is available for the object under the cursor"/> | |||
| 89 | + | <entry name="pointer" value="4" summary="pointer that indicates a link or another interactive element"/> | |||
| 90 | + | <entry name="progress" value="5" summary="progress indicator"/> | |||
| 91 | + | <entry name="wait" value="6" summary="program is busy, user should wait"/> | |||
| 92 | + | <entry name="cell" value="7" summary="a cell or set of cells may be selected"/> | |||
| 93 | + | <entry name="crosshair" value="8" summary="simple crosshair"/> | |||
| 94 | + | <entry name="text" value="9" summary="text may be selected"/> | |||
| 95 | + | <entry name="vertical_text" value="10" summary="vertical text may be selected"/> | |||
| 96 | + | <entry name="alias" value="11" summary="drag-and-drop: alias of/shortcut to something is to be created"/> | |||
| 97 | + | <entry name="copy" value="12" summary="drag-and-drop: something is to be copied"/> | |||
| 98 | + | <entry name="move" value="13" summary="drag-and-drop: something is to be moved"/> | |||
| 99 | + | <entry name="no_drop" value="14" summary="drag-and-drop: the dragged item cannot be dropped at the current cursor location"/> | |||
| 100 | + | <entry name="not_allowed" value="15" summary="drag-and-drop: the requested action will not be carried out"/> | |||
| 101 | + | <entry name="grab" value="16" summary="drag-and-drop: something can be grabbed"/> | |||
| 102 | + | <entry name="grabbing" value="17" summary="drag-and-drop: something is being grabbed"/> | |||
| 103 | + | <entry name="e_resize" value="18" summary="resizing: the east border is to be moved"/> | |||
| 104 | + | <entry name="n_resize" value="19" summary="resizing: the north border is to be moved"/> | |||
| 105 | + | <entry name="ne_resize" value="20" summary="resizing: the north-east corner is to be moved"/> | |||
| 106 | + | <entry name="nw_resize" value="21" summary="resizing: the north-west corner is to be moved"/> | |||
| 107 | + | <entry name="s_resize" value="22" summary="resizing: the south border is to be moved"/> | |||
| 108 | + | <entry name="se_resize" value="23" summary="resizing: the south-east corner is to be moved"/> | |||
| 109 | + | <entry name="sw_resize" value="24" summary="resizing: the south-west corner is to be moved"/> | |||
| 110 | + | <entry name="w_resize" value="25" summary="resizing: the west border is to be moved"/> | |||
| 111 | + | <entry name="ew_resize" value="26" summary="resizing: the east and west borders are to be moved"/> | |||
| 112 | + | <entry name="ns_resize" value="27" summary="resizing: the north and south borders are to be moved"/> | |||
| 113 | + | <entry name="nesw_resize" value="28" summary="resizing: the north-east and south-west corners are to be moved"/> | |||
| 114 | + | <entry name="nwse_resize" value="29" summary="resizing: the north-west and south-east corners are to be moved"/> | |||
| 115 | + | <entry name="col_resize" value="30" summary="resizing: that the item/column can be resized horizontally"/> | |||
| 116 | + | <entry name="row_resize" value="31" summary="resizing: that the item/row can be resized vertically"/> | |||
| 117 | + | <entry name="all_scroll" value="32" summary="something can be scrolled in any direction"/> | |||
| 118 | + | <entry name="zoom_in" value="33" summary="something can be zoomed in"/> | |||
| 119 | + | <entry name="zoom_out" value="34" summary="something can be zoomed out"/> | |||
| 120 | + | <entry name="dnd_ask" value="35" summary="drag-and-drop: the user will select which action will be carried out (non-css value)" since="2"/> | |||
| 121 | + | <entry name="all_resize" value="36" summary="resizing: something can be moved or resized in any direction (non-css value)" since="2"/> | |||
| 122 | + | </enum> | |||
| 123 | + | ||||
| 124 | + | <enum name="error"> | |||
| 125 | + | <entry name="invalid_shape" value="1" | |||
| 126 | + | summary="the specified shape value is invalid"/> | |||
| 127 | + | </enum> | |||
| 128 | + | ||||
| 129 | + | <request name="destroy" type="destructor"> | |||
| 130 | + | <description summary="destroy the cursor shape device"> | |||
| 131 | + | Destroy the cursor shape device. | |||
| 132 | + | ||||
| 133 | + | The device cursor shape remains unchanged. | |||
| 134 | + | </description> | |||
| 135 | + | </request> | |||
| 136 | + | ||||
| 137 | + | <request name="set_shape"> | |||
| 138 | + | <description summary="set device cursor to the shape"> | |||
| 139 | + | Sets the device cursor to the specified shape. The compositor will | |||
| 140 | + | change the cursor image based on the specified shape. | |||
| 141 | + | ||||
| 142 | + | The cursor actually changes only if the input device focus is one of | |||
| 143 | + | the requesting client's surfaces. If any, the previous cursor image | |||
| 144 | + | (surface or shape) is replaced. | |||
| 145 | + | ||||
| 146 | + | The "shape" argument must be a valid enum entry, otherwise the | |||
| 147 | + | invalid_shape protocol error is raised. | |||
| 148 | + | ||||
| 149 | + | This is similar to the wl_pointer.set_cursor and | |||
| 150 | + | zwp_tablet_tool_v2.set_cursor requests, but this request accepts a | |||
| 151 | + | shape instead of contents in the form of a surface. Clients can mix | |||
| 152 | + | set_cursor and set_shape requests. | |||
| 153 | + | ||||
| 154 | + | The serial parameter must match the latest wl_pointer.enter or | |||
| 155 | + | zwp_tablet_tool_v2.proximity_in serial number sent to the client. | |||
| 156 | + | Otherwise the request will be ignored. | |||
| 157 | + | </description> | |||
| 158 | + | <arg name="serial" type="uint" summary="serial number of the enter event"/> | |||
| 159 | + | <arg name="shape" type="uint" enum="shape"/> | |||
| 160 | + | </request> | |||
| 161 | + | </interface> | |||
| 162 | + | </protocol> | |||
A spec/xml/drmlease.xml +317 -0
| @@ -0,0 +1,317 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="drm_lease_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2018 NXP | |||
| 5 | + | Copyright © 2019 Status Research & Development GmbH. | |||
| 6 | + | Copyright © 2021 Xaver Hugl | |||
| 7 | + | ||||
| 8 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 9 | + | copy of this software and associated documentation files (the "Software"), | |||
| 10 | + | to deal in the Software without restriction, including without limitation | |||
| 11 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 12 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 13 | + | Software is furnished to do so, subject to the following conditions: | |||
| 14 | + | ||||
| 15 | + | The above copyright notice and this permission notice (including the next | |||
| 16 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 17 | + | Software. | |||
| 18 | + | ||||
| 19 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 20 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 21 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 22 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 23 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 24 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 25 | + | DEALINGS IN THE SOFTWARE. | |||
| 26 | + | </copyright> | |||
| 27 | + | ||||
| 28 | + | <interface name="wp_drm_lease_device_v1" version="1"> | |||
| 29 | + | <description summary="lease device"> | |||
| 30 | + | This protocol is used by Wayland compositors which act as Direct | |||
| 31 | + | Rendering Manager (DRM) masters to lease DRM resources to Wayland | |||
| 32 | + | clients. | |||
| 33 | + | ||||
| 34 | + | The compositor will advertise one wp_drm_lease_device_v1 global for each | |||
| 35 | + | DRM node. Some time after a client binds to the wp_drm_lease_device_v1 | |||
| 36 | + | global, the compositor will send a drm_fd event followed by zero, one or | |||
| 37 | + | more connector events. After all currently available connectors have been | |||
| 38 | + | sent, the compositor will send a wp_drm_lease_device_v1.done event. | |||
| 39 | + | ||||
| 40 | + | When the list of connectors available for lease changes the compositor | |||
| 41 | + | will send wp_drm_lease_device_v1.connector events for added connectors and | |||
| 42 | + | wp_drm_lease_connector_v1.withdrawn events for removed connectors, | |||
| 43 | + | followed by a wp_drm_lease_device_v1.done event. | |||
| 44 | + | ||||
| 45 | + | The compositor will indicate when a device is gone by removing the global | |||
| 46 | + | via a wl_registry.global_remove event. Upon receiving this event, the | |||
| 47 | + | client should destroy any matching wp_drm_lease_device_v1 object. | |||
| 48 | + | ||||
| 49 | + | To destroy a wp_drm_lease_device_v1 object, the client must first issue | |||
| 50 | + | a release request. Upon receiving this request, the compositor will | |||
| 51 | + | immediately send a released event and destroy the object. The client must | |||
| 52 | + | continue to process and discard drm_fd and connector events until it | |||
| 53 | + | receives the released event. Upon receiving the released event, the | |||
| 54 | + | client can safely cleanup any client-side resources. | |||
| 55 | + | ||||
| 56 | + | Warning! The protocol described in this file is currently in the testing | |||
| 57 | + | phase. Backward compatible changes may be added together with the | |||
| 58 | + | corresponding interface version bump. Backward incompatible changes can | |||
| 59 | + | only be done by creating a new major version of the extension. | |||
| 60 | + | </description> | |||
| 61 | + | ||||
| 62 | + | <request name="create_lease_request"> | |||
| 63 | + | <description summary="create a lease request object"> | |||
| 64 | + | Creates a lease request object. | |||
| 65 | + | ||||
| 66 | + | See the documentation for wp_drm_lease_request_v1 for details. | |||
| 67 | + | </description> | |||
| 68 | + | <arg name="id" type="new_id" interface="wp_drm_lease_request_v1" /> | |||
| 69 | + | </request> | |||
| 70 | + | ||||
| 71 | + | <request name="release"> | |||
| 72 | + | <description summary="release this object"> | |||
| 73 | + | Indicates the client no longer wishes to use this object. In response | |||
| 74 | + | the compositor will immediately send the released event and destroy | |||
| 75 | + | this object. It can however not guarantee that the client won't receive | |||
| 76 | + | connector events before the released event. The client must not send any | |||
| 77 | + | requests after this one, doing so will raise a wl_display error. | |||
| 78 | + | Existing connectors, lease request and leases will not be affected. | |||
| 79 | + | </description> | |||
| 80 | + | </request> | |||
| 81 | + | ||||
| 82 | + | <event name="drm_fd"> | |||
| 83 | + | <description summary="open a non-master fd for this DRM node"> | |||
| 84 | + | The compositor will send this event when the wp_drm_lease_device_v1 | |||
| 85 | + | global is bound, although there are no guarantees as to how long this | |||
| 86 | + | takes - the compositor might need to wait until regaining DRM master. | |||
| 87 | + | The included fd is a non-master DRM file descriptor opened for this | |||
| 88 | + | device and the compositor must not authenticate it. | |||
| 89 | + | The purpose of this event is to give the client the ability to | |||
| 90 | + | query DRM and discover information which may help them pick the | |||
| 91 | + | appropriate DRM device or select the appropriate connectors therein. | |||
| 92 | + | </description> | |||
| 93 | + | <arg name="fd" type="fd" summary="DRM file descriptor" /> | |||
| 94 | + | </event> | |||
| 95 | + | ||||
| 96 | + | <event name="connector"> | |||
| 97 | + | <description summary="advertise connectors available for leases"> | |||
| 98 | + | The compositor will use this event to advertise connectors available for | |||
| 99 | + | lease by clients. This object may be passed into a lease request to | |||
| 100 | + | indicate the client would like to lease that connector, see | |||
| 101 | + | wp_drm_lease_request_v1.request_connector for details. While the | |||
| 102 | + | compositor will make a best effort to not send disconnected connectors, | |||
| 103 | + | no guarantees can be made. | |||
| 104 | + | ||||
| 105 | + | The compositor must send the drm_fd event before sending connectors. | |||
| 106 | + | After the drm_fd event it will send all available connectors but may | |||
| 107 | + | send additional connectors at any time. | |||
| 108 | + | </description> | |||
| 109 | + | <arg name="id" type="new_id" interface="wp_drm_lease_connector_v1" /> | |||
| 110 | + | </event> | |||
| 111 | + | ||||
| 112 | + | <event name="done"> | |||
| 113 | + | <description summary="signals grouping of connectors"> | |||
| 114 | + | The compositor will send this event to indicate that it has sent all | |||
| 115 | + | currently available connectors after the client binds to the global or | |||
| 116 | + | when it updates the connector list, for example on hotplug, drm master | |||
| 117 | + | change or when a leased connector becomes available again. It will | |||
| 118 | + | similarly send this event to group wp_drm_lease_connector_v1.withdrawn | |||
| 119 | + | events of connectors of this device. | |||
| 120 | + | </description> | |||
| 121 | + | </event> | |||
| 122 | + | ||||
| 123 | + | <event name="released" type="destructor"> | |||
| 124 | + | <description summary="the compositor has finished using the device"> | |||
| 125 | + | This event is sent in response to the release request and indicates | |||
| 126 | + | that the compositor is done sending connector events. | |||
| 127 | + | The compositor will destroy this object immediately after sending the | |||
| 128 | + | event and it will become invalid. The client should release any | |||
| 129 | + | resources associated with this device after receiving this event. | |||
| 130 | + | </description> | |||
| 131 | + | </event> | |||
| 132 | + | </interface> | |||
| 133 | + | ||||
| 134 | + | <interface name="wp_drm_lease_connector_v1" version="1"> | |||
| 135 | + | <description summary="a leasable DRM connector"> | |||
| 136 | + | Represents a DRM connector which is available for lease. These objects are | |||
| 137 | + | created via wp_drm_lease_device_v1.connector events, and should be passed | |||
| 138 | + | to lease requests via wp_drm_lease_request_v1.request_connector. | |||
| 139 | + | Immediately after the wp_drm_lease_connector_v1 object is created the | |||
| 140 | + | compositor will send a name, a description, a connector_id and a done | |||
| 141 | + | event. When the description is updated the compositor will send a | |||
| 142 | + | description event followed by a done event. | |||
| 143 | + | </description> | |||
| 144 | + | ||||
| 145 | + | <event name="name"> | |||
| 146 | + | <description summary="name"> | |||
| 147 | + | The compositor sends this event once the connector is created to | |||
| 148 | + | indicate the name of this connector. This will not change for the | |||
| 149 | + | duration of the Wayland session, but is not guaranteed to be consistent | |||
| 150 | + | between sessions. | |||
| 151 | + | ||||
| 152 | + | If the compositor supports wl_output version 4 and this connector | |||
| 153 | + | corresponds to a wl_output, the compositor should use the same name as | |||
| 154 | + | for the wl_output. | |||
| 155 | + | </description> | |||
| 156 | + | <arg name="name" type="string" summary="connector name" /> | |||
| 157 | + | </event> | |||
| 158 | + | ||||
| 159 | + | <event name="description"> | |||
| 160 | + | <description summary="description"> | |||
| 161 | + | The compositor sends this event once the connector is created to provide | |||
| 162 | + | a human-readable description for this connector, which may be presented | |||
| 163 | + | to the user. The compositor may send this event multiple times over the | |||
| 164 | + | lifetime of this object to reflect changes in the description. | |||
| 165 | + | </description> | |||
| 166 | + | <arg name="description" type="string" summary="connector description" /> | |||
| 167 | + | </event> | |||
| 168 | + | ||||
| 169 | + | <event name="connector_id"> | |||
| 170 | + | <description summary="connector_id"> | |||
| 171 | + | The compositor sends this event once the connector is created to | |||
| 172 | + | indicate the DRM object ID which represents the underlying connector | |||
| 173 | + | that is being offered. Note that the final lease may include additional | |||
| 174 | + | object IDs, such as CRTCs and planes. | |||
| 175 | + | </description> | |||
| 176 | + | <arg name="connector_id" type="uint" summary="DRM connector ID" /> | |||
| 177 | + | </event> | |||
| 178 | + | ||||
| 179 | + | <event name="done"> | |||
| 180 | + | <description summary="all properties have been sent"> | |||
| 181 | + | This event is sent after all properties of a connector have been sent. | |||
| 182 | + | This allows changes to the properties to be seen as atomic even if they | |||
| 183 | + | happen via multiple events. | |||
| 184 | + | </description> | |||
| 185 | + | </event> | |||
| 186 | + | ||||
| 187 | + | <event name="withdrawn"> | |||
| 188 | + | <description summary="lease offer withdrawn"> | |||
| 189 | + | Sent to indicate that the compositor will no longer honor requests for | |||
| 190 | + | DRM leases which include this connector. The client may still issue a | |||
| 191 | + | lease request including this connector, but the compositor will send | |||
| 192 | + | wp_drm_lease_v1.finished without issuing a lease fd. Compositors are | |||
| 193 | + | encouraged to send this event when they lose access to connector, for | |||
| 194 | + | example when the connector is hot-unplugged, when the connector gets | |||
| 195 | + | leased to a client or when the compositor loses DRM master. | |||
| 196 | + | ||||
| 197 | + | If a client holds a lease for the connector, the status of the lease | |||
| 198 | + | remains the same. The client should destroy the object after receiving | |||
| 199 | + | this event. | |||
| 200 | + | </description> | |||
| 201 | + | </event> | |||
| 202 | + | ||||
| 203 | + | <request name="destroy" type="destructor"> | |||
| 204 | + | <description summary="destroy connector"> | |||
| 205 | + | The client may send this request to indicate that it will not use this | |||
| 206 | + | connector. Clients are encouraged to send this after receiving the | |||
| 207 | + | "withdrawn" event so that the server can release the resources | |||
| 208 | + | associated with this connector offer. Neither existing lease requests | |||
| 209 | + | nor leases will be affected. | |||
| 210 | + | </description> | |||
| 211 | + | </request> | |||
| 212 | + | </interface> | |||
| 213 | + | ||||
| 214 | + | <interface name="wp_drm_lease_request_v1" version="1"> | |||
| 215 | + | <description summary="DRM lease request"> | |||
| 216 | + | A client that wishes to lease DRM resources will attach the list of | |||
| 217 | + | connectors advertised with wp_drm_lease_device_v1.connector that they | |||
| 218 | + | wish to lease, then use wp_drm_lease_request_v1.submit to submit the | |||
| 219 | + | request. | |||
| 220 | + | </description> | |||
| 221 | + | ||||
| 222 | + | <enum name="error"> | |||
| 223 | + | <entry name="wrong_device" value="0" | |||
| 224 | + | summary="requested a connector from a different lease device"/> | |||
| 225 | + | <entry name="duplicate_connector" value="1" | |||
| 226 | + | summary="requested a connector twice"/> | |||
| 227 | + | <entry name="empty_lease" value="2" | |||
| 228 | + | summary="requested a lease without requesting a connector"/> | |||
| 229 | + | </enum> | |||
| 230 | + | ||||
| 231 | + | <request name="request_connector"> | |||
| 232 | + | <description summary="request a connector for this lease"> | |||
| 233 | + | Indicates that the client would like to lease the given connector. | |||
| 234 | + | This is only used as a suggestion, the compositor may choose to | |||
| 235 | + | include any resources in the lease it issues, or change the set of | |||
| 236 | + | leased resources at any time. Compositors are however encouraged to | |||
| 237 | + | include the requested connector and other resources necessary | |||
| 238 | + | to drive the connected output in the lease. | |||
| 239 | + | ||||
| 240 | + | Requesting a connector that was created from a different lease device | |||
| 241 | + | than this lease request raises the wrong_device error. Requesting a | |||
| 242 | + | connector twice will raise the duplicate_connector error. | |||
| 243 | + | </description> | |||
| 244 | + | <arg name="connector" type="object" | |||
| 245 | + | interface="wp_drm_lease_connector_v1" /> | |||
| 246 | + | </request> | |||
| 247 | + | ||||
| 248 | + | <request name="submit" type="destructor"> | |||
| 249 | + | <description summary="submit the lease request"> | |||
| 250 | + | Submits the lease request and creates a new wp_drm_lease_v1 object. | |||
| 251 | + | After calling submit the compositor will immediately destroy this | |||
| 252 | + | object, issuing any more requests will cause a wl_display error. | |||
| 253 | + | The compositor doesn't make any guarantees about the events of the | |||
| 254 | + | lease object, clients cannot expect an immediate response. | |||
| 255 | + | Not requesting any connectors before submitting the lease request | |||
| 256 | + | will raise the empty_lease error. | |||
| 257 | + | </description> | |||
| 258 | + | <arg name="id" type="new_id" interface="wp_drm_lease_v1" /> | |||
| 259 | + | </request> | |||
| 260 | + | </interface> | |||
| 261 | + | ||||
| 262 | + | <interface name="wp_drm_lease_v1" version="1"> | |||
| 263 | + | <description summary="a DRM lease"> | |||
| 264 | + | A DRM lease object is used to transfer the DRM file descriptor to the | |||
| 265 | + | client and manage the lifetime of the lease. | |||
| 266 | + | ||||
| 267 | + | Some time after the wp_drm_lease_v1 object is created, the compositor | |||
| 268 | + | will reply with the lease request's result. If the lease request is | |||
| 269 | + | granted, the compositor will send a lease_fd event. If the lease request | |||
| 270 | + | is denied, the compositor will send a finished event without a lease_fd | |||
| 271 | + | event. | |||
| 272 | + | </description> | |||
| 273 | + | ||||
| 274 | + | <event name="lease_fd"> | |||
| 275 | + | <description summary="shares the DRM file descriptor"> | |||
| 276 | + | This event returns a file descriptor suitable for use with DRM-related | |||
| 277 | + | ioctls. The client should use drmModeGetLease to enumerate the DRM | |||
| 278 | + | objects which have been leased to them. The compositor guarantees it | |||
| 279 | + | will not use the leased DRM objects itself until it sends the finished | |||
| 280 | + | event. If the compositor cannot or will not grant a lease for the | |||
| 281 | + | requested connectors, it will not send this event, instead sending the | |||
| 282 | + | finished event. | |||
| 283 | + | ||||
| 284 | + | The compositor will send this event at most once during this objects | |||
| 285 | + | lifetime. | |||
| 286 | + | </description> | |||
| 287 | + | <arg name="leased_fd" type="fd" summary="leased DRM file descriptor" /> | |||
| 288 | + | </event> | |||
| 289 | + | ||||
| 290 | + | <event name="finished"> | |||
| 291 | + | <description summary="sent when the lease has been revoked"> | |||
| 292 | + | The compositor uses this event to either reject a lease request, or if | |||
| 293 | + | it previously sent a lease_fd, to notify the client that the lease has | |||
| 294 | + | been revoked. If the client requires a new lease, they should destroy | |||
| 295 | + | this object and submit a new lease request. The compositor will send | |||
| 296 | + | no further events for this object after sending the finish event. | |||
| 297 | + | Compositors should revoke the lease when any of the leased resources | |||
| 298 | + | become unavailable, namely when a hot-unplug occurs or when the | |||
| 299 | + | compositor loses DRM master. Compositors may advertise the connector | |||
| 300 | + | for leasing again, if the resource is available, by sending the | |||
| 301 | + | connector event through the wp_drm_lease_device_v1 interface. | |||
| 302 | + | </description> | |||
| 303 | + | </event> | |||
| 304 | + | ||||
| 305 | + | <request name="destroy" type="destructor"> | |||
| 306 | + | <description summary="destroys the lease object"> | |||
| 307 | + | The client should send this to indicate that it no longer wishes to use | |||
| 308 | + | this lease. The compositor should use drmModeRevokeLease on the | |||
| 309 | + | appropriate file descriptor, if necessary. | |||
| 310 | + | ||||
| 311 | + | Upon destruction, the compositor should advertise the connector for | |||
| 312 | + | leasing again by sending the connector event through the | |||
| 313 | + | wp_drm_lease_device_v1 interface. | |||
| 314 | + | </description> | |||
| 315 | + | </request> | |||
| 316 | + | </interface> | |||
| 317 | + | </protocol> | |||
A spec/xml/extbackgroundeffect.xml +129 -0
| @@ -0,0 +1,129 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="ext_background_effect_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright (C) 2015 Martin Gräßlin | |||
| 5 | + | Copyright (C) 2015 Marco Martin | |||
| 6 | + | Copyright (C) 2020 Vlad Zahorodnii | |||
| 7 | + | Copyright (C) 2024 Xaver Hugl | |||
| 8 | + | ||||
| 9 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 10 | + | copy of this software and associated documentation files (the "Software"), | |||
| 11 | + | to deal in the Software without restriction, including without limitation | |||
| 12 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 13 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 14 | + | Software is furnished to do so, subject to the following conditions: | |||
| 15 | + | ||||
| 16 | + | The above copyright notice and this permission notice (including the next | |||
| 17 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 18 | + | Software. | |||
| 19 | + | ||||
| 20 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 21 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 22 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 23 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 24 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 25 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 26 | + | DEALINGS IN THE SOFTWARE. | |||
| 27 | + | </copyright> | |||
| 28 | + | ||||
| 29 | + | <interface name="ext_background_effect_manager_v1" version="1"> | |||
| 30 | + | <description summary="background effect factory"> | |||
| 31 | + | This protocol provides a way to improve visuals of translucent surfaces | |||
| 32 | + | by applying effects like blur to the background behind them. | |||
| 33 | + | ||||
| 34 | + | The capabilities are send when the global is bound, and every time they | |||
| 35 | + | change. Note that when the capability goes away, the corresponding effect | |||
| 36 | + | is no longer applied by the compositor, even if it was set before. | |||
| 37 | + | ||||
| 38 | + | Warning! The protocol described in this file is currently in the testing | |||
| 39 | + | phase. Backward compatible changes may be added together with the | |||
| 40 | + | corresponding interface version bump. Backward incompatible changes can | |||
| 41 | + | only be done by creating a new major version of the extension. | |||
| 42 | + | </description> | |||
| 43 | + | ||||
| 44 | + | <request name="destroy" type="destructor"> | |||
| 45 | + | <description summary="destroy the background effect manager"> | |||
| 46 | + | Informs the server that the client will no longer be using this | |||
| 47 | + | protocol object. Existing objects created by this object are not | |||
| 48 | + | affected. | |||
| 49 | + | </description> | |||
| 50 | + | </request> | |||
| 51 | + | ||||
| 52 | + | <enum name="error"> | |||
| 53 | + | <entry name="background_effect_exists" value="0" | |||
| 54 | + | summary="the surface already has a background effect object"/> | |||
| 55 | + | </enum> | |||
| 56 | + | ||||
| 57 | + | <enum name="capability" bitfield="true"> | |||
| 58 | + | <entry name="blur" value="1" | |||
| 59 | + | summary="the compositor supports applying blur"/> | |||
| 60 | + | </enum> | |||
| 61 | + | ||||
| 62 | + | <event name="capabilities"> | |||
| 63 | + | <description summary="capabilities of the compositor"/> | |||
| 64 | + | <arg name="flags" type="uint" enum="capability"/> | |||
| 65 | + | </event> | |||
| 66 | + | ||||
| 67 | + | <request name="get_background_effect"> | |||
| 68 | + | <description summary="get a background effects object"> | |||
| 69 | + | Instantiate an interface extension for the given wl_surface to add | |||
| 70 | + | effects like blur for the background behind it. | |||
| 71 | + | ||||
| 72 | + | If the given wl_surface already has a ext_background_effect_surface_v1 | |||
| 73 | + | object associated, the background_effect_exists protocol error will be | |||
| 74 | + | raised. | |||
| 75 | + | </description> | |||
| 76 | + | <arg name="id" type="new_id" interface="ext_background_effect_surface_v1" | |||
| 77 | + | summary="the new ext_background_effect_surface_v1 object"/> | |||
| 78 | + | <arg name="surface" type="object" interface="wl_surface" | |||
| 79 | + | summary="the surface"/> | |||
| 80 | + | </request> | |||
| 81 | + | </interface> | |||
| 82 | + | ||||
| 83 | + | <interface name="ext_background_effect_surface_v1" version="1"> | |||
| 84 | + | <description summary="background effects for a surface"> | |||
| 85 | + | The background effect object provides a way to specify a region behind | |||
| 86 | + | a surface that should have background effects like blur applied. | |||
| 87 | + | ||||
| 88 | + | If the wl_surface associated with the ext_background_effect_surface_v1 | |||
| 89 | + | object has been destroyed, this object becomes inert. | |||
| 90 | + | </description> | |||
| 91 | + | ||||
| 92 | + | <request name="destroy" type="destructor"> | |||
| 93 | + | <description summary="release the blur object"> | |||
| 94 | + | Informs the server that the client will no longer be using this protocol | |||
| 95 | + | object. The effect regions will be removed on the next commit. | |||
| 96 | + | </description> | |||
| 97 | + | </request> | |||
| 98 | + | ||||
| 99 | + | <enum name="error"> | |||
| 100 | + | <entry name="surface_destroyed" value="0" | |||
| 101 | + | summary="the associated surface has been destroyed"/> | |||
| 102 | + | </enum> | |||
| 103 | + | ||||
| 104 | + | <request name="set_blur_region"> | |||
| 105 | + | <description summary="set blur region"> | |||
| 106 | + | This request sets the region of the surface that will have its | |||
| 107 | + | background blurred. | |||
| 108 | + | ||||
| 109 | + | The blur region is specified in the surface-local coordinates, and | |||
| 110 | + | clipped by the compositor to the surface size. | |||
| 111 | + | ||||
| 112 | + | The initial value for the blur region is empty. Setting the pending | |||
| 113 | + | blur region has copy semantics, and the wl_region object can be | |||
| 114 | + | destroyed immediately. A NULL wl_region removes the effect. | |||
| 115 | + | ||||
| 116 | + | The blur region is double-buffered state, and will be applied on | |||
| 117 | + | the next wl_surface.commit. | |||
| 118 | + | ||||
| 119 | + | The blur algorithm is subject to compositor policies. | |||
| 120 | + | ||||
| 121 | + | If the associated surface has been destroyed, the surface_destroyed | |||
| 122 | + | error will be raised. | |||
| 123 | + | </description> | |||
| 124 | + | <arg name="region" type="object" interface="wl_region" allow-null="true" | |||
| 125 | + | summary="blur region of the surface"/> | |||
| 126 | + | </request> | |||
| 127 | + | ||||
| 128 | + | </interface> | |||
| 129 | + | </protocol> | |||
A spec/xml/extdatacontrol.xml +276 -0
| @@ -0,0 +1,276 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="ext_data_control_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2018 Simon Ser | |||
| 5 | + | Copyright © 2019 Ivan Molodetskikh | |||
| 6 | + | Copyright © 2024 Neal Gompa | |||
| 7 | + | ||||
| 8 | + | Permission to use, copy, modify, distribute, and sell this | |||
| 9 | + | software and its documentation for any purpose is hereby granted | |||
| 10 | + | without fee, provided that the above copyright notice appear in | |||
| 11 | + | all copies and that both that copyright notice and this permission | |||
| 12 | + | notice appear in supporting documentation, and that the name of | |||
| 13 | + | the copyright holders not be used in advertising or publicity | |||
| 14 | + | pertaining to distribution of the software without specific, | |||
| 15 | + | written prior permission. The copyright holders make no | |||
| 16 | + | representations about the suitability of this software for any | |||
| 17 | + | purpose. It is provided "as is" without express or implied | |||
| 18 | + | warranty. | |||
| 19 | + | ||||
| 20 | + | THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | |||
| 21 | + | SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||
| 22 | + | FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | |||
| 23 | + | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||
| 24 | + | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | |||
| 25 | + | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |||
| 26 | + | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |||
| 27 | + | THIS SOFTWARE. | |||
| 28 | + | </copyright> | |||
| 29 | + | ||||
| 30 | + | <description summary="control data devices"> | |||
| 31 | + | This protocol allows a privileged client to control data devices. In | |||
| 32 | + | particular, the client will be able to manage the current selection and take | |||
| 33 | + | the role of a clipboard manager. | |||
| 34 | + | ||||
| 35 | + | Warning! The protocol described in this file is currently in the testing | |||
| 36 | + | phase. Backward compatible changes may be added together with the | |||
| 37 | + | corresponding interface version bump. Backward incompatible changes can | |||
| 38 | + | only be done by creating a new major version of the extension. | |||
| 39 | + | </description> | |||
| 40 | + | ||||
| 41 | + | <interface name="ext_data_control_manager_v1" version="1"> | |||
| 42 | + | <description summary="manager to control data devices"> | |||
| 43 | + | This interface is a manager that allows creating per-seat data device | |||
| 44 | + | controls. | |||
| 45 | + | </description> | |||
| 46 | + | ||||
| 47 | + | <request name="create_data_source"> | |||
| 48 | + | <description summary="create a new data source"> | |||
| 49 | + | Create a new data source. | |||
| 50 | + | </description> | |||
| 51 | + | <arg name="id" type="new_id" interface="ext_data_control_source_v1" | |||
| 52 | + | summary="data source to create"/> | |||
| 53 | + | </request> | |||
| 54 | + | ||||
| 55 | + | <request name="get_data_device"> | |||
| 56 | + | <description summary="get a data device for a seat"> | |||
| 57 | + | Create a data device that can be used to manage a seat's selection. | |||
| 58 | + | </description> | |||
| 59 | + | <arg name="id" type="new_id" interface="ext_data_control_device_v1"/> | |||
| 60 | + | <arg name="seat" type="object" interface="wl_seat"/> | |||
| 61 | + | </request> | |||
| 62 | + | ||||
| 63 | + | <request name="destroy" type="destructor"> | |||
| 64 | + | <description summary="destroy the manager"> | |||
| 65 | + | All objects created by the manager will still remain valid, until their | |||
| 66 | + | appropriate destroy request has been called. | |||
| 67 | + | </description> | |||
| 68 | + | </request> | |||
| 69 | + | </interface> | |||
| 70 | + | ||||
| 71 | + | <interface name="ext_data_control_device_v1" version="1"> | |||
| 72 | + | <description summary="manage a data device for a seat"> | |||
| 73 | + | This interface allows a client to manage a seat's selection. | |||
| 74 | + | ||||
| 75 | + | When the seat is destroyed, this object becomes inert. | |||
| 76 | + | </description> | |||
| 77 | + | ||||
| 78 | + | <request name="set_selection"> | |||
| 79 | + | <description summary="copy data to the selection"> | |||
| 80 | + | This request asks the compositor to set the selection to the data from | |||
| 81 | + | the source on behalf of the client. | |||
| 82 | + | ||||
| 83 | + | The given source may not be used in any further set_selection or | |||
| 84 | + | set_primary_selection requests. Attempting to use a previously used | |||
| 85 | + | source triggers the used_source protocol error. | |||
| 86 | + | ||||
| 87 | + | To unset the selection, set the source to NULL. | |||
| 88 | + | </description> | |||
| 89 | + | <arg name="source" type="object" interface="ext_data_control_source_v1" | |||
| 90 | + | allow-null="true"/> | |||
| 91 | + | </request> | |||
| 92 | + | ||||
| 93 | + | <request name="destroy" type="destructor"> | |||
| 94 | + | <description summary="destroy this data device"> | |||
| 95 | + | Destroys the data device object. | |||
| 96 | + | </description> | |||
| 97 | + | </request> | |||
| 98 | + | ||||
| 99 | + | <event name="data_offer"> | |||
| 100 | + | <description summary="introduce a new ext_data_control_offer"> | |||
| 101 | + | The data_offer event introduces a new ext_data_control_offer object, | |||
| 102 | + | which will subsequently be used in either the | |||
| 103 | + | ext_data_control_device.selection event (for the regular clipboard | |||
| 104 | + | selections) or the ext_data_control_device.primary_selection event (for | |||
| 105 | + | the primary clipboard selections). Immediately following the | |||
| 106 | + | ext_data_control_device.data_offer event, the new data_offer object | |||
| 107 | + | will send out ext_data_control_offer.offer events to describe the MIME | |||
| 108 | + | types it offers. | |||
| 109 | + | </description> | |||
| 110 | + | <arg name="id" type="new_id" interface="ext_data_control_offer_v1"/> | |||
| 111 | + | </event> | |||
| 112 | + | ||||
| 113 | + | <event name="selection"> | |||
| 114 | + | <description summary="advertise new selection"> | |||
| 115 | + | The selection event is sent out to notify the client of a new | |||
| 116 | + | ext_data_control_offer for the selection for this device. The | |||
| 117 | + | ext_data_control_device.data_offer and the ext_data_control_offer.offer | |||
| 118 | + | events are sent out immediately before this event to introduce the data | |||
| 119 | + | offer object. The selection event is sent to a client when a new | |||
| 120 | + | selection is set. The ext_data_control_offer is valid until a new | |||
| 121 | + | ext_data_control_offer or NULL is received. The client must destroy the | |||
| 122 | + | previous selection ext_data_control_offer, if any, upon receiving this | |||
| 123 | + | event. Regardless, the previous selection will be ignored once a new | |||
| 124 | + | selection ext_data_control_offer is received. | |||
| 125 | + | ||||
| 126 | + | The first selection event is sent upon binding the | |||
| 127 | + | ext_data_control_device object. | |||
| 128 | + | </description> | |||
| 129 | + | <arg name="id" type="object" interface="ext_data_control_offer_v1" | |||
| 130 | + | allow-null="true"/> | |||
| 131 | + | </event> | |||
| 132 | + | ||||
| 133 | + | <event name="finished"> | |||
| 134 | + | <description summary="this data control is no longer valid"> | |||
| 135 | + | This data control object is no longer valid and should be destroyed by | |||
| 136 | + | the client. | |||
| 137 | + | </description> | |||
| 138 | + | </event> | |||
| 139 | + | ||||
| 140 | + | <event name="primary_selection"> | |||
| 141 | + | <description summary="advertise new primary selection"> | |||
| 142 | + | The primary_selection event is sent out to notify the client of a new | |||
| 143 | + | ext_data_control_offer for the primary selection for this device. The | |||
| 144 | + | ext_data_control_device.data_offer and the ext_data_control_offer.offer | |||
| 145 | + | events are sent out immediately before this event to introduce the data | |||
| 146 | + | offer object. The primary_selection event is sent to a client when a | |||
| 147 | + | new primary selection is set. The ext_data_control_offer is valid until | |||
| 148 | + | a new ext_data_control_offer or NULL is received. The client must | |||
| 149 | + | destroy the previous primary selection ext_data_control_offer, if any, | |||
| 150 | + | upon receiving this event. Regardless, the previous primary selection | |||
| 151 | + | will be ignored once a new primary selection ext_data_control_offer is | |||
| 152 | + | received. | |||
| 153 | + | ||||
| 154 | + | If the compositor supports primary selection, the first | |||
| 155 | + | primary_selection event is sent upon binding the | |||
| 156 | + | ext_data_control_device object. | |||
| 157 | + | </description> | |||
| 158 | + | <arg name="id" type="object" interface="ext_data_control_offer_v1" | |||
| 159 | + | allow-null="true"/> | |||
| 160 | + | </event> | |||
| 161 | + | ||||
| 162 | + | <request name="set_primary_selection"> | |||
| 163 | + | <description summary="copy data to the primary selection"> | |||
| 164 | + | This request asks the compositor to set the primary selection to the | |||
| 165 | + | data from the source on behalf of the client. | |||
| 166 | + | ||||
| 167 | + | The given source may not be used in any further set_selection or | |||
| 168 | + | set_primary_selection requests. Attempting to use a previously used | |||
| 169 | + | source triggers the used_source protocol error. | |||
| 170 | + | ||||
| 171 | + | To unset the primary selection, set the source to NULL. | |||
| 172 | + | ||||
| 173 | + | The compositor will ignore this request if it does not support primary | |||
| 174 | + | selection. | |||
| 175 | + | </description> | |||
| 176 | + | <arg name="source" type="object" interface="ext_data_control_source_v1" | |||
| 177 | + | allow-null="true"/> | |||
| 178 | + | </request> | |||
| 179 | + | ||||
| 180 | + | <enum name="error"> | |||
| 181 | + | <entry name="used_source" value="1" | |||
| 182 | + | summary="source given to set_selection or set_primary_selection was already used before"/> | |||
| 183 | + | </enum> | |||
| 184 | + | </interface> | |||
| 185 | + | ||||
| 186 | + | <interface name="ext_data_control_source_v1" version="1"> | |||
| 187 | + | <description summary="offer to transfer data"> | |||
| 188 | + | The ext_data_control_source object is the source side of a | |||
| 189 | + | ext_data_control_offer. It is created by the source client in a data | |||
| 190 | + | transfer and provides a way to describe the offered data and a way to | |||
| 191 | + | respond to requests to transfer the data. | |||
| 192 | + | </description> | |||
| 193 | + | ||||
| 194 | + | <enum name="error"> | |||
| 195 | + | <entry name="invalid_offer" value="1" | |||
| 196 | + | summary="offer sent after ext_data_control_device.set_selection"/> | |||
| 197 | + | </enum> | |||
| 198 | + | ||||
| 199 | + | <request name="offer"> | |||
| 200 | + | <description summary="add an offered MIME type"> | |||
| 201 | + | This request adds a MIME type to the set of MIME types advertised to | |||
| 202 | + | targets. Can be called several times to offer multiple types. | |||
| 203 | + | ||||
| 204 | + | Calling this after ext_data_control_device.set_selection is a protocol | |||
| 205 | + | error. | |||
| 206 | + | </description> | |||
| 207 | + | <arg name="mime_type" type="string" | |||
| 208 | + | summary="MIME type offered by the data source"/> | |||
| 209 | + | </request> | |||
| 210 | + | ||||
| 211 | + | <request name="destroy" type="destructor"> | |||
| 212 | + | <description summary="destroy this source"> | |||
| 213 | + | Destroys the data source object. | |||
| 214 | + | </description> | |||
| 215 | + | </request> | |||
| 216 | + | ||||
| 217 | + | <event name="send"> | |||
| 218 | + | <description summary="send the data"> | |||
| 219 | + | Request for data from the client. Send the data as the specified MIME | |||
| 220 | + | type over the passed file descriptor, then close it. | |||
| 221 | + | </description> | |||
| 222 | + | <arg name="mime_type" type="string" summary="MIME type for the data"/> | |||
| 223 | + | <arg name="fd" type="fd" summary="file descriptor for the data"/> | |||
| 224 | + | </event> | |||
| 225 | + | ||||
| 226 | + | <event name="cancelled"> | |||
| 227 | + | <description summary="selection was cancelled"> | |||
| 228 | + | This data source is no longer valid. The data source has been replaced | |||
| 229 | + | by another data source. | |||
| 230 | + | ||||
| 231 | + | The client should clean up and destroy this data source. | |||
| 232 | + | </description> | |||
| 233 | + | </event> | |||
| 234 | + | </interface> | |||
| 235 | + | ||||
| 236 | + | <interface name="ext_data_control_offer_v1" version="1"> | |||
| 237 | + | <description summary="offer to transfer data"> | |||
| 238 | + | A ext_data_control_offer represents a piece of data offered for transfer | |||
| 239 | + | by another client (the source client). The offer describes the different | |||
| 240 | + | MIME types that the data can be converted to and provides the mechanism | |||
| 241 | + | for transferring the data directly from the source client. | |||
| 242 | + | </description> | |||
| 243 | + | ||||
| 244 | + | <request name="receive"> | |||
| 245 | + | <description summary="request that the data is transferred"> | |||
| 246 | + | To transfer the offered data, the client issues this request and | |||
| 247 | + | indicates the MIME type it wants to receive. The transfer happens | |||
| 248 | + | through the passed file descriptor (typically created with the pipe | |||
| 249 | + | system call). The source client writes the data in the MIME type | |||
| 250 | + | representation requested and then closes the file descriptor. | |||
| 251 | + | ||||
| 252 | + | The receiving client reads from the read end of the pipe until EOF and | |||
| 253 | + | then closes its end, at which point the transfer is complete. | |||
| 254 | + | ||||
| 255 | + | This request may happen multiple times for different MIME types. | |||
| 256 | + | </description> | |||
| 257 | + | <arg name="mime_type" type="string" | |||
| 258 | + | summary="MIME type desired by receiver"/> | |||
| 259 | + | <arg name="fd" type="fd" summary="file descriptor for data transfer"/> | |||
| 260 | + | </request> | |||
| 261 | + | ||||
| 262 | + | <request name="destroy" type="destructor"> | |||
| 263 | + | <description summary="destroy this offer"> | |||
| 264 | + | Destroys the data offer object. | |||
| 265 | + | </description> | |||
| 266 | + | </request> | |||
| 267 | + | ||||
| 268 | + | <event name="offer"> | |||
| 269 | + | <description summary="advertise offered MIME type"> | |||
| 270 | + | Sent immediately after creating the ext_data_control_offer object. | |||
| 271 | + | One event per offered MIME type. | |||
| 272 | + | </description> | |||
| 273 | + | <arg name="mime_type" type="string" summary="offered MIME type"/> | |||
| 274 | + | </event> | |||
| 275 | + | </interface> | |||
| 276 | + | </protocol> | |||
A spec/xml/extforeigntoplevellist.xml +219 -0
| @@ -0,0 +1,219 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="ext_foreign_toplevel_list_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2018 Ilia Bozhinov | |||
| 5 | + | Copyright © 2020 Isaac Freund | |||
| 6 | + | Copyright © 2022 wb9688 | |||
| 7 | + | Copyright © 2023 i509VCB | |||
| 8 | + | ||||
| 9 | + | Permission to use, copy, modify, distribute, and sell this | |||
| 10 | + | software and its documentation for any purpose is hereby granted | |||
| 11 | + | without fee, provided that the above copyright notice appear in | |||
| 12 | + | all copies and that both that copyright notice and this permission | |||
| 13 | + | notice appear in supporting documentation, and that the name of | |||
| 14 | + | the copyright holders not be used in advertising or publicity | |||
| 15 | + | pertaining to distribution of the software without specific, | |||
| 16 | + | written prior permission. The copyright holders make no | |||
| 17 | + | representations about the suitability of this software for any | |||
| 18 | + | purpose. It is provided "as is" without express or implied | |||
| 19 | + | warranty. | |||
| 20 | + | ||||
| 21 | + | THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | |||
| 22 | + | SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||
| 23 | + | FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | |||
| 24 | + | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||
| 25 | + | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | |||
| 26 | + | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |||
| 27 | + | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |||
| 28 | + | THIS SOFTWARE. | |||
| 29 | + | </copyright> | |||
| 30 | + | ||||
| 31 | + | <description summary="list toplevels"> | |||
| 32 | + | The purpose of this protocol is to provide protocol object handles for | |||
| 33 | + | toplevels, possibly originating from another client. | |||
| 34 | + | ||||
| 35 | + | This protocol is intentionally minimalistic and expects additional | |||
| 36 | + | functionality (e.g. creating a screencopy source from a toplevel handle, | |||
| 37 | + | getting information about the state of the toplevel) to be implemented | |||
| 38 | + | in extension protocols. | |||
| 39 | + | ||||
| 40 | + | The compositor may choose to restrict this protocol to a special client | |||
| 41 | + | launched by the compositor itself or expose it to all clients, | |||
| 42 | + | this is compositor policy. | |||
| 43 | + | ||||
| 44 | + | The key words "must", "must not", "required", "shall", "shall not", | |||
| 45 | + | "should", "should not", "recommended", "may", and "optional" in this | |||
| 46 | + | document are to be interpreted as described in IETF RFC 2119. | |||
| 47 | + | ||||
| 48 | + | Warning! The protocol described in this file is currently in the testing | |||
| 49 | + | phase. Backward compatible changes may be added together with the | |||
| 50 | + | corresponding interface version bump. Backward incompatible changes can | |||
| 51 | + | only be done by creating a new major version of the extension. | |||
| 52 | + | </description> | |||
| 53 | + | ||||
| 54 | + | <interface name="ext_foreign_toplevel_list_v1" version="1"> | |||
| 55 | + | <description summary="list toplevels"> | |||
| 56 | + | A toplevel is defined as a surface with a role similar to xdg_toplevel. | |||
| 57 | + | XWayland surfaces may be treated like toplevels in this protocol. | |||
| 58 | + | ||||
| 59 | + | After a client binds the ext_foreign_toplevel_list_v1, each mapped | |||
| 60 | + | toplevel window will be sent using the ext_foreign_toplevel_list_v1.toplevel | |||
| 61 | + | event. | |||
| 62 | + | ||||
| 63 | + | Clients which only care about the current state can perform a roundtrip after | |||
| 64 | + | binding this global. | |||
| 65 | + | ||||
| 66 | + | For each instance of ext_foreign_toplevel_list_v1, the compositor must | |||
| 67 | + | create a new ext_foreign_toplevel_handle_v1 object for each mapped toplevel. | |||
| 68 | + | ||||
| 69 | + | If a compositor implementation sends the ext_foreign_toplevel_list_v1.finished | |||
| 70 | + | event after the global is bound, the compositor must not send any | |||
| 71 | + | ext_foreign_toplevel_list_v1.toplevel events. | |||
| 72 | + | </description> | |||
| 73 | + | ||||
| 74 | + | <event name="toplevel"> | |||
| 75 | + | <description summary="a toplevel has been created"> | |||
| 76 | + | This event is emitted whenever a new toplevel window is created. It is | |||
| 77 | + | emitted for all toplevels, regardless of the app that has created them. | |||
| 78 | + | ||||
| 79 | + | All initial properties of the toplevel (identifier, title, app_id) will be sent | |||
| 80 | + | immediately after this event using the corresponding events for | |||
| 81 | + | ext_foreign_toplevel_handle_v1. The compositor will use the | |||
| 82 | + | ext_foreign_toplevel_handle_v1.done event to indicate when all data has | |||
| 83 | + | been sent. | |||
| 84 | + | </description> | |||
| 85 | + | <arg name="toplevel" type="new_id" interface="ext_foreign_toplevel_handle_v1"/> | |||
| 86 | + | </event> | |||
| 87 | + | ||||
| 88 | + | <event name="finished"> | |||
| 89 | + | <description summary="the compositor has finished with the toplevel manager"> | |||
| 90 | + | This event indicates that the compositor is done sending events | |||
| 91 | + | to this object. The client should destroy the object. | |||
| 92 | + | See ext_foreign_toplevel_list_v1.destroy for more information. | |||
| 93 | + | ||||
| 94 | + | The compositor must not send any more toplevel events after this event. | |||
| 95 | + | </description> | |||
| 96 | + | </event> | |||
| 97 | + | ||||
| 98 | + | <request name="stop"> | |||
| 99 | + | <description summary="stop sending events"> | |||
| 100 | + | This request indicates that the client no longer wishes to receive | |||
| 101 | + | events for new toplevels. | |||
| 102 | + | ||||
| 103 | + | The Wayland protocol is asynchronous, meaning the compositor may send | |||
| 104 | + | further toplevel events until the stop request is processed. | |||
| 105 | + | The client should wait for a ext_foreign_toplevel_list_v1.finished | |||
| 106 | + | event before destroying this object. | |||
| 107 | + | </description> | |||
| 108 | + | </request> | |||
| 109 | + | ||||
| 110 | + | <request name="destroy" type="destructor"> | |||
| 111 | + | <description summary="destroy the ext_foreign_toplevel_list_v1 object"> | |||
| 112 | + | This request should be called either when the client will no longer | |||
| 113 | + | use the ext_foreign_toplevel_list_v1 or after the finished event | |||
| 114 | + | has been received to allow destruction of the object. | |||
| 115 | + | ||||
| 116 | + | If a client wishes to destroy this object it should send a | |||
| 117 | + | ext_foreign_toplevel_list_v1.stop request and wait for a ext_foreign_toplevel_list_v1.finished | |||
| 118 | + | event, then destroy the handles and then this object. | |||
| 119 | + | </description> | |||
| 120 | + | </request> | |||
| 121 | + | </interface> | |||
| 122 | + | ||||
| 123 | + | <interface name="ext_foreign_toplevel_handle_v1" version="1"> | |||
| 124 | + | <description summary="a mapped toplevel"> | |||
| 125 | + | A ext_foreign_toplevel_handle_v1 object represents a mapped toplevel | |||
| 126 | + | window. A single app may have multiple mapped toplevels. | |||
| 127 | + | </description> | |||
| 128 | + | ||||
| 129 | + | <request name="destroy" type="destructor"> | |||
| 130 | + | <description summary="destroy the ext_foreign_toplevel_handle_v1 object"> | |||
| 131 | + | This request should be used when the client will no longer use the handle | |||
| 132 | + | or after the closed event has been received to allow destruction of the | |||
| 133 | + | object. | |||
| 134 | + | ||||
| 135 | + | When a handle is destroyed, a new handle may not be created by the server | |||
| 136 | + | until the toplevel is unmapped and then remapped. Destroying a toplevel handle | |||
| 137 | + | is not recommended unless the client is cleaning up child objects | |||
| 138 | + | before destroying the ext_foreign_toplevel_list_v1 object, the toplevel | |||
| 139 | + | was closed or the toplevel handle will not be used in the future. | |||
| 140 | + | ||||
| 141 | + | Other protocols which extend the ext_foreign_toplevel_handle_v1 | |||
| 142 | + | interface should require destructors for extension interfaces be | |||
| 143 | + | called before allowing the toplevel handle to be destroyed. | |||
| 144 | + | </description> | |||
| 145 | + | </request> | |||
| 146 | + | ||||
| 147 | + | <event name="closed"> | |||
| 148 | + | <description summary="the toplevel has been closed"> | |||
| 149 | + | The server will emit no further events on the ext_foreign_toplevel_handle_v1 | |||
| 150 | + | after this event. Any requests received aside from the destroy request must | |||
| 151 | + | be ignored. Upon receiving this event, the client should destroy the handle. | |||
| 152 | + | ||||
| 153 | + | Other protocols which extend the ext_foreign_toplevel_handle_v1 | |||
| 154 | + | interface must also ignore requests other than destructors. | |||
| 155 | + | </description> | |||
| 156 | + | </event> | |||
| 157 | + | ||||
| 158 | + | <event name="done"> | |||
| 159 | + | <description summary="all information about the toplevel has been sent"> | |||
| 160 | + | This event is sent after all changes in the toplevel state have | |||
| 161 | + | been sent. | |||
| 162 | + | ||||
| 163 | + | This allows changes to the ext_foreign_toplevel_handle_v1 properties | |||
| 164 | + | to be atomically applied. Other protocols which extend the | |||
| 165 | + | ext_foreign_toplevel_handle_v1 interface may use this event to also | |||
| 166 | + | atomically apply any pending state. | |||
| 167 | + | ||||
| 168 | + | This event must not be sent after the ext_foreign_toplevel_handle_v1.closed | |||
| 169 | + | event. | |||
| 170 | + | </description> | |||
| 171 | + | </event> | |||
| 172 | + | ||||
| 173 | + | <event name="title"> | |||
| 174 | + | <description summary="title change"> | |||
| 175 | + | The title of the toplevel has changed. | |||
| 176 | + | ||||
| 177 | + | The configured state must not be applied immediately. See | |||
| 178 | + | ext_foreign_toplevel_handle_v1.done for details. | |||
| 179 | + | </description> | |||
| 180 | + | <arg name="title" type="string"/> | |||
| 181 | + | </event> | |||
| 182 | + | ||||
| 183 | + | <event name="app_id"> | |||
| 184 | + | <description summary="app_id change"> | |||
| 185 | + | The app id of the toplevel has changed. | |||
| 186 | + | ||||
| 187 | + | The configured state must not be applied immediately. See | |||
| 188 | + | ext_foreign_toplevel_handle_v1.done for details. | |||
| 189 | + | </description> | |||
| 190 | + | <arg name="app_id" type="string"/> | |||
| 191 | + | </event> | |||
| 192 | + | ||||
| 193 | + | <event name="identifier"> | |||
| 194 | + | <description summary="a stable identifier for a toplevel"> | |||
| 195 | + | This identifier is used to check if two or more toplevel handles belong | |||
| 196 | + | to the same toplevel. | |||
| 197 | + | ||||
| 198 | + | The identifier is useful for command line tools or privileged clients | |||
| 199 | + | which may need to reference an exact toplevel across processes or | |||
| 200 | + | instances of the ext_foreign_toplevel_list_v1 global. | |||
| 201 | + | ||||
| 202 | + | The compositor must only send this event when the handle is created. | |||
| 203 | + | ||||
| 204 | + | The identifier must be unique per toplevel and its handles. Two different | |||
| 205 | + | toplevels must not have the same identifier. The identifier is only valid | |||
| 206 | + | as long as the toplevel is mapped. If the toplevel is unmapped the identifier | |||
| 207 | + | must not be reused. An identifier must not be reused by the compositor to | |||
| 208 | + | ensure there are no races when sharing identifiers between processes. | |||
| 209 | + | ||||
| 210 | + | An identifier is a string that contains up to 32 printable ASCII bytes. | |||
| 211 | + | An identifier must not be an empty string. It is recommended that a | |||
| 212 | + | compositor includes an opaque generation value in identifiers. How the | |||
| 213 | + | generation value is used when generating the identifier is implementation | |||
| 214 | + | dependent. | |||
| 215 | + | </description> | |||
| 216 | + | <arg name="identifier" type="string"/> | |||
| 217 | + | </event> | |||
| 218 | + | </interface> | |||
| 219 | + | </protocol> | |||
A spec/xml/extidlenotify.xml +131 -0
| @@ -0,0 +1,131 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="ext_idle_notify_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2015 Martin Gräßlin | |||
| 5 | + | Copyright © 2022 Simon Ser | |||
| 6 | + | ||||
| 7 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 8 | + | copy of this software and associated documentation files (the "Software"), | |||
| 9 | + | to deal in the Software without restriction, including without limitation | |||
| 10 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 11 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 12 | + | Software is furnished to do so, subject to the following conditions: | |||
| 13 | + | ||||
| 14 | + | The above copyright notice and this permission notice (including the next | |||
| 15 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 16 | + | Software. | |||
| 17 | + | ||||
| 18 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 19 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 20 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 21 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 22 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 23 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 24 | + | DEALINGS IN THE SOFTWARE. | |||
| 25 | + | </copyright> | |||
| 26 | + | ||||
| 27 | + | <interface name="ext_idle_notifier_v1" version="2"> | |||
| 28 | + | <description summary="idle notification manager"> | |||
| 29 | + | This interface allows clients to monitor user idle status. | |||
| 30 | + | ||||
| 31 | + | After binding to this global, clients can create ext_idle_notification_v1 | |||
| 32 | + | objects to get notified when the user is idle for a given amount of time. | |||
| 33 | + | </description> | |||
| 34 | + | ||||
| 35 | + | <request name="destroy" type="destructor"> | |||
| 36 | + | <description summary="destroy the manager"> | |||
| 37 | + | Destroy the manager object. All objects created via this interface | |||
| 38 | + | remain valid. | |||
| 39 | + | </description> | |||
| 40 | + | </request> | |||
| 41 | + | ||||
| 42 | + | <request name="get_idle_notification"> | |||
| 43 | + | <description summary="create a notification object"> | |||
| 44 | + | Create a new idle notification object. | |||
| 45 | + | ||||
| 46 | + | The notification object has a minimum timeout duration and is tied to a | |||
| 47 | + | seat. The client will be notified if the seat is inactive for at least | |||
| 48 | + | the provided timeout. See ext_idle_notification_v1 for more details. | |||
| 49 | + | ||||
| 50 | + | A zero timeout is valid and means the client wants to be notified as | |||
| 51 | + | soon as possible when the seat is inactive. | |||
| 52 | + | </description> | |||
| 53 | + | <arg name="id" type="new_id" interface="ext_idle_notification_v1"/> | |||
| 54 | + | <arg name="timeout" type="uint" summary="minimum idle timeout in msec"/> | |||
| 55 | + | <arg name="seat" type="object" interface="wl_seat"/> | |||
| 56 | + | </request> | |||
| 57 | + | ||||
| 58 | + | <!-- Version 2 additions --> | |||
| 59 | + | ||||
| 60 | + | <request name="get_input_idle_notification" since="2"> | |||
| 61 | + | <description summary="create a notification object"> | |||
| 62 | + | Create a new idle notification object to track input from the | |||
| 63 | + | user, such as keyboard and mouse movement. Because this object is | |||
| 64 | + | meant to track user input alone, it ignores idle inhibitors. | |||
| 65 | + | ||||
| 66 | + | The notification object has a minimum timeout duration and is tied to a | |||
| 67 | + | seat. The client will be notified if the seat is inactive for at least | |||
| 68 | + | the provided timeout. See ext_idle_notification_v1 for more details. | |||
| 69 | + | ||||
| 70 | + | A zero timeout is valid and means the client wants to be notified as | |||
| 71 | + | soon as possible when the seat is inactive. | |||
| 72 | + | </description> | |||
| 73 | + | <arg name="id" type="new_id" interface="ext_idle_notification_v1"/> | |||
| 74 | + | <arg name="timeout" type="uint" summary="minimum idle timeout in msec"/> | |||
| 75 | + | <arg name="seat" type="object" interface="wl_seat"/> | |||
| 76 | + | </request> | |||
| 77 | + | ||||
| 78 | + | </interface> | |||
| 79 | + | ||||
| 80 | + | <interface name="ext_idle_notification_v1" version="2"> | |||
| 81 | + | <description summary="idle notification"> | |||
| 82 | + | This interface is used by the compositor to send idle notification events | |||
| 83 | + | to clients. | |||
| 84 | + | ||||
| 85 | + | Initially the notification object is not idle. The notification object | |||
| 86 | + | becomes idle when no user activity has happened for at least the timeout | |||
| 87 | + | duration, starting from the creation of the notification object. User | |||
| 88 | + | activity may include input events or a presence sensor, but is | |||
| 89 | + | compositor-specific. | |||
| 90 | + | ||||
| 91 | + | How this notification responds to idle inhibitors depends on how | |||
| 92 | + | it was constructed. If constructed from the | |||
| 93 | + | get_idle_notification request, then if an idle inhibitor is | |||
| 94 | + | active (e.g. another client has created a zwp_idle_inhibitor_v1 | |||
| 95 | + | on a visible surface), the compositor must not make the | |||
| 96 | + | notification object idle. However, if constructed from the | |||
| 97 | + | get_input_idle_notification request, then idle inhibitors are | |||
| 98 | + | ignored, and only input from the user, e.g. from a keyboard or | |||
| 99 | + | mouse, counts as activity. | |||
| 100 | + | ||||
| 101 | + | When the notification object becomes idle, an idled event is sent. When | |||
| 102 | + | user activity starts again, the notification object stops being idle, | |||
| 103 | + | a resumed event is sent and the timeout is restarted. | |||
| 104 | + | </description> | |||
| 105 | + | ||||
| 106 | + | <request name="destroy" type="destructor"> | |||
| 107 | + | <description summary="destroy the notification object"> | |||
| 108 | + | Destroy the notification object. | |||
| 109 | + | </description> | |||
| 110 | + | </request> | |||
| 111 | + | ||||
| 112 | + | <event name="idled"> | |||
| 113 | + | <description summary="notification object is idle"> | |||
| 114 | + | This event is sent when the notification object becomes idle. | |||
| 115 | + | ||||
| 116 | + | It's a compositor protocol error to send this event twice without a | |||
| 117 | + | resumed event in-between. | |||
| 118 | + | </description> | |||
| 119 | + | </event> | |||
| 120 | + | ||||
| 121 | + | <event name="resumed"> | |||
| 122 | + | <description summary="notification object is no longer idle"> | |||
| 123 | + | This event is sent when the notification object stops being idle. | |||
| 124 | + | ||||
| 125 | + | It's a compositor protocol error to send this event twice without an | |||
| 126 | + | idled event in-between. It's a compositor protocol error to send this | |||
| 127 | + | event prior to any idled event. | |||
| 128 | + | </description> | |||
| 129 | + | </event> | |||
| 130 | + | </interface> | |||
| 131 | + | </protocol> | |||
A spec/xml/extimagecapturesource.xml +109 -0
| @@ -0,0 +1,109 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="ext_image_capture_source_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2022 Andri Yngvason | |||
| 5 | + | Copyright © 2024 Simon Ser | |||
| 6 | + | ||||
| 7 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 8 | + | copy of this software and associated documentation files (the "Software"), | |||
| 9 | + | to deal in the Software without restriction, including without limitation | |||
| 10 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 11 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 12 | + | Software is furnished to do so, subject to the following conditions: | |||
| 13 | + | ||||
| 14 | + | The above copyright notice and this permission notice (including the next | |||
| 15 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 16 | + | Software. | |||
| 17 | + | ||||
| 18 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 19 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 20 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 21 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 22 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 23 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 24 | + | DEALINGS IN THE SOFTWARE. | |||
| 25 | + | </copyright> | |||
| 26 | + | ||||
| 27 | + | <description summary="opaque image capture source objects"> | |||
| 28 | + | This protocol serves as an intermediary between capturing protocols and | |||
| 29 | + | potential image capture sources such as outputs and toplevels. | |||
| 30 | + | ||||
| 31 | + | This protocol may be extended to support more image capture sources in the | |||
| 32 | + | future, thereby adding those image capture sources to other protocols that | |||
| 33 | + | use the image capture source object without having to modify those | |||
| 34 | + | protocols. | |||
| 35 | + | ||||
| 36 | + | Warning! The protocol described in this file is currently in the testing | |||
| 37 | + | phase. Backward compatible changes may be added together with the | |||
| 38 | + | corresponding interface version bump. Backward incompatible changes can | |||
| 39 | + | only be done by creating a new major version of the extension. | |||
| 40 | + | </description> | |||
| 41 | + | ||||
| 42 | + | <interface name="ext_image_capture_source_v1" version="1" frozen="true"> | |||
| 43 | + | <description summary="opaque image capture source object"> | |||
| 44 | + | The image capture source object is an opaque descriptor for a capturable | |||
| 45 | + | resource. This resource may be any sort of entity from which an image | |||
| 46 | + | may be derived. | |||
| 47 | + | ||||
| 48 | + | Note, because ext_image_capture_source_v1 objects are created from multiple | |||
| 49 | + | independent factory interfaces, the ext_image_capture_source_v1 interface is | |||
| 50 | + | frozen at version 1. | |||
| 51 | + | </description> | |||
| 52 | + | ||||
| 53 | + | <request name="destroy" type="destructor"> | |||
| 54 | + | <description summary="delete this object"> | |||
| 55 | + | Destroys the image capture source. This request may be sent at any time | |||
| 56 | + | by the client. | |||
| 57 | + | </description> | |||
| 58 | + | </request> | |||
| 59 | + | </interface> | |||
| 60 | + | ||||
| 61 | + | <interface name="ext_output_image_capture_source_manager_v1" version="1"> | |||
| 62 | + | <description summary="image capture source manager for outputs"> | |||
| 63 | + | A manager for creating image capture source objects for wl_output objects. | |||
| 64 | + | </description> | |||
| 65 | + | ||||
| 66 | + | <request name="create_source"> | |||
| 67 | + | <description summary="create source object for output"> | |||
| 68 | + | Creates a source object for an output. Images captured from this source | |||
| 69 | + | will show the same content as the output. Some elements may be omitted, | |||
| 70 | + | such as cursors and overlays that have been marked as transparent to | |||
| 71 | + | capturing. | |||
| 72 | + | </description> | |||
| 73 | + | <arg name="source" type="new_id" interface="ext_image_capture_source_v1"/> | |||
| 74 | + | <arg name="output" type="object" interface="wl_output"/> | |||
| 75 | + | </request> | |||
| 76 | + | ||||
| 77 | + | <request name="destroy" type="destructor"> | |||
| 78 | + | <description summary="delete this object"> | |||
| 79 | + | Destroys the manager. This request may be sent at any time by the client | |||
| 80 | + | and objects created by the manager will remain valid after its | |||
| 81 | + | destruction. | |||
| 82 | + | </description> | |||
| 83 | + | </request> | |||
| 84 | + | </interface> | |||
| 85 | + | ||||
| 86 | + | <interface name="ext_foreign_toplevel_image_capture_source_manager_v1" version="1"> | |||
| 87 | + | <description summary="image capture source manager for foreign toplevels"> | |||
| 88 | + | A manager for creating image capture source objects for | |||
| 89 | + | ext_foreign_toplevel_handle_v1 objects. | |||
| 90 | + | </description> | |||
| 91 | + | ||||
| 92 | + | <request name="create_source"> | |||
| 93 | + | <description summary="create source object for foreign toplevel"> | |||
| 94 | + | Creates a source object for a foreign toplevel handle. Images captured | |||
| 95 | + | from this source will show the same content as the toplevel. | |||
| 96 | + | </description> | |||
| 97 | + | <arg name="source" type="new_id" interface="ext_image_capture_source_v1"/> | |||
| 98 | + | <arg name="toplevel_handle" type="object" interface="ext_foreign_toplevel_handle_v1"/> | |||
| 99 | + | </request> | |||
| 100 | + | ||||
| 101 | + | <request name="destroy" type="destructor"> | |||
| 102 | + | <description summary="delete this object"> | |||
| 103 | + | Destroys the manager. This request may be sent at any time by the client | |||
| 104 | + | and objects created by the manager will remain valid after its | |||
| 105 | + | destruction. | |||
| 106 | + | </description> | |||
| 107 | + | </request> | |||
| 108 | + | </interface> | |||
| 109 | + | </protocol> | |||
A spec/xml/extimagecopycapture.xml +456 -0
| @@ -0,0 +1,456 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="ext_image_copy_capture_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2021-2023 Andri Yngvason | |||
| 5 | + | Copyright © 2024 Simon Ser | |||
| 6 | + | ||||
| 7 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 8 | + | copy of this software and associated documentation files (the "Software"), | |||
| 9 | + | to deal in the Software without restriction, including without limitation | |||
| 10 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 11 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 12 | + | Software is furnished to do so, subject to the following conditions: | |||
| 13 | + | ||||
| 14 | + | The above copyright notice and this permission notice (including the next | |||
| 15 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 16 | + | Software. | |||
| 17 | + | ||||
| 18 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 19 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 20 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 21 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 22 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 23 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 24 | + | DEALINGS IN THE SOFTWARE. | |||
| 25 | + | </copyright> | |||
| 26 | + | ||||
| 27 | + | <description summary="image capturing into client buffers"> | |||
| 28 | + | This protocol allows clients to ask the compositor to capture image sources | |||
| 29 | + | such as outputs and toplevels into user submitted buffers. | |||
| 30 | + | ||||
| 31 | + | Warning! The protocol described in this file is currently in the testing | |||
| 32 | + | phase. Backward compatible changes may be added together with the | |||
| 33 | + | corresponding interface version bump. Backward incompatible changes can | |||
| 34 | + | only be done by creating a new major version of the extension. | |||
| 35 | + | </description> | |||
| 36 | + | ||||
| 37 | + | <interface name="ext_image_copy_capture_manager_v1" version="1"> | |||
| 38 | + | <description summary="manager to inform clients and begin capturing"> | |||
| 39 | + | This object is a manager which offers requests to start capturing from a | |||
| 40 | + | source. | |||
| 41 | + | </description> | |||
| 42 | + | ||||
| 43 | + | <enum name="error"> | |||
| 44 | + | <entry name="invalid_option" value="1" summary="invalid option flag"/> | |||
| 45 | + | </enum> | |||
| 46 | + | ||||
| 47 | + | <enum name="options" bitfield="true"> | |||
| 48 | + | <entry name="paint_cursors" value="1" summary="paint cursors onto captured frames"/> | |||
| 49 | + | </enum> | |||
| 50 | + | ||||
| 51 | + | <request name="create_session"> | |||
| 52 | + | <description summary="capture an image capture source"> | |||
| 53 | + | Create a capturing session for an image capture source. | |||
| 54 | + | ||||
| 55 | + | If the paint_cursors option is set, cursors shall be composited onto | |||
| 56 | + | the captured frame. The cursor must not be composited onto the frame | |||
| 57 | + | if this flag is not set. | |||
| 58 | + | ||||
| 59 | + | If the options bitfield is invalid, the invalid_option protocol error | |||
| 60 | + | is sent. | |||
| 61 | + | </description> | |||
| 62 | + | <arg name="session" type="new_id" interface="ext_image_copy_capture_session_v1"/> | |||
| 63 | + | <arg name="source" type="object" interface="ext_image_capture_source_v1"/> | |||
| 64 | + | <arg name="options" type="uint" enum="options"/> | |||
| 65 | + | </request> | |||
| 66 | + | ||||
| 67 | + | <request name="create_pointer_cursor_session"> | |||
| 68 | + | <description summary="capture the pointer cursor of an image capture source"> | |||
| 69 | + | Create a cursor capturing session for the pointer of an image capture | |||
| 70 | + | source. | |||
| 71 | + | </description> | |||
| 72 | + | <arg name="session" type="new_id" interface="ext_image_copy_capture_cursor_session_v1"/> | |||
| 73 | + | <arg name="source" type="object" interface="ext_image_capture_source_v1"/> | |||
| 74 | + | <arg name="pointer" type="object" interface="wl_pointer"/> | |||
| 75 | + | </request> | |||
| 76 | + | ||||
| 77 | + | <request name="destroy" type="destructor"> | |||
| 78 | + | <description summary="destroy the manager"> | |||
| 79 | + | Destroy the manager object. | |||
| 80 | + | ||||
| 81 | + | Other objects created via this interface are unaffected. | |||
| 82 | + | </description> | |||
| 83 | + | </request> | |||
| 84 | + | </interface> | |||
| 85 | + | ||||
| 86 | + | <interface name="ext_image_copy_capture_session_v1" version="1"> | |||
| 87 | + | <description summary="image copy capture session"> | |||
| 88 | + | This object represents an active image copy capture session. | |||
| 89 | + | ||||
| 90 | + | After a capture session is created, buffer constraint events will be | |||
| 91 | + | emitted from the compositor to tell the client which buffer types and | |||
| 92 | + | formats are supported for reading from the session. The compositor may | |||
| 93 | + | re-send buffer constraint events whenever they change. | |||
| 94 | + | ||||
| 95 | + | To advertise buffer constraints, the compositor must send in no | |||
| 96 | + | particular order: zero or more shm_format and dmabuf_format events, zero | |||
| 97 | + | or one dmabuf_device event, and exactly one buffer_size event. Then the | |||
| 98 | + | compositor must send a done event. | |||
| 99 | + | ||||
| 100 | + | When the client has received all the buffer constraints, it can create a | |||
| 101 | + | buffer accordingly, attach it to the capture session using the | |||
| 102 | + | attach_buffer request, set the buffer damage using the damage_buffer | |||
| 103 | + | request and then send the capture request. | |||
| 104 | + | </description> | |||
| 105 | + | ||||
| 106 | + | <enum name="error"> | |||
| 107 | + | <entry name="duplicate_frame" value="1" | |||
| 108 | + | summary="create_frame sent before destroying previous frame"/> | |||
| 109 | + | </enum> | |||
| 110 | + | ||||
| 111 | + | <event name="buffer_size"> | |||
| 112 | + | <description summary="image capture source dimensions"> | |||
| 113 | + | Provides the dimensions of the source image in buffer pixel coordinates. | |||
| 114 | + | ||||
| 115 | + | The client must attach buffers that match this size. | |||
| 116 | + | </description> | |||
| 117 | + | <arg name="width" type="uint" summary="buffer width"/> | |||
| 118 | + | <arg name="height" type="uint" summary="buffer height"/> | |||
| 119 | + | </event> | |||
| 120 | + | ||||
| 121 | + | <event name="shm_format"> | |||
| 122 | + | <description summary="shm buffer format"> | |||
| 123 | + | Provides the format that must be used for shared-memory buffers. | |||
| 124 | + | ||||
| 125 | + | This event may be emitted multiple times, in which case the client may | |||
| 126 | + | choose any given format. | |||
| 127 | + | </description> | |||
| 128 | + | <arg name="format" type="uint" enum="wl_shm.format" summary="shm format"/> | |||
| 129 | + | </event> | |||
| 130 | + | ||||
| 131 | + | <event name="dmabuf_device"> | |||
| 132 | + | <description summary="dma-buf device"> | |||
| 133 | + | This event advertises the device buffers must be allocated on for | |||
| 134 | + | dma-buf buffers. | |||
| 135 | + | ||||
| 136 | + | In general the device is a DRM node. The DRM node type (primary vs. | |||
| 137 | + | render) is unspecified. Clients must not rely on the compositor sending | |||
| 138 | + | a particular node type. Clients cannot check two devices for equality | |||
| 139 | + | by comparing the dev_t value. | |||
| 140 | + | </description> | |||
| 141 | + | <arg name="device" type="array" summary="device dev_t value"/> | |||
| 142 | + | </event> | |||
| 143 | + | ||||
| 144 | + | <event name="dmabuf_format"> | |||
| 145 | + | <description summary="dma-buf format"> | |||
| 146 | + | Provides the format that must be used for dma-buf buffers. | |||
| 147 | + | ||||
| 148 | + | The client may choose any of the modifiers advertised in the array of | |||
| 149 | + | 64-bit unsigned integers. | |||
| 150 | + | ||||
| 151 | + | This event may be emitted multiple times, in which case the client may | |||
| 152 | + | choose any given format. | |||
| 153 | + | </description> | |||
| 154 | + | <arg name="format" type="uint" summary="drm format code"/> | |||
| 155 | + | <arg name="modifiers" type="array" summary="drm format modifiers"/> | |||
| 156 | + | </event> | |||
| 157 | + | ||||
| 158 | + | <event name="done"> | |||
| 159 | + | <description summary="all constraints have been sent"> | |||
| 160 | + | This event is sent once when all buffer constraint events have been | |||
| 161 | + | sent. | |||
| 162 | + | ||||
| 163 | + | The compositor must always end a batch of buffer constraint events with | |||
| 164 | + | this event, regardless of whether it sends the initial constraints or | |||
| 165 | + | an update. | |||
| 166 | + | </description> | |||
| 167 | + | </event> | |||
| 168 | + | ||||
| 169 | + | <event name="stopped"> | |||
| 170 | + | <description summary="session is no longer available"> | |||
| 171 | + | This event indicates that the capture session has stopped and is no | |||
| 172 | + | longer available. This can happen in a number of cases, e.g. when the | |||
| 173 | + | underlying source is destroyed, if the user decides to end the image | |||
| 174 | + | capture, or if an unrecoverable runtime error has occurred. | |||
| 175 | + | ||||
| 176 | + | The client should destroy the session after receiving this event. | |||
| 177 | + | </description> | |||
| 178 | + | </event> | |||
| 179 | + | ||||
| 180 | + | <request name="create_frame"> | |||
| 181 | + | <description summary="create a frame"> | |||
| 182 | + | Create a capture frame for this session. | |||
| 183 | + | ||||
| 184 | + | At most one frame object can exist for a given session at any time. If | |||
| 185 | + | a client sends a create_frame request before a previous frame object | |||
| 186 | + | has been destroyed, the duplicate_frame protocol error is raised. | |||
| 187 | + | </description> | |||
| 188 | + | <arg name="frame" type="new_id" interface="ext_image_copy_capture_frame_v1"/> | |||
| 189 | + | </request> | |||
| 190 | + | ||||
| 191 | + | <request name="destroy" type="destructor"> | |||
| 192 | + | <description summary="delete this object"> | |||
| 193 | + | Destroys the session. This request can be sent at any time by the | |||
| 194 | + | client. | |||
| 195 | + | ||||
| 196 | + | This request doesn't affect ext_image_copy_capture_frame_v1 objects created by | |||
| 197 | + | this object. | |||
| 198 | + | </description> | |||
| 199 | + | </request> | |||
| 200 | + | </interface> | |||
| 201 | + | ||||
| 202 | + | <interface name="ext_image_copy_capture_frame_v1" version="1"> | |||
| 203 | + | <description summary="image capture frame"> | |||
| 204 | + | This object represents an image capture frame. | |||
| 205 | + | ||||
| 206 | + | The client should attach a buffer, damage the buffer, and then send a | |||
| 207 | + | capture request. | |||
| 208 | + | ||||
| 209 | + | If the capture is successful, the compositor must send the frame metadata | |||
| 210 | + | (transform, damage, presentation_time in any order) followed by the ready | |||
| 211 | + | event. | |||
| 212 | + | ||||
| 213 | + | If the capture fails, the compositor must send the failed event. | |||
| 214 | + | </description> | |||
| 215 | + | ||||
| 216 | + | <enum name="error"> | |||
| 217 | + | <entry name="no_buffer" value="1" summary="capture sent without attach_buffer"/> | |||
| 218 | + | <entry name="invalid_buffer_damage" value="2" summary="invalid buffer damage"/> | |||
| 219 | + | <entry name="already_captured" value="3" summary="capture request has been sent"/> | |||
| 220 | + | </enum> | |||
| 221 | + | ||||
| 222 | + | <request name="destroy" type="destructor"> | |||
| 223 | + | <description summary="destroy this object"> | |||
| 224 | + | Destroys the frame. This request can be sent at any time by the | |||
| 225 | + | client. | |||
| 226 | + | </description> | |||
| 227 | + | </request> | |||
| 228 | + | ||||
| 229 | + | <request name="attach_buffer"> | |||
| 230 | + | <description summary="attach buffer to session"> | |||
| 231 | + | Attach a buffer to the session. | |||
| 232 | + | ||||
| 233 | + | The wl_buffer.release request is unused. | |||
| 234 | + | ||||
| 235 | + | The new buffer replaces any previously attached buffer. | |||
| 236 | + | ||||
| 237 | + | This request must not be sent after capture, or else the | |||
| 238 | + | already_captured protocol error is raised. | |||
| 239 | + | </description> | |||
| 240 | + | <arg name="buffer" type="object" interface="wl_buffer"/> | |||
| 241 | + | </request> | |||
| 242 | + | ||||
| 243 | + | <request name="damage_buffer"> | |||
| 244 | + | <description summary="damage buffer"> | |||
| 245 | + | Apply damage to the buffer which is to be captured next. This request | |||
| 246 | + | may be sent multiple times to describe a region. | |||
| 247 | + | ||||
| 248 | + | The client indicates the accumulated damage since this wl_buffer was | |||
| 249 | + | last captured. During capture, the compositor will update the buffer | |||
| 250 | + | with at least the union of the region passed by the client and the | |||
| 251 | + | region advertised by ext_image_copy_capture_frame_v1.damage. | |||
| 252 | + | ||||
| 253 | + | When a wl_buffer is captured for the first time, or when the client | |||
| 254 | + | doesn't track damage, the client must damage the whole buffer. | |||
| 255 | + | ||||
| 256 | + | This is for optimisation purposes. The compositor may use this | |||
| 257 | + | information to reduce copying. | |||
| 258 | + | ||||
| 259 | + | These coordinates originate from the upper left corner of the buffer. | |||
| 260 | + | ||||
| 261 | + | If x or y are strictly negative, or if width or height are negative or | |||
| 262 | + | zero, the invalid_buffer_damage protocol error is raised. | |||
| 263 | + | ||||
| 264 | + | This request must not be sent after capture, or else the | |||
| 265 | + | already_captured protocol error is raised. | |||
| 266 | + | </description> | |||
| 267 | + | <arg name="x" type="int" summary="region x coordinate"/> | |||
| 268 | + | <arg name="y" type="int" summary="region y coordinate"/> | |||
| 269 | + | <arg name="width" type="int" summary="region width"/> | |||
| 270 | + | <arg name="height" type="int" summary="region height"/> | |||
| 271 | + | </request> | |||
| 272 | + | ||||
| 273 | + | <request name="capture"> | |||
| 274 | + | <description summary="capture a frame"> | |||
| 275 | + | Capture a frame. | |||
| 276 | + | ||||
| 277 | + | Unless this is the first successful captured frame performed in this | |||
| 278 | + | session, the compositor may wait an indefinite amount of time for the | |||
| 279 | + | source content to change before performing the copy. | |||
| 280 | + | ||||
| 281 | + | This request may only be sent once, or else the already_captured | |||
| 282 | + | protocol error is raised. A buffer must be attached before this request | |||
| 283 | + | is sent, or else the no_buffer protocol error is raised. | |||
| 284 | + | </description> | |||
| 285 | + | </request> | |||
| 286 | + | ||||
| 287 | + | <event name="transform"> | |||
| 288 | + | <description summary="buffer transform"> | |||
| 289 | + | This event is sent before the ready event and holds the transform that | |||
| 290 | + | the compositor has applied to the buffer contents. | |||
| 291 | + | </description> | |||
| 292 | + | <arg name="transform" type="uint" enum="wl_output.transform"/> | |||
| 293 | + | </event> | |||
| 294 | + | ||||
| 295 | + | <event name="damage"> | |||
| 296 | + | <description summary="buffer damaged region"> | |||
| 297 | + | This event is sent before the ready event. It may be generated multiple | |||
| 298 | + | times to describe a region. | |||
| 299 | + | ||||
| 300 | + | The first captured frame in a session will always carry full damage. | |||
| 301 | + | Subsequent frames' damaged regions describe which parts of the buffer | |||
| 302 | + | have changed since the last ready event. | |||
| 303 | + | ||||
| 304 | + | These coordinates originate in the upper left corner of the buffer. | |||
| 305 | + | </description> | |||
| 306 | + | <arg name="x" type="int" summary="damage x coordinate"/> | |||
| 307 | + | <arg name="y" type="int" summary="damage y coordinate"/> | |||
| 308 | + | <arg name="width" type="int" summary="damage width"/> | |||
| 309 | + | <arg name="height" type="int" summary="damage height"/> | |||
| 310 | + | </event> | |||
| 311 | + | ||||
| 312 | + | <event name="presentation_time"> | |||
| 313 | + | <description summary="presentation time of the frame"> | |||
| 314 | + | This event indicates the time at which the frame is presented to the | |||
| 315 | + | output in system monotonic time. This event is sent before the ready | |||
| 316 | + | event. | |||
| 317 | + | ||||
| 318 | + | The timestamp is expressed as tv_sec_hi, tv_sec_lo, tv_nsec triples, | |||
| 319 | + | each component being an unsigned 32-bit value. Whole seconds are in | |||
| 320 | + | tv_sec which is a 64-bit value combined from tv_sec_hi and tv_sec_lo, | |||
| 321 | + | and the additional fractional part in tv_nsec as nanoseconds. Hence, | |||
| 322 | + | for valid timestamps tv_nsec must be in [0, 999999999]. | |||
| 323 | + | </description> | |||
| 324 | + | <arg name="tv_sec_hi" type="uint" | |||
| 325 | + | summary="high 32 bits of the seconds part of the timestamp"/> | |||
| 326 | + | <arg name="tv_sec_lo" type="uint" | |||
| 327 | + | summary="low 32 bits of the seconds part of the timestamp"/> | |||
| 328 | + | <arg name="tv_nsec" type="uint" | |||
| 329 | + | summary="nanoseconds part of the timestamp"/> | |||
| 330 | + | </event> | |||
| 331 | + | ||||
| 332 | + | <event name="ready"> | |||
| 333 | + | <description summary="frame is available for reading"> | |||
| 334 | + | Called as soon as the frame is copied, indicating it is available | |||
| 335 | + | for reading. | |||
| 336 | + | ||||
| 337 | + | The buffer may be re-used by the client after this event. | |||
| 338 | + | ||||
| 339 | + | After receiving this event, the client must destroy the object. | |||
| 340 | + | </description> | |||
| 341 | + | </event> | |||
| 342 | + | ||||
| 343 | + | <enum name="failure_reason"> | |||
| 344 | + | <entry name="unknown" value="0"> | |||
| 345 | + | <description summary="unknown runtime error"> | |||
| 346 | + | An unspecified runtime error has occurred. The client may retry. | |||
| 347 | + | </description> | |||
| 348 | + | </entry> | |||
| 349 | + | <entry name="buffer_constraints" value="1"> | |||
| 350 | + | <description summary="buffer constraints mismatch"> | |||
| 351 | + | The buffer submitted by the client doesn't match the latest session | |||
| 352 | + | constraints. The client should re-allocate its buffers and retry. | |||
| 353 | + | </description> | |||
| 354 | + | </entry> | |||
| 355 | + | <entry name="stopped" value="2"> | |||
| 356 | + | <description summary="session is no longer available"> | |||
| 357 | + | The session has stopped. See ext_image_copy_capture_session_v1.stopped. | |||
| 358 | + | </description> | |||
| 359 | + | </entry> | |||
| 360 | + | </enum> | |||
| 361 | + | ||||
| 362 | + | <event name="failed"> | |||
| 363 | + | <description summary="capture failed"> | |||
| 364 | + | This event indicates that the attempted frame copy has failed. | |||
| 365 | + | ||||
| 366 | + | After receiving this event, the client must destroy the object. | |||
| 367 | + | </description> | |||
| 368 | + | <arg name="reason" type="uint" enum="failure_reason"/> | |||
| 369 | + | </event> | |||
| 370 | + | </interface> | |||
| 371 | + | ||||
| 372 | + | <interface name="ext_image_copy_capture_cursor_session_v1" version="1"> | |||
| 373 | + | <description summary="cursor capture session"> | |||
| 374 | + | This object represents a cursor capture session. It extends the base | |||
| 375 | + | capture session with cursor-specific metadata. | |||
| 376 | + | </description> | |||
| 377 | + | ||||
| 378 | + | <enum name="error"> | |||
| 379 | + | <entry name="duplicate_session" value="1" summary="get_capture_session sent twice"/> | |||
| 380 | + | </enum> | |||
| 381 | + | ||||
| 382 | + | <request name="destroy" type="destructor"> | |||
| 383 | + | <description summary="delete this object"> | |||
| 384 | + | Destroys the session. This request can be sent at any time by the | |||
| 385 | + | client. | |||
| 386 | + | ||||
| 387 | + | This request doesn't affect ext_image_copy_capture_frame_v1 objects created by | |||
| 388 | + | this object. | |||
| 389 | + | </description> | |||
| 390 | + | </request> | |||
| 391 | + | ||||
| 392 | + | <request name="get_capture_session"> | |||
| 393 | + | <description summary="get image copy capturer session"> | |||
| 394 | + | Gets the image copy capture session for this cursor session. | |||
| 395 | + | ||||
| 396 | + | The session will produce frames of the cursor image. The compositor may | |||
| 397 | + | pause the session when the cursor leaves the captured area. | |||
| 398 | + | ||||
| 399 | + | This request must not be sent more than once, or else the | |||
| 400 | + | duplicate_session protocol error is raised. | |||
| 401 | + | </description> | |||
| 402 | + | <arg name="session" type="new_id" interface="ext_image_copy_capture_session_v1"/> | |||
| 403 | + | </request> | |||
| 404 | + | ||||
| 405 | + | <event name="enter"> | |||
| 406 | + | <description summary="cursor entered captured area"> | |||
| 407 | + | Sent when a cursor enters the captured area. It shall be generated | |||
| 408 | + | before the "position" and "hotspot" events when and only when a cursor | |||
| 409 | + | enters the area. | |||
| 410 | + | ||||
| 411 | + | The cursor enters the captured area when the cursor image intersects | |||
| 412 | + | with the captured area. Note, this is different from e.g. | |||
| 413 | + | wl_pointer.enter. | |||
| 414 | + | </description> | |||
| 415 | + | </event> | |||
| 416 | + | ||||
| 417 | + | <event name="leave"> | |||
| 418 | + | <description summary="cursor left captured area"> | |||
| 419 | + | Sent when a cursor leaves the captured area. No "position" or "hotspot" | |||
| 420 | + | event is generated for the cursor until the cursor enters the captured | |||
| 421 | + | area again. | |||
| 422 | + | </description> | |||
| 423 | + | </event> | |||
| 424 | + | ||||
| 425 | + | <event name="position"> | |||
| 426 | + | <description summary="position changed"> | |||
| 427 | + | Cursors outside the image capture source do not get captured and no | |||
| 428 | + | event will be generated for them. | |||
| 429 | + | ||||
| 430 | + | The given position is the position of the cursor's hotspot and it is | |||
| 431 | + | relative to the main buffer's top left corner in transformed buffer | |||
| 432 | + | pixel coordinates. The coordinates may be negative or greater than the | |||
| 433 | + | main buffer size. | |||
| 434 | + | </description> | |||
| 435 | + | <arg name="x" type="int" summary="position x coordinates"/> | |||
| 436 | + | <arg name="y" type="int" summary="position y coordinates"/> | |||
| 437 | + | </event> | |||
| 438 | + | ||||
| 439 | + | <event name="hotspot"> | |||
| 440 | + | <description summary="hotspot changed"> | |||
| 441 | + | The hotspot describes the offset between the cursor image and the | |||
| 442 | + | position of the input device. | |||
| 443 | + | ||||
| 444 | + | The given coordinates are the hotspot's offset from the origin in | |||
| 445 | + | buffer coordinates. | |||
| 446 | + | ||||
| 447 | + | Clients should not apply the hotspot immediately: the hotspot becomes | |||
| 448 | + | effective when the next ext_image_copy_capture_frame_v1.ready event is received. | |||
| 449 | + | ||||
| 450 | + | Compositors may delay this event until the client captures a new frame. | |||
| 451 | + | </description> | |||
| 452 | + | <arg name="x" type="int" summary="hotspot x coordinates"/> | |||
| 453 | + | <arg name="y" type="int" summary="hotspot y coordinates"/> | |||
| 454 | + | </event> | |||
| 455 | + | </interface> | |||
| 456 | + | </protocol> | |||
A spec/xml/extsessionlock.xml +328 -0
| @@ -0,0 +1,328 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="ext_session_lock_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright 2021 Isaac Freund | |||
| 5 | + | ||||
| 6 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 7 | + | copy of this software and associated documentation files (the "Software"), | |||
| 8 | + | to deal in the Software without restriction, including without limitation | |||
| 9 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 10 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 11 | + | Software is furnished to do so, subject to the following conditions: | |||
| 12 | + | ||||
| 13 | + | The above copyright notice and this permission notice shall be included in | |||
| 14 | + | all copies or substantial portions of the Software. | |||
| 15 | + | ||||
| 16 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 17 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 18 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 19 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 20 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
| 21 | + | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||
| 22 | + | THE SOFTWARE. | |||
| 23 | + | </copyright> | |||
| 24 | + | ||||
| 25 | + | <description summary="secure session locking with arbitrary graphics"> | |||
| 26 | + | This protocol allows for a privileged Wayland client to lock the session | |||
| 27 | + | and display arbitrary graphics while the session is locked. | |||
| 28 | + | ||||
| 29 | + | The compositor may choose to restrict this protocol to a special client | |||
| 30 | + | launched by the compositor itself or expose it to all privileged clients, | |||
| 31 | + | this is compositor policy. | |||
| 32 | + | ||||
| 33 | + | The client is responsible for performing authentication and informing the | |||
| 34 | + | compositor when the session should be unlocked. If the client dies while | |||
| 35 | + | the session is locked the session remains locked, possibly permanently | |||
| 36 | + | depending on compositor policy. | |||
| 37 | + | ||||
| 38 | + | The key words "must", "must not", "required", "shall", "shall not", | |||
| 39 | + | "should", "should not", "recommended", "may", and "optional" in this | |||
| 40 | + | document are to be interpreted as described in IETF RFC 2119. | |||
| 41 | + | ||||
| 42 | + | Warning! The protocol described in this file is currently in the | |||
| 43 | + | testing phase. Backward compatible changes may be added together with | |||
| 44 | + | the corresponding interface version bump. Backward incompatible changes | |||
| 45 | + | can only be done by creating a new major version of the extension. | |||
| 46 | + | </description> | |||
| 47 | + | ||||
| 48 | + | <interface name="ext_session_lock_manager_v1" version="1"> | |||
| 49 | + | <description summary="used to lock the session"> | |||
| 50 | + | This interface is used to request that the session be locked. | |||
| 51 | + | </description> | |||
| 52 | + | ||||
| 53 | + | <request name="destroy" type="destructor"> | |||
| 54 | + | <description summary="destroy the session lock manager object"> | |||
| 55 | + | This informs the compositor that the session lock manager object will | |||
| 56 | + | no longer be used. Existing objects created through this interface | |||
| 57 | + | remain valid. | |||
| 58 | + | </description> | |||
| 59 | + | </request> | |||
| 60 | + | ||||
| 61 | + | <request name="lock"> | |||
| 62 | + | <description summary="attempt to lock the session"> | |||
| 63 | + | This request creates a session lock and asks the compositor to lock the | |||
| 64 | + | session. The compositor will send either the ext_session_lock_v1.locked | |||
| 65 | + | or ext_session_lock_v1.finished event on the created object in | |||
| 66 | + | response to this request. | |||
| 67 | + | </description> | |||
| 68 | + | <arg name="id" type="new_id" interface="ext_session_lock_v1"/> | |||
| 69 | + | </request> | |||
| 70 | + | </interface> | |||
| 71 | + | ||||
| 72 | + | <interface name="ext_session_lock_v1" version="1"> | |||
| 73 | + | <description summary="manage lock state and create lock surfaces"> | |||
| 74 | + | In response to the creation of this object the compositor must send | |||
| 75 | + | either the locked or finished event. | |||
| 76 | + | ||||
| 77 | + | The locked event indicates that the session is locked. This means | |||
| 78 | + | that the compositor must stop rendering and providing input to normal | |||
| 79 | + | clients. Instead the compositor must blank all outputs with an opaque | |||
| 80 | + | color such that their normal content is fully hidden. | |||
| 81 | + | ||||
| 82 | + | The only surfaces that should be rendered while the session is locked | |||
| 83 | + | are the lock surfaces created through this interface and optionally, | |||
| 84 | + | at the compositor's discretion, special privileged surfaces such as | |||
| 85 | + | input methods or portions of desktop shell UIs. | |||
| 86 | + | ||||
| 87 | + | The locked event must not be sent until a new "locked" frame (either | |||
| 88 | + | from a session lock surface or the compositor blanking the output) has | |||
| 89 | + | been presented on all outputs and no security sensitive normal/unlocked | |||
| 90 | + | content is possibly visible. | |||
| 91 | + | ||||
| 92 | + | The finished event should be sent immediately on creation of this | |||
| 93 | + | object if the compositor decides that the locked event will not be sent. | |||
| 94 | + | ||||
| 95 | + | The compositor may wait for the client to create and render session lock | |||
| 96 | + | surfaces before sending the locked event to avoid displaying intermediate | |||
| 97 | + | blank frames. However, it must impose a reasonable time limit if | |||
| 98 | + | waiting and send the locked event as soon as the hard requirements | |||
| 99 | + | described above can be met if the time limit expires. Clients should | |||
| 100 | + | immediately create lock surfaces for all outputs on creation of this | |||
| 101 | + | object to make this possible. | |||
| 102 | + | ||||
| 103 | + | This behavior of the locked event is required in order to prevent | |||
| 104 | + | possible race conditions with clients that wish to suspend the system | |||
| 105 | + | or similar after locking the session. Without these semantics, clients | |||
| 106 | + | triggering a suspend after receiving the locked event would race with | |||
| 107 | + | the first "locked" frame being presented and normal/unlocked frames | |||
| 108 | + | might be briefly visible as the system is resumed if the suspend | |||
| 109 | + | operation wins the race. | |||
| 110 | + | ||||
| 111 | + | If the client dies while the session is locked, the compositor must not | |||
| 112 | + | unlock the session in response. It is acceptable for the session to be | |||
| 113 | + | permanently locked if this happens. The compositor may choose to continue | |||
| 114 | + | to display the lock surfaces the client had mapped before it died or | |||
| 115 | + | alternatively fall back to a solid color, this is compositor policy. | |||
| 116 | + | ||||
| 117 | + | Compositors may also allow a secure way to recover the session, the | |||
| 118 | + | details of this are compositor policy. Compositors may allow a new | |||
| 119 | + | client to create a ext_session_lock_v1 object and take responsibility | |||
| 120 | + | for unlocking the session, they may even start a new lock client | |||
| 121 | + | instance automatically. | |||
| 122 | + | </description> | |||
| 123 | + | ||||
| 124 | + | <enum name="error"> | |||
| 125 | + | <entry name="invalid_destroy" value="0" | |||
| 126 | + | summary="attempted to destroy session lock while locked"/> | |||
| 127 | + | <entry name="invalid_unlock" value="1" | |||
| 128 | + | summary="unlock requested but locked event was never sent"/> | |||
| 129 | + | <entry name="role" value="2" | |||
| 130 | + | summary="given wl_surface already has a role"/> | |||
| 131 | + | <entry name="duplicate_output" value="3" | |||
| 132 | + | summary="given output already has a lock surface"/> | |||
| 133 | + | <entry name="already_constructed" value="4" | |||
| 134 | + | summary="given wl_surface has a buffer attached or committed"/> | |||
| 135 | + | </enum> | |||
| 136 | + | ||||
| 137 | + | <request name="destroy" type="destructor"> | |||
| 138 | + | <description summary="destroy the session lock"> | |||
| 139 | + | This informs the compositor that the lock object will no longer be | |||
| 140 | + | used. Existing objects created through this interface remain valid. | |||
| 141 | + | ||||
| 142 | + | After this request is made, lock surfaces created through this object | |||
| 143 | + | should be destroyed by the client as they will no longer be used by | |||
| 144 | + | the compositor. | |||
| 145 | + | ||||
| 146 | + | It is a protocol error to make this request if the locked event was | |||
| 147 | + | sent, the unlock_and_destroy request must be used instead. | |||
| 148 | + | </description> | |||
| 149 | + | </request> | |||
| 150 | + | ||||
| 151 | + | <event name="locked"> | |||
| 152 | + | <description summary="session successfully locked"> | |||
| 153 | + | This client is now responsible for displaying graphics while the | |||
| 154 | + | session is locked and deciding when to unlock the session. | |||
| 155 | + | ||||
| 156 | + | The locked event must not be sent until a new "locked" frame has been | |||
| 157 | + | presented on all outputs and no security sensitive normal/unlocked | |||
| 158 | + | content is possibly visible. | |||
| 159 | + | ||||
| 160 | + | If this event is sent, making the destroy request is a protocol error, | |||
| 161 | + | the lock object must be destroyed using the unlock_and_destroy request. | |||
| 162 | + | </description> | |||
| 163 | + | </event> | |||
| 164 | + | ||||
| 165 | + | <event name="finished"> | |||
| 166 | + | <description summary="the session lock object should be destroyed"> | |||
| 167 | + | The compositor has decided that the session lock should be destroyed | |||
| 168 | + | as it will no longer be used by the compositor. Exactly when this | |||
| 169 | + | event is sent is compositor policy, but it must never be sent more | |||
| 170 | + | than once for a given session lock object. | |||
| 171 | + | ||||
| 172 | + | This might be sent because there is already another ext_session_lock_v1 | |||
| 173 | + | object held by a client, or the compositor has decided to deny the | |||
| 174 | + | request to lock the session for some other reason. This might also | |||
| 175 | + | be sent because the compositor implements some alternative, secure | |||
| 176 | + | way to authenticate and unlock the session. | |||
| 177 | + | ||||
| 178 | + | The finished event should be sent immediately on creation of this | |||
| 179 | + | object if the compositor decides that the locked event will not | |||
| 180 | + | be sent. | |||
| 181 | + | ||||
| 182 | + | If the locked event is sent on creation of this object the finished | |||
| 183 | + | event may still be sent at some later time in this object's | |||
| 184 | + | lifetime. This is compositor policy. | |||
| 185 | + | ||||
| 186 | + | Upon receiving this event, the client should make either the destroy | |||
| 187 | + | request or the unlock_and_destroy request, depending on whether or | |||
| 188 | + | not the locked event was received on this object. | |||
| 189 | + | </description> | |||
| 190 | + | </event> | |||
| 191 | + | ||||
| 192 | + | <request name="get_lock_surface"> | |||
| 193 | + | <description summary="create a lock surface for a given output"> | |||
| 194 | + | The client is expected to create lock surfaces for all outputs | |||
| 195 | + | currently present and any new outputs as they are advertised. These | |||
| 196 | + | won't be displayed by the compositor unless the lock is successful | |||
| 197 | + | and the locked event is sent. | |||
| 198 | + | ||||
| 199 | + | Providing a wl_surface which already has a role or already has a buffer | |||
| 200 | + | attached or committed is a protocol error, as is attaching/committing | |||
| 201 | + | a buffer before the first ext_session_lock_surface_v1.configure event. | |||
| 202 | + | ||||
| 203 | + | Attempting to create more than one lock surface for a given output | |||
| 204 | + | is a duplicate_output protocol error. | |||
| 205 | + | </description> | |||
| 206 | + | <arg name="id" type="new_id" interface="ext_session_lock_surface_v1"/> | |||
| 207 | + | <arg name="surface" type="object" interface="wl_surface"/> | |||
| 208 | + | <arg name="output" type="object" interface="wl_output"/> | |||
| 209 | + | </request> | |||
| 210 | + | ||||
| 211 | + | <request name="unlock_and_destroy" type="destructor"> | |||
| 212 | + | <description summary="unlock the session, destroying the object"> | |||
| 213 | + | This request indicates that the session should be unlocked, for | |||
| 214 | + | example because the user has entered their password and it has been | |||
| 215 | + | verified by the client. | |||
| 216 | + | ||||
| 217 | + | This request also informs the compositor that the lock object will | |||
| 218 | + | no longer be used and should be destroyed. Existing objects created | |||
| 219 | + | through this interface remain valid. | |||
| 220 | + | ||||
| 221 | + | After this request is made, lock surfaces created through this object | |||
| 222 | + | should be destroyed by the client as they will no longer be used by | |||
| 223 | + | the compositor. | |||
| 224 | + | ||||
| 225 | + | It is a protocol error to make this request if the locked event has | |||
| 226 | + | not been sent. In that case, the lock object must be destroyed using | |||
| 227 | + | the destroy request. | |||
| 228 | + | ||||
| 229 | + | Note that a correct client that wishes to exit directly after unlocking | |||
| 230 | + | the session must use the wl_display.sync request to ensure the server | |||
| 231 | + | receives and processes the unlock_and_destroy request. Otherwise | |||
| 232 | + | there is no guarantee that the server has unlocked the session due | |||
| 233 | + | to the asynchronous nature of the Wayland protocol. For example, | |||
| 234 | + | the server might terminate the client with a protocol error before | |||
| 235 | + | it processes the unlock_and_destroy request. | |||
| 236 | + | </description> | |||
| 237 | + | </request> | |||
| 238 | + | </interface> | |||
| 239 | + | ||||
| 240 | + | <interface name="ext_session_lock_surface_v1" version="1"> | |||
| 241 | + | <description summary="a surface displayed while the session is locked"> | |||
| 242 | + | The client may use lock surfaces to display a screensaver, render a | |||
| 243 | + | dialog to enter a password and unlock the session, or however else it | |||
| 244 | + | sees fit. | |||
| 245 | + | ||||
| 246 | + | On binding this interface the compositor will immediately send the | |||
| 247 | + | first configure event. After making the ack_configure request in | |||
| 248 | + | response to this event the client should attach and commit the first | |||
| 249 | + | buffer. Committing the surface before acking the first configure is a | |||
| 250 | + | protocol error. Committing the surface with a null buffer at any time | |||
| 251 | + | is a protocol error. | |||
| 252 | + | ||||
| 253 | + | The compositor is free to handle keyboard/pointer focus for lock | |||
| 254 | + | surfaces however it chooses. A reasonable way to do this would be to | |||
| 255 | + | give the first lock surface created keyboard focus and change keyboard | |||
| 256 | + | focus if the user clicks on other surfaces. | |||
| 257 | + | </description> | |||
| 258 | + | ||||
| 259 | + | <enum name="error"> | |||
| 260 | + | <entry name="commit_before_first_ack" value="0" | |||
| 261 | + | summary="surface committed before first ack_configure request"/> | |||
| 262 | + | <entry name="null_buffer" value="1" | |||
| 263 | + | summary="surface committed with a null buffer"/> | |||
| 264 | + | <entry name="dimensions_mismatch" value="2" | |||
| 265 | + | summary="failed to match ack'd width/height"/> | |||
| 266 | + | <entry name="invalid_serial" value="3" | |||
| 267 | + | summary="serial provided in ack_configure is invalid"/> | |||
| 268 | + | </enum> | |||
| 269 | + | ||||
| 270 | + | <request name="destroy" type="destructor"> | |||
| 271 | + | <description summary="destroy the lock surface object"> | |||
| 272 | + | This informs the compositor that the lock surface object will no | |||
| 273 | + | longer be used. | |||
| 274 | + | ||||
| 275 | + | It is recommended for a lock client to destroy lock surfaces if | |||
| 276 | + | their corresponding wl_output global is removed. | |||
| 277 | + | ||||
| 278 | + | If a lock surface on an active output is destroyed before the | |||
| 279 | + | ext_session_lock_v1.unlock_and_destroy event is sent, the compositor | |||
| 280 | + | must fall back to rendering a solid color. | |||
| 281 | + | </description> | |||
| 282 | + | </request> | |||
| 283 | + | ||||
| 284 | + | <request name="ack_configure"> | |||
| 285 | + | <description summary="ack a configure event"> | |||
| 286 | + | When a configure event is received, if a client commits the surface | |||
| 287 | + | in response to the configure event, then the client must make an | |||
| 288 | + | ack_configure request sometime before the commit request, passing | |||
| 289 | + | along the serial of the configure event. | |||
| 290 | + | ||||
| 291 | + | If the client receives multiple configure events before it can | |||
| 292 | + | respond to one, it only has to ack the last configure event. | |||
| 293 | + | ||||
| 294 | + | A client is not required to commit immediately after sending an | |||
| 295 | + | ack_configure request - it may even ack_configure several times | |||
| 296 | + | before its next surface commit. | |||
| 297 | + | ||||
| 298 | + | A client may send multiple ack_configure requests before committing, | |||
| 299 | + | but only the last request sent before a commit indicates which | |||
| 300 | + | configure event the client really is responding to. | |||
| 301 | + | ||||
| 302 | + | Sending an ack_configure request consumes the configure event | |||
| 303 | + | referenced by the given serial, as well as all older configure events | |||
| 304 | + | sent on this object. | |||
| 305 | + | ||||
| 306 | + | It is a protocol error to issue multiple ack_configure requests | |||
| 307 | + | referencing the same configure event or to issue an ack_configure | |||
| 308 | + | request referencing a configure event older than the last configure | |||
| 309 | + | event acked for a given lock surface. | |||
| 310 | + | </description> | |||
| 311 | + | <arg name="serial" type="uint" summary="serial from the configure event"/> | |||
| 312 | + | </request> | |||
| 313 | + | ||||
| 314 | + | <event name="configure"> | |||
| 315 | + | <description summary="the client should resize its surface"> | |||
| 316 | + | This event is sent once on binding the interface and may be sent again | |||
| 317 | + | at the compositor's discretion, for example if output geometry changes. | |||
| 318 | + | ||||
| 319 | + | The width and height are in surface-local coordinates and are exact | |||
| 320 | + | requirements. Failing to match these surface dimensions in the next | |||
| 321 | + | commit after acking a configure is a protocol error. | |||
| 322 | + | </description> | |||
| 323 | + | <arg name="serial" type="uint" summary="serial for use in ack_configure"/> | |||
| 324 | + | <arg name="width" type="uint"/> | |||
| 325 | + | <arg name="height" type="uint"/> | |||
| 326 | + | </event> | |||
| 327 | + | </interface> | |||
| 328 | + | </protocol> | |||
A spec/xml/exttransientseat.xml +110 -0
| @@ -0,0 +1,110 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="ext_transient_seat_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2020 - 2023 Andri Yngvason | |||
| 5 | + | ||||
| 6 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 7 | + | copy of this software and associated documentation files (the "Software"), | |||
| 8 | + | to deal in the Software without restriction, including without limitation | |||
| 9 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 10 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 11 | + | Software is furnished to do so, subject to the following conditions: | |||
| 12 | + | ||||
| 13 | + | The above copyright notice and this permission notice (including the next | |||
| 14 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 15 | + | Software. | |||
| 16 | + | ||||
| 17 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 18 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 19 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 20 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 21 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 22 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 23 | + | DEALINGS IN THE SOFTWARE. | |||
| 24 | + | </copyright> | |||
| 25 | + | ||||
| 26 | + | <description summary="protocol for creating temporary seats"> | |||
| 27 | + | The transient seat protocol can be used by privileged clients to create | |||
| 28 | + | independent seats that will be removed from the compositor when the client | |||
| 29 | + | destroys its transient seat. | |||
| 30 | + | ||||
| 31 | + | This protocol is intended for use with virtual input protocols such as | |||
| 32 | + | "virtual_keyboard_unstable_v1" or "wlr_virtual_pointer_unstable_v1", both | |||
| 33 | + | of which allow the user to select a seat. | |||
| 34 | + | ||||
| 35 | + | The "wl_seat" global created by this protocol does not generate input events | |||
| 36 | + | on its own, or have any capabilities except those assigned to it by other | |||
| 37 | + | protocol extensions, such as the ones mentioned above. | |||
| 38 | + | ||||
| 39 | + | For example, a remote desktop server can create a seat with virtual inputs | |||
| 40 | + | for each remote user by following these steps for each new connection: | |||
| 41 | + | * Create a transient seat | |||
| 42 | + | * Wait for the transient seat to be created | |||
| 43 | + | * Locate a "wl_seat" global with a matching name | |||
| 44 | + | * Create virtual inputs using the resulting "wl_seat" global | |||
| 45 | + | </description> | |||
| 46 | + | ||||
| 47 | + | <interface name="ext_transient_seat_manager_v1" version="1"> | |||
| 48 | + | <description summary="transient seat manager"> | |||
| 49 | + | The transient seat manager creates short-lived seats. | |||
| 50 | + | </description> | |||
| 51 | + | ||||
| 52 | + | <request name="create"> | |||
| 53 | + | <description summary="create a transient seat"> | |||
| 54 | + | Create a new seat that is removed when the client side transient seat | |||
| 55 | + | object is destroyed. | |||
| 56 | + | ||||
| 57 | + | The actual seat may be removed sooner, in which case the transient seat | |||
| 58 | + | object shall become inert. | |||
| 59 | + | </description> | |||
| 60 | + | <arg name="seat" type="new_id" interface="ext_transient_seat_v1"/> | |||
| 61 | + | </request> | |||
| 62 | + | ||||
| 63 | + | <request name="destroy" type="destructor"> | |||
| 64 | + | <description summary="destroy the manager"> | |||
| 65 | + | Destroy the manager. | |||
| 66 | + | ||||
| 67 | + | All objects created by the manager will remain valid until they are | |||
| 68 | + | destroyed themselves. | |||
| 69 | + | </description> | |||
| 70 | + | </request> | |||
| 71 | + | </interface> | |||
| 72 | + | ||||
| 73 | + | <interface name="ext_transient_seat_v1" version="1"> | |||
| 74 | + | <description summary="transient seat handle"> | |||
| 75 | + | When the transient seat handle is destroyed, the seat itself will also be | |||
| 76 | + | destroyed. | |||
| 77 | + | </description> | |||
| 78 | + | ||||
| 79 | + | <event name="ready"> | |||
| 80 | + | <description summary="transient seat is ready"> | |||
| 81 | + | This event advertises the global name for the wl_seat to be used with | |||
| 82 | + | wl_registry_bind. | |||
| 83 | + | ||||
| 84 | + | It is sent exactly once, immediately after the transient seat is created | |||
| 85 | + | and the new "wl_seat" global is advertised, if and only if the creation | |||
| 86 | + | of the transient seat was allowed. | |||
| 87 | + | </description> | |||
| 88 | + | <arg name="global_name" type="uint"/> | |||
| 89 | + | </event> | |||
| 90 | + | ||||
| 91 | + | <event name="denied"> | |||
| 92 | + | <description summary="transient seat creation denied"> | |||
| 93 | + | The event informs the client that the compositor denied its request to | |||
| 94 | + | create a transient seat. | |||
| 95 | + | ||||
| 96 | + | It is sent exactly once, immediately after the transient seat object is | |||
| 97 | + | created, if and only if the creation of the transient seat was denied. | |||
| 98 | + | ||||
| 99 | + | After receiving this event, the client should destroy the object. | |||
| 100 | + | </description> | |||
| 101 | + | </event> | |||
| 102 | + | ||||
| 103 | + | <request name="destroy" type="destructor"> | |||
| 104 | + | <description summary="destroy transient seat"> | |||
| 105 | + | When the transient seat object is destroyed by the client, the | |||
| 106 | + | associated seat created by the compositor is also destroyed. | |||
| 107 | + | </description> | |||
| 108 | + | </request> | |||
| 109 | + | </interface> | |||
| 110 | + | </protocol> | |||
A spec/xml/extworkspace.xml +422 -0
| @@ -0,0 +1,422 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="ext_workspace_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2019 Christopher Billington | |||
| 5 | + | Copyright © 2020 Ilia Bozhinov | |||
| 6 | + | Copyright © 2022 Victoria Brekenfeld | |||
| 7 | + | ||||
| 8 | + | Permission to use, copy, modify, distribute, and sell this | |||
| 9 | + | software and its documentation for any purpose is hereby granted | |||
| 10 | + | without fee, provided that the above copyright notice appear in | |||
| 11 | + | all copies and that both that copyright notice and this permission | |||
| 12 | + | notice appear in supporting documentation, and that the name of | |||
| 13 | + | the copyright holders not be used in advertising or publicity | |||
| 14 | + | pertaining to distribution of the software without specific, | |||
| 15 | + | written prior permission. The copyright holders make no | |||
| 16 | + | representations about the suitability of this software for any | |||
| 17 | + | purpose. It is provided "as is" without express or implied | |||
| 18 | + | warranty. | |||
| 19 | + | ||||
| 20 | + | THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | |||
| 21 | + | SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||
| 22 | + | FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | |||
| 23 | + | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||
| 24 | + | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | |||
| 25 | + | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |||
| 26 | + | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |||
| 27 | + | THIS SOFTWARE. | |||
| 28 | + | </copyright> | |||
| 29 | + | ||||
| 30 | + | <interface name="ext_workspace_manager_v1" version="1"> | |||
| 31 | + | <description summary="list and control workspaces"> | |||
| 32 | + | Workspaces, also called virtual desktops, are groups of surfaces. A | |||
| 33 | + | compositor with a concept of workspaces may only show some such groups of | |||
| 34 | + | surfaces (those of 'active' workspaces) at a time. 'Activating' a | |||
| 35 | + | workspace is a request for the compositor to display that workspace's | |||
| 36 | + | surfaces as normal, whereas the compositor may hide or otherwise | |||
| 37 | + | de-emphasise surfaces that are associated only with 'inactive' workspaces. | |||
| 38 | + | Workspaces are grouped by which sets of outputs they correspond to, and | |||
| 39 | + | may contain surfaces only from those outputs. In this way, it is possible | |||
| 40 | + | for each output to have its own set of workspaces, or for all outputs (or | |||
| 41 | + | any other arbitrary grouping) to share workspaces. Compositors may | |||
| 42 | + | optionally conceptually arrange each group of workspaces in an | |||
| 43 | + | N-dimensional grid. | |||
| 44 | + | ||||
| 45 | + | The purpose of this protocol is to enable the creation of taskbars and | |||
| 46 | + | docks by providing them with a list of workspaces and their properties, | |||
| 47 | + | and allowing them to activate and deactivate workspaces. | |||
| 48 | + | ||||
| 49 | + | After a client binds the ext_workspace_manager_v1, each workspace will be | |||
| 50 | + | sent via the workspace event. | |||
| 51 | + | </description> | |||
| 52 | + | ||||
| 53 | + | <event name="workspace_group"> | |||
| 54 | + | <description summary="a workspace group has been created"> | |||
| 55 | + | This event is emitted whenever a new workspace group has been created. | |||
| 56 | + | ||||
| 57 | + | All initial details of the workspace group (outputs) will be | |||
| 58 | + | sent immediately after this event via the corresponding events in | |||
| 59 | + | ext_workspace_group_handle_v1 and ext_workspace_handle_v1. | |||
| 60 | + | </description> | |||
| 61 | + | <arg name="workspace_group" type="new_id" interface="ext_workspace_group_handle_v1"/> | |||
| 62 | + | </event> | |||
| 63 | + | ||||
| 64 | + | <event name="workspace"> | |||
| 65 | + | <description summary="workspace has been created"> | |||
| 66 | + | This event is emitted whenever a new workspace has been created. | |||
| 67 | + | ||||
| 68 | + | All initial details of the workspace (name, coordinates, state) will | |||
| 69 | + | be sent immediately after this event via the corresponding events in | |||
| 70 | + | ext_workspace_handle_v1. | |||
| 71 | + | ||||
| 72 | + | Workspaces start off unassigned to any workspace group. | |||
| 73 | + | </description> | |||
| 74 | + | <arg name="workspace" type="new_id" interface="ext_workspace_handle_v1"/> | |||
| 75 | + | </event> | |||
| 76 | + | ||||
| 77 | + | <request name="commit"> | |||
| 78 | + | <description summary="all requests about the workspaces have been sent"> | |||
| 79 | + | The client must send this request after it has finished sending other | |||
| 80 | + | requests. The compositor must process a series of requests preceding a | |||
| 81 | + | commit request atomically. | |||
| 82 | + | ||||
| 83 | + | This allows changes to the workspace properties to be seen as atomic, | |||
| 84 | + | even if they happen via multiple events, and even if they involve | |||
| 85 | + | multiple ext_workspace_handle_v1 objects, for example, deactivating one | |||
| 86 | + | workspace and activating another. | |||
| 87 | + | </description> | |||
| 88 | + | </request> | |||
| 89 | + | ||||
| 90 | + | <event name="done"> | |||
| 91 | + | <description summary="all information about the workspaces and workspace groups has been sent"> | |||
| 92 | + | This event is sent after all changes in all workspaces and workspace groups have been | |||
| 93 | + | sent. | |||
| 94 | + | ||||
| 95 | + | This allows changes to one or more ext_workspace_group_handle_v1 | |||
| 96 | + | properties and ext_workspace_handle_v1 properties | |||
| 97 | + | to be seen as atomic, even if they happen via multiple events. | |||
| 98 | + | In particular, an output moving from one workspace group to | |||
| 99 | + | another sends an output_enter event and an output_leave event to the two | |||
| 100 | + | ext_workspace_group_handle_v1 objects in question. The compositor sends | |||
| 101 | + | the done event only after updating the output information in both | |||
| 102 | + | workspace groups. | |||
| 103 | + | </description> | |||
| 104 | + | </event> | |||
| 105 | + | ||||
| 106 | + | <event name="finished" type="destructor"> | |||
| 107 | + | <description summary="the compositor has finished with the workspace_manager"> | |||
| 108 | + | This event indicates that the compositor is done sending events to the | |||
| 109 | + | ext_workspace_manager_v1. The server will destroy the object | |||
| 110 | + | immediately after sending this request. | |||
| 111 | + | </description> | |||
| 112 | + | </event> | |||
| 113 | + | ||||
| 114 | + | <request name="stop"> | |||
| 115 | + | <description summary="stop sending events"> | |||
| 116 | + | Indicates the client no longer wishes to receive events for new | |||
| 117 | + | workspace groups. However the compositor may emit further workspace | |||
| 118 | + | events, until the finished event is emitted. The compositor is expected | |||
| 119 | + | to send the finished event eventually once the stop request has been processed. | |||
| 120 | + | ||||
| 121 | + | The client must not send any requests after this one, doing so will raise a wl_display | |||
| 122 | + | invalid_object error. | |||
| 123 | + | </description> | |||
| 124 | + | </request> | |||
| 125 | + | ||||
| 126 | + | </interface> | |||
| 127 | + | ||||
| 128 | + | <interface name="ext_workspace_group_handle_v1" version="1"> | |||
| 129 | + | <description summary="a workspace group assigned to a set of outputs"> | |||
| 130 | + | A ext_workspace_group_handle_v1 object represents a workspace group | |||
| 131 | + | that is assigned a set of outputs and contains a number of workspaces. | |||
| 132 | + | ||||
| 133 | + | The set of outputs assigned to the workspace group is conveyed to the client via | |||
| 134 | + | output_enter and output_leave events, and its workspaces are conveyed with | |||
| 135 | + | workspace events. | |||
| 136 | + | ||||
| 137 | + | For example, a compositor which has a set of workspaces for each output may | |||
| 138 | + | advertise a workspace group (and its workspaces) per output, whereas a compositor | |||
| 139 | + | where a workspace spans all outputs may advertise a single workspace group for all | |||
| 140 | + | outputs. | |||
| 141 | + | </description> | |||
| 142 | + | ||||
| 143 | + | <enum name="group_capabilities" bitfield="true"> | |||
| 144 | + | <entry name="create_workspace" value="1" summary="create_workspace request is available"/> | |||
| 145 | + | </enum> | |||
| 146 | + | ||||
| 147 | + | <event name="capabilities"> | |||
| 148 | + | <description summary="compositor capabilities"> | |||
| 149 | + | This event advertises the capabilities supported by the compositor. If | |||
| 150 | + | a capability isn't supported, clients should hide or disable the UI | |||
| 151 | + | elements that expose this functionality. For instance, if the | |||
| 152 | + | compositor doesn't advertise support for creating workspaces, a button | |||
| 153 | + | triggering the create_workspace request should not be displayed. | |||
| 154 | + | ||||
| 155 | + | The compositor will ignore requests it doesn't support. For instance, | |||
| 156 | + | a compositor which doesn't advertise support for creating workspaces will ignore | |||
| 157 | + | create_workspace requests. | |||
| 158 | + | ||||
| 159 | + | Compositors must send this event once after creation of an | |||
| 160 | + | ext_workspace_group_handle_v1. When the capabilities change, compositors | |||
| 161 | + | must send this event again. | |||
| 162 | + | </description> | |||
| 163 | + | <arg name="capabilities" type="uint" summary="capabilities" enum="group_capabilities"/> | |||
| 164 | + | </event> | |||
| 165 | + | ||||
| 166 | + | <event name="output_enter"> | |||
| 167 | + | <description summary="output assigned to workspace group"> | |||
| 168 | + | This event is emitted whenever an output is assigned to the workspace | |||
| 169 | + | group or a new `wl_output` object is bound by the client, which was already | |||
| 170 | + | assigned to this workspace_group. | |||
| 171 | + | </description> | |||
| 172 | + | <arg name="output" type="object" interface="wl_output"/> | |||
| 173 | + | </event> | |||
| 174 | + | ||||
| 175 | + | <event name="output_leave"> | |||
| 176 | + | <description summary="output removed from workspace group"> | |||
| 177 | + | This event is emitted whenever an output is removed from the workspace | |||
| 178 | + | group. | |||
| 179 | + | </description> | |||
| 180 | + | <arg name="output" type="object" interface="wl_output"/> | |||
| 181 | + | </event> | |||
| 182 | + | ||||
| 183 | + | <event name="workspace_enter"> | |||
| 184 | + | <description summary="workspace added to workspace group"> | |||
| 185 | + | This event is emitted whenever a workspace is assigned to this group. | |||
| 186 | + | A workspace may only ever be assigned to a single group at a single point | |||
| 187 | + | in time, but can be re-assigned during its lifetime. | |||
| 188 | + | </description> | |||
| 189 | + | <arg name="workspace" type="object" interface="ext_workspace_handle_v1"/> | |||
| 190 | + | </event> | |||
| 191 | + | ||||
| 192 | + | <event name="workspace_leave"> | |||
| 193 | + | <description summary="workspace removed from workspace group"> | |||
| 194 | + | This event is emitted whenever a workspace is removed from this group. | |||
| 195 | + | </description> | |||
| 196 | + | <arg name="workspace" type="object" interface="ext_workspace_handle_v1"/> | |||
| 197 | + | </event> | |||
| 198 | + | ||||
| 199 | + | <event name="removed"> | |||
| 200 | + | <description summary="this workspace group has been removed"> | |||
| 201 | + | This event is send when the group associated with the ext_workspace_group_handle_v1 | |||
| 202 | + | has been removed. After sending this request the compositor will immediately consider | |||
| 203 | + | the object inert. Any requests will be ignored except the destroy request. | |||
| 204 | + | It is guaranteed there won't be any more events referencing this | |||
| 205 | + | ext_workspace_group_handle_v1. | |||
| 206 | + | ||||
| 207 | + | The compositor must remove all workspaces belonging to a workspace group | |||
| 208 | + | via a workspace_leave event before removing the workspace group. | |||
| 209 | + | </description> | |||
| 210 | + | </event> | |||
| 211 | + | ||||
| 212 | + | <request name="create_workspace"> | |||
| 213 | + | <description summary="create a new workspace"> | |||
| 214 | + | Request that the compositor create a new workspace with the given name | |||
| 215 | + | and assign it to this group. | |||
| 216 | + | ||||
| 217 | + | There is no guarantee that the compositor will create a new workspace, | |||
| 218 | + | or that the created workspace will have the provided name. | |||
| 219 | + | </description> | |||
| 220 | + | <arg name="workspace" type="string"/> | |||
| 221 | + | </request> | |||
| 222 | + | ||||
| 223 | + | <request name="destroy" type="destructor"> | |||
| 224 | + | <description summary="destroy the ext_workspace_group_handle_v1 object"> | |||
| 225 | + | Destroys the ext_workspace_group_handle_v1 object. | |||
| 226 | + | ||||
| 227 | + | This request should be send either when the client does not want to | |||
| 228 | + | use the workspace group object any more or after the removed event to finalize | |||
| 229 | + | the destruction of the object. | |||
| 230 | + | </description> | |||
| 231 | + | </request> | |||
| 232 | + | </interface> | |||
| 233 | + | ||||
| 234 | + | <interface name="ext_workspace_handle_v1" version="1"> | |||
| 235 | + | <description summary="a workspace handing a group of surfaces"> | |||
| 236 | + | A ext_workspace_handle_v1 object represents a workspace that handles a | |||
| 237 | + | group of surfaces. | |||
| 238 | + | ||||
| 239 | + | Each workspace has: | |||
| 240 | + | - a name, conveyed to the client with the name event | |||
| 241 | + | - potentially an id conveyed with the id event | |||
| 242 | + | - a list of states, conveyed to the client with the state event | |||
| 243 | + | - and optionally a set of coordinates, conveyed to the client with the | |||
| 244 | + | coordinates event | |||
| 245 | + | ||||
| 246 | + | The client may request that the compositor activate or deactivate the workspace. | |||
| 247 | + | ||||
| 248 | + | Each workspace can belong to only a single workspace group. | |||
| 249 | + | Depending on the compositor policy, there might be workspaces with | |||
| 250 | + | the same name in different workspace groups, but these workspaces are still | |||
| 251 | + | separate (e.g. one of them might be active while the other is not). | |||
| 252 | + | </description> | |||
| 253 | + | ||||
| 254 | + | <event name="id"> | |||
| 255 | + | <description summary="workspace id"> | |||
| 256 | + | If this event is emitted, it will be send immediately after the | |||
| 257 | + | ext_workspace_handle_v1 is created or when an id is assigned to | |||
| 258 | + | a workspace (at most once during its lifetime). | |||
| 259 | + | ||||
| 260 | + | An id will never change during the lifetime of the `ext_workspace_handle_v1` | |||
| 261 | + | and is guaranteed to be unique during its lifetime. | |||
| 262 | + | ||||
| 263 | + | Ids are not human-readable and shouldn't be displayed, use `name` for that purpose. | |||
| 264 | + | ||||
| 265 | + | Compositors are expected to only send ids for workspaces likely stable across multiple | |||
| 266 | + | sessions and can be used by clients to store preferences for workspaces. Workspaces without | |||
| 267 | + | ids should be considered temporary and any data associated with them should be deleted once | |||
| 268 | + | the respective object is lost. | |||
| 269 | + | </description> | |||
| 270 | + | <arg name="id" type="string"/> | |||
| 271 | + | </event> | |||
| 272 | + | ||||
| 273 | + | <event name="name"> | |||
| 274 | + | <description summary="workspace name changed"> | |||
| 275 | + | This event is emitted immediately after the ext_workspace_handle_v1 is | |||
| 276 | + | created and whenever the name of the workspace changes. | |||
| 277 | + | ||||
| 278 | + | A name is meant to be human-readable and can be displayed to a user. | |||
| 279 | + | Unlike the id it is neither stable nor unique. | |||
| 280 | + | </description> | |||
| 281 | + | <arg name="name" type="string"/> | |||
| 282 | + | </event> | |||
| 283 | + | ||||
| 284 | + | <event name="coordinates"> | |||
| 285 | + | <description summary="workspace coordinates changed"> | |||
| 286 | + | This event is used to organize workspaces into an N-dimensional grid | |||
| 287 | + | within a workspace group, and if supported, is emitted immediately after | |||
| 288 | + | the ext_workspace_handle_v1 is created and whenever the coordinates of | |||
| 289 | + | the workspace change. Compositors may not send this event if they do not | |||
| 290 | + | conceptually arrange workspaces in this way. If compositors simply | |||
| 291 | + | number workspaces, without any geometric interpretation, they may send | |||
| 292 | + | 1D coordinates, which clients should not interpret as implying any | |||
| 293 | + | geometry. Sending an empty array means that the compositor no longer | |||
| 294 | + | orders the workspace geometrically. | |||
| 295 | + | ||||
| 296 | + | Coordinates have an arbitrary number of dimensions N with an uint32 | |||
| 297 | + | position along each dimension. By convention if N > 1, the first | |||
| 298 | + | dimension is X, the second Y, the third Z, and so on. The compositor may | |||
| 299 | + | chose to utilize these events for a more novel workspace layout | |||
| 300 | + | convention, however. No guarantee is made about the grid being filled or | |||
| 301 | + | bounded; there may be a workspace at coordinate 1 and another at | |||
| 302 | + | coordinate 1000 and none in between. Within a workspace group, however, | |||
| 303 | + | workspaces must have unique coordinates of equal dimensionality. | |||
| 304 | + | </description> | |||
| 305 | + | <arg name="coordinates" type="array"/> | |||
| 306 | + | </event> | |||
| 307 | + | ||||
| 308 | + | <enum name="state" bitfield="true"> | |||
| 309 | + | <description summary="types of states on the workspace"> | |||
| 310 | + | The different states that a workspace can have. | |||
| 311 | + | </description> | |||
| 312 | + | ||||
| 313 | + | <entry name="active" value="1" summary="the workspace is active"/> | |||
| 314 | + | <entry name="urgent" value="2" summary="the workspace requests attention"/> | |||
| 315 | + | <entry name="hidden" value="4"> | |||
| 316 | + | <description summary="the workspace is not visible"> | |||
| 317 | + | The workspace is not visible in its workspace group, and clients | |||
| 318 | + | attempting to visualize the compositor workspace state should not | |||
| 319 | + | display such workspaces. | |||
| 320 | + | </description> | |||
| 321 | + | </entry> | |||
| 322 | + | </enum> | |||
| 323 | + | ||||
| 324 | + | <event name="state"> | |||
| 325 | + | <description summary="the state of the workspace changed"> | |||
| 326 | + | This event is emitted immediately after the ext_workspace_handle_v1 is | |||
| 327 | + | created and each time the workspace state changes, either because of a | |||
| 328 | + | compositor action or because of a request in this protocol. | |||
| 329 | + | ||||
| 330 | + | Missing states convey the opposite meaning, e.g. an unset active bit | |||
| 331 | + | means the workspace is currently inactive. | |||
| 332 | + | </description> | |||
| 333 | + | <arg name="state" type="uint" enum="state"/> | |||
| 334 | + | </event> | |||
| 335 | + | ||||
| 336 | + | <enum name="workspace_capabilities" bitfield="true"> | |||
| 337 | + | <entry name="activate" value="1" summary="activate request is available"/> | |||
| 338 | + | <entry name="deactivate" value="2" summary="deactivate request is available"/> | |||
| 339 | + | <entry name="remove" value="4" summary="remove request is available"/> | |||
| 340 | + | <entry name="assign" value="8" summary="assign request is available"/> | |||
| 341 | + | </enum> | |||
| 342 | + | ||||
| 343 | + | <event name="capabilities"> | |||
| 344 | + | <description summary="compositor capabilities"> | |||
| 345 | + | This event advertises the capabilities supported by the compositor. If | |||
| 346 | + | a capability isn't supported, clients should hide or disable the UI | |||
| 347 | + | elements that expose this functionality. For instance, if the | |||
| 348 | + | compositor doesn't advertise support for removing workspaces, a button | |||
| 349 | + | triggering the remove request should not be displayed. | |||
| 350 | + | ||||
| 351 | + | The compositor will ignore requests it doesn't support. For instance, | |||
| 352 | + | a compositor which doesn't advertise support for remove will ignore | |||
| 353 | + | remove requests. | |||
| 354 | + | ||||
| 355 | + | Compositors must send this event once after creation of an | |||
| 356 | + | ext_workspace_handle_v1 . When the capabilities change, compositors | |||
| 357 | + | must send this event again. | |||
| 358 | + | </description> | |||
| 359 | + | <arg name="capabilities" type="uint" summary="capabilities" enum="workspace_capabilities"/> | |||
| 360 | + | </event> | |||
| 361 | + | ||||
| 362 | + | <event name="removed"> | |||
| 363 | + | <description summary="this workspace has been removed"> | |||
| 364 | + | This event is send when the workspace associated with the ext_workspace_handle_v1 | |||
| 365 | + | has been removed. After sending this request, the compositor will immediately consider | |||
| 366 | + | the object inert. Any requests will be ignored except the destroy request. | |||
| 367 | + | ||||
| 368 | + | It is guaranteed there won't be any more events referencing this | |||
| 369 | + | ext_workspace_handle_v1. | |||
| 370 | + | ||||
| 371 | + | The compositor must only remove a workspaces not currently belonging to any | |||
| 372 | + | workspace_group. | |||
| 373 | + | </description> | |||
| 374 | + | </event> | |||
| 375 | + | ||||
| 376 | + | <request name="destroy" type="destructor"> | |||
| 377 | + | <description summary="destroy the ext_workspace_handle_v1 object"> | |||
| 378 | + | Destroys the ext_workspace_handle_v1 object. | |||
| 379 | + | ||||
| 380 | + | This request should be made either when the client does not want to | |||
| 381 | + | use the workspace object any more or after the remove event to finalize | |||
| 382 | + | the destruction of the object. | |||
| 383 | + | </description> | |||
| 384 | + | </request> | |||
| 385 | + | ||||
| 386 | + | <request name="activate"> | |||
| 387 | + | <description summary="activate the workspace"> | |||
| 388 | + | Request that this workspace be activated. | |||
| 389 | + | ||||
| 390 | + | There is no guarantee the workspace will be actually activated, and | |||
| 391 | + | behaviour may be compositor-dependent. For example, activating a | |||
| 392 | + | workspace may or may not deactivate all other workspaces in the same | |||
| 393 | + | group. | |||
| 394 | + | </description> | |||
| 395 | + | </request> | |||
| 396 | + | ||||
| 397 | + | <request name="deactivate"> | |||
| 398 | + | <description summary="deactivate the workspace"> | |||
| 399 | + | Request that this workspace be deactivated. | |||
| 400 | + | ||||
| 401 | + | There is no guarantee the workspace will be actually deactivated. | |||
| 402 | + | </description> | |||
| 403 | + | </request> | |||
| 404 | + | ||||
| 405 | + | <request name="assign"> | |||
| 406 | + | <description summary="assign workspace to group"> | |||
| 407 | + | Requests that this workspace is assigned to the given workspace group. | |||
| 408 | + | ||||
| 409 | + | There is no guarantee the workspace will be assigned. | |||
| 410 | + | </description> | |||
| 411 | + | <arg name="workspace_group" type="object" interface="ext_workspace_group_handle_v1"/> | |||
| 412 | + | </request> | |||
| 413 | + | ||||
| 414 | + | <request name="remove"> | |||
| 415 | + | <description summary="remove the workspace"> | |||
| 416 | + | Request that this workspace be removed. | |||
| 417 | + | ||||
| 418 | + | There is no guarantee the workspace will be actually removed. | |||
| 419 | + | </description> | |||
| 420 | + | </request> | |||
| 421 | + | </interface> | |||
| 422 | + | </protocol> | |||
A spec/xml/fifo.xml +143 -0
| @@ -0,0 +1,143 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="fifo_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2023 Valve Corporation | |||
| 5 | + | ||||
| 6 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 7 | + | copy of this software and associated documentation files (the "Software"), | |||
| 8 | + | to deal in the Software without restriction, including without limitation | |||
| 9 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 10 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 11 | + | Software is furnished to do so, subject to the following conditions: | |||
| 12 | + | ||||
| 13 | + | The above copyright notice and this permission notice (including the next | |||
| 14 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 15 | + | Software. | |||
| 16 | + | ||||
| 17 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 18 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 19 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 20 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 21 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 22 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 23 | + | DEALINGS IN THE SOFTWARE. | |||
| 24 | + | </copyright> | |||
| 25 | + | ||||
| 26 | + | <interface name="wp_fifo_manager_v1" version="1"> | |||
| 27 | + | <description summary="protocol for fifo constraints"> | |||
| 28 | + | When a Wayland compositor considers applying a content update, | |||
| 29 | + | it must ensure all the update's readiness constraints (fences, etc) | |||
| 30 | + | are met. | |||
| 31 | + | ||||
| 32 | + | This protocol provides a way to use the completion of a display refresh | |||
| 33 | + | cycle as an additional readiness constraint. | |||
| 34 | + | ||||
| 35 | + | Warning! The protocol described in this file is currently in the testing | |||
| 36 | + | phase. Backward compatible changes may be added together with the | |||
| 37 | + | corresponding interface version bump. Backward incompatible changes can | |||
| 38 | + | only be done by creating a new major version of the extension. | |||
| 39 | + | </description> | |||
| 40 | + | ||||
| 41 | + | <enum name="error"> | |||
| 42 | + | <description summary="fatal presentation error"> | |||
| 43 | + | These fatal protocol errors may be emitted in response to | |||
| 44 | + | illegal requests. | |||
| 45 | + | </description> | |||
| 46 | + | <entry name="already_exists" value="0" | |||
| 47 | + | summary="fifo manager already exists for surface"/> | |||
| 48 | + | </enum> | |||
| 49 | + | ||||
| 50 | + | <request name="destroy" type="destructor"> | |||
| 51 | + | <description summary="unbind from the manager interface"> | |||
| 52 | + | Informs the server that the client will no longer be using | |||
| 53 | + | this protocol object. Existing objects created by this object | |||
| 54 | + | are not affected. | |||
| 55 | + | </description> | |||
| 56 | + | </request> | |||
| 57 | + | ||||
| 58 | + | <request name="get_fifo"> | |||
| 59 | + | <description summary="request fifo interface for surface"> | |||
| 60 | + | Establish a fifo object for a surface that may be used to add | |||
| 61 | + | display refresh constraints to content updates. | |||
| 62 | + | ||||
| 63 | + | Only one such object may exist for a surface and attempting | |||
| 64 | + | to create more than one will result in an already_exists | |||
| 65 | + | protocol error. If a surface is acted on by multiple software | |||
| 66 | + | components, general best practice is that only the component | |||
| 67 | + | performing wl_surface.attach operations should use this protocol. | |||
| 68 | + | </description> | |||
| 69 | + | <arg name="id" type="new_id" interface="wp_fifo_v1"/> | |||
| 70 | + | <arg name="surface" type="object" interface="wl_surface"/> | |||
| 71 | + | </request> | |||
| 72 | + | </interface> | |||
| 73 | + | ||||
| 74 | + | <interface name="wp_fifo_v1" version="1"> | |||
| 75 | + | <description summary="fifo interface"> | |||
| 76 | + | A fifo object for a surface that may be used to add | |||
| 77 | + | display refresh constraints to content updates. | |||
| 78 | + | </description> | |||
| 79 | + | ||||
| 80 | + | <enum name="error"> | |||
| 81 | + | <description summary="fatal error"> | |||
| 82 | + | These fatal protocol errors may be emitted in response to | |||
| 83 | + | illegal requests. | |||
| 84 | + | </description> | |||
| 85 | + | <entry name="surface_destroyed" value="0" | |||
| 86 | + | summary="the associated surface no longer exists"/> | |||
| 87 | + | </enum> | |||
| 88 | + | ||||
| 89 | + | <request name="set_barrier"> | |||
| 90 | + | <description summary="sets the start point for a fifo constraint"> | |||
| 91 | + | When the content update containing the "set_barrier" is applied, | |||
| 92 | + | it sets a "fifo_barrier" condition on the surface associated with | |||
| 93 | + | the fifo object. The condition is cleared immediately after the | |||
| 94 | + | following latching deadline for non-tearing presentation. | |||
| 95 | + | ||||
| 96 | + | The compositor may clear the condition early if it must do so to | |||
| 97 | + | ensure client forward progress assumptions. | |||
| 98 | + | ||||
| 99 | + | To wait for this condition to clear, use the "wait_barrier" request. | |||
| 100 | + | ||||
| 101 | + | "set_barrier" is double-buffered state, see wl_surface.commit. | |||
| 102 | + | ||||
| 103 | + | Requesting set_barrier after the fifo object's surface is | |||
| 104 | + | destroyed will generate a "surface_destroyed" error. | |||
| 105 | + | </description> | |||
| 106 | + | </request> | |||
| 107 | + | ||||
| 108 | + | <request name="wait_barrier"> | |||
| 109 | + | <description summary="adds a fifo constraint to a content update"> | |||
| 110 | + | Indicate that this content update is not ready while a | |||
| 111 | + | "fifo_barrier" condition is present on the surface. | |||
| 112 | + | ||||
| 113 | + | This means that when the content update containing "set_barrier" | |||
| 114 | + | was made active at a latching deadline, it will be active for | |||
| 115 | + | at least one refresh cycle. A content update which is allowed to | |||
| 116 | + | tear might become active after a latching deadline if no content | |||
| 117 | + | update became active at the deadline. | |||
| 118 | + | ||||
| 119 | + | The constraint must be ignored if the surface is a subsurface in | |||
| 120 | + | synchronized mode. If the surface is not being updated by the | |||
| 121 | + | compositor (off-screen, occluded) the compositor may ignore the | |||
| 122 | + | constraint. Clients must use an additional mechanism such as | |||
| 123 | + | frame callbacks or timestamps to ensure throttling occurs under | |||
| 124 | + | all conditions. | |||
| 125 | + | ||||
| 126 | + | "wait_barrier" is double-buffered state, see wl_surface.commit. | |||
| 127 | + | ||||
| 128 | + | Requesting "wait_barrier" after the fifo object's surface is | |||
| 129 | + | destroyed will generate a "surface_destroyed" error. | |||
| 130 | + | </description> | |||
| 131 | + | </request> | |||
| 132 | + | ||||
| 133 | + | <request name="destroy" type="destructor"> | |||
| 134 | + | <description summary="destroy the fifo interface"> | |||
| 135 | + | Informs the server that the client will no longer be using | |||
| 136 | + | this protocol object. | |||
| 137 | + | ||||
| 138 | + | Surface state changes previously made by this protocol are | |||
| 139 | + | unaffected by this object's destruction. | |||
| 140 | + | </description> | |||
| 141 | + | </request> | |||
| 142 | + | </interface> | |||
| 143 | + | </protocol> | |||
A spec/xml/fractionalscale.xml +102 -0
| @@ -0,0 +1,102 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="fractional_scale_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2022 Kenny Levinsen | |||
| 5 | + | ||||
| 6 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 7 | + | copy of this software and associated documentation files (the "Software"), | |||
| 8 | + | to deal in the Software without restriction, including without limitation | |||
| 9 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 10 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 11 | + | Software is furnished to do so, subject to the following conditions: | |||
| 12 | + | ||||
| 13 | + | The above copyright notice and this permission notice (including the next | |||
| 14 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 15 | + | Software. | |||
| 16 | + | ||||
| 17 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 18 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 19 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 20 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 21 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 22 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 23 | + | DEALINGS IN THE SOFTWARE. | |||
| 24 | + | </copyright> | |||
| 25 | + | ||||
| 26 | + | <description summary="Protocol for requesting fractional surface scales"> | |||
| 27 | + | This protocol allows a compositor to suggest for surfaces to render at | |||
| 28 | + | fractional scales. | |||
| 29 | + | ||||
| 30 | + | A client can submit scaled content by utilizing wp_viewport. This is done by | |||
| 31 | + | creating a wp_viewport object for the surface and setting the destination | |||
| 32 | + | rectangle to the surface size before the scale factor is applied. | |||
| 33 | + | ||||
| 34 | + | The buffer size is calculated by multiplying the surface size by the | |||
| 35 | + | intended scale. | |||
| 36 | + | ||||
| 37 | + | The wl_surface buffer scale should remain set to 1. | |||
| 38 | + | ||||
| 39 | + | If a surface has a surface-local size of 100 px by 50 px and wishes to | |||
| 40 | + | submit buffers with a scale of 1.5, then a buffer of 150px by 75 px should | |||
| 41 | + | be used and the wp_viewport destination rectangle should be 100 px by 50 px. | |||
| 42 | + | ||||
| 43 | + | For toplevel surfaces, the size is rounded halfway away from zero. The | |||
| 44 | + | rounding algorithm for subsurface position and size is not defined. | |||
| 45 | + | </description> | |||
| 46 | + | ||||
| 47 | + | <interface name="wp_fractional_scale_manager_v1" version="1"> | |||
| 48 | + | <description summary="fractional surface scale information"> | |||
| 49 | + | A global interface for requesting surfaces to use fractional scales. | |||
| 50 | + | </description> | |||
| 51 | + | ||||
| 52 | + | <request name="destroy" type="destructor"> | |||
| 53 | + | <description summary="unbind the fractional surface scale interface"> | |||
| 54 | + | Informs the server that the client will not be using this protocol | |||
| 55 | + | object anymore. This does not affect any other objects, | |||
| 56 | + | wp_fractional_scale_v1 objects included. | |||
| 57 | + | </description> | |||
| 58 | + | </request> | |||
| 59 | + | ||||
| 60 | + | <enum name="error"> | |||
| 61 | + | <entry name="fractional_scale_exists" value="0" | |||
| 62 | + | summary="the surface already has a fractional_scale object associated"/> | |||
| 63 | + | </enum> | |||
| 64 | + | ||||
| 65 | + | <request name="get_fractional_scale"> | |||
| 66 | + | <description summary="extend surface interface for scale information"> | |||
| 67 | + | Create an add-on object for the the wl_surface to let the compositor | |||
| 68 | + | request fractional scales. If the given wl_surface already has a | |||
| 69 | + | wp_fractional_scale_v1 object associated, the fractional_scale_exists | |||
| 70 | + | protocol error is raised. | |||
| 71 | + | </description> | |||
| 72 | + | <arg name="id" type="new_id" interface="wp_fractional_scale_v1" | |||
| 73 | + | summary="the new surface scale info interface id"/> | |||
| 74 | + | <arg name="surface" type="object" interface="wl_surface" | |||
| 75 | + | summary="the surface"/> | |||
| 76 | + | </request> | |||
| 77 | + | </interface> | |||
| 78 | + | ||||
| 79 | + | <interface name="wp_fractional_scale_v1" version="1"> | |||
| 80 | + | <description summary="fractional scale interface to a wl_surface"> | |||
| 81 | + | An additional interface to a wl_surface object which allows the compositor | |||
| 82 | + | to inform the client of the preferred scale. | |||
| 83 | + | </description> | |||
| 84 | + | ||||
| 85 | + | <request name="destroy" type="destructor"> | |||
| 86 | + | <description summary="remove surface scale information for surface"> | |||
| 87 | + | Destroy the fractional scale object. When this object is destroyed, | |||
| 88 | + | preferred_scale events will no longer be sent. | |||
| 89 | + | </description> | |||
| 90 | + | </request> | |||
| 91 | + | ||||
| 92 | + | <event name="preferred_scale"> | |||
| 93 | + | <description summary="notify of new preferred scale"> | |||
| 94 | + | Notification of a new preferred scale for this surface that the | |||
| 95 | + | compositor suggests that the client should use. | |||
| 96 | + | ||||
| 97 | + | The sent scale is the numerator of a fraction with a denominator of 120. | |||
| 98 | + | </description> | |||
| 99 | + | <arg name="scale" type="uint" summary="the new preferred scale"/> | |||
| 100 | + | </event> | |||
| 101 | + | </interface> | |||
| 102 | + | </protocol> | |||
A spec/xml/fullscreenshell.xml +254 -0
| @@ -0,0 +1,254 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="fullscreen_shell_unstable_v1"> | |||
| 3 | + | ||||
| 4 | + | <copyright> | |||
| 5 | + | Copyright © 2016 Yong Bakos | |||
| 6 | + | Copyright © 2015 Jason Ekstrand | |||
| 7 | + | Copyright © 2015 Jonas Ådahl | |||
| 8 | + | ||||
| 9 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 10 | + | copy of this software and associated documentation files (the "Software"), | |||
| 11 | + | to deal in the Software without restriction, including without limitation | |||
| 12 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 13 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 14 | + | Software is furnished to do so, subject to the following conditions: | |||
| 15 | + | ||||
| 16 | + | The above copyright notice and this permission notice (including the next | |||
| 17 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 18 | + | Software. | |||
| 19 | + | ||||
| 20 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 21 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 22 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 23 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 24 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 25 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 26 | + | DEALINGS IN THE SOFTWARE. | |||
| 27 | + | </copyright> | |||
| 28 | + | ||||
| 29 | + | <interface name="zwp_fullscreen_shell_v1" version="1"> | |||
| 30 | + | <description summary="displays a single surface per output"> | |||
| 31 | + | Displays a single surface per output. | |||
| 32 | + | ||||
| 33 | + | This interface provides a mechanism for a single client to display | |||
| 34 | + | simple full-screen surfaces. While there technically may be multiple | |||
| 35 | + | clients bound to this interface, only one of those clients should be | |||
| 36 | + | shown at a time. | |||
| 37 | + | ||||
| 38 | + | To present a surface, the client uses either the present_surface or | |||
| 39 | + | present_surface_for_mode requests. Presenting a surface takes effect | |||
| 40 | + | on the next wl_surface.commit. See the individual requests for | |||
| 41 | + | details about scaling and mode switches. | |||
| 42 | + | ||||
| 43 | + | The client can have at most one surface per output at any time. | |||
| 44 | + | Requesting a surface to be presented on an output that already has a | |||
| 45 | + | surface replaces the previously presented surface. Presenting a null | |||
| 46 | + | surface removes its content and effectively disables the output. | |||
| 47 | + | Exactly what happens when an output is "disabled" is | |||
| 48 | + | compositor-specific. The same surface may be presented on multiple | |||
| 49 | + | outputs simultaneously. | |||
| 50 | + | ||||
| 51 | + | Once a surface is presented on an output, it stays on that output | |||
| 52 | + | until either the client removes it or the compositor destroys the | |||
| 53 | + | output. This way, the client can update the output's contents by | |||
| 54 | + | simply attaching a new buffer. | |||
| 55 | + | ||||
| 56 | + | Warning! The protocol described in this file is experimental and | |||
| 57 | + | backward incompatible changes may be made. Backward compatible changes | |||
| 58 | + | may be added together with the corresponding interface version bump. | |||
| 59 | + | Backward incompatible changes are done by bumping the version number in | |||
| 60 | + | the protocol and interface names and resetting the interface version. | |||
| 61 | + | Once the protocol is to be declared stable, the 'z' prefix and the | |||
| 62 | + | version number in the protocol and interface names are removed and the | |||
| 63 | + | interface version number is reset. | |||
| 64 | + | </description> | |||
| 65 | + | ||||
| 66 | + | <request name="release" type="destructor"> | |||
| 67 | + | <description summary="release the wl_fullscreen_shell interface"> | |||
| 68 | + | Release the binding from the wl_fullscreen_shell interface. | |||
| 69 | + | ||||
| 70 | + | This destroys the server-side object and frees this binding. If | |||
| 71 | + | the client binds to wl_fullscreen_shell multiple times, it may wish | |||
| 72 | + | to free some of those bindings. | |||
| 73 | + | </description> | |||
| 74 | + | </request> | |||
| 75 | + | ||||
| 76 | + | <enum name="capability"> | |||
| 77 | + | <description summary="capabilities advertised by the compositor"> | |||
| 78 | + | Various capabilities that can be advertised by the compositor. They | |||
| 79 | + | are advertised one-at-a-time when the wl_fullscreen_shell interface is | |||
| 80 | + | bound. See the wl_fullscreen_shell.capability event for more details. | |||
| 81 | + | ||||
| 82 | + | ARBITRARY_MODES: | |||
| 83 | + | This is a hint to the client that indicates that the compositor is | |||
| 84 | + | capable of setting practically any mode on its outputs. If this | |||
| 85 | + | capability is provided, wl_fullscreen_shell.present_surface_for_mode | |||
| 86 | + | will almost never fail and clients should feel free to set whatever | |||
| 87 | + | mode they like. If the compositor does not advertise this, it may | |||
| 88 | + | still support some modes that are not advertised through wl_global.mode | |||
| 89 | + | but it is less likely. | |||
| 90 | + | ||||
| 91 | + | CURSOR_PLANE: | |||
| 92 | + | This is a hint to the client that indicates that the compositor can | |||
| 93 | + | handle a cursor surface from the client without actually compositing. | |||
| 94 | + | This may be because of a hardware cursor plane or some other mechanism. | |||
| 95 | + | If the compositor does not advertise this capability then setting | |||
| 96 | + | wl_pointer.cursor may degrade performance or be ignored entirely. If | |||
| 97 | + | CURSOR_PLANE is not advertised, it is recommended that the client draw | |||
| 98 | + | its own cursor and set wl_pointer.cursor(NULL). | |||
| 99 | + | </description> | |||
| 100 | + | <entry name="arbitrary_modes" value="1" summary="compositor is capable of almost any output mode"/> | |||
| 101 | + | <entry name="cursor_plane" value="2" summary="compositor has a separate cursor plane"/> | |||
| 102 | + | </enum> | |||
| 103 | + | ||||
| 104 | + | <event name="capability"> | |||
| 105 | + | <description summary="advertises a capability of the compositor"> | |||
| 106 | + | Advertises a single capability of the compositor. | |||
| 107 | + | ||||
| 108 | + | When the wl_fullscreen_shell interface is bound, this event is emitted | |||
| 109 | + | once for each capability advertised. Valid capabilities are given by | |||
| 110 | + | the wl_fullscreen_shell.capability enum. If clients want to take | |||
| 111 | + | advantage of any of these capabilities, they should use a | |||
| 112 | + | wl_display.sync request immediately after binding to ensure that they | |||
| 113 | + | receive all the capability events. | |||
| 114 | + | </description> | |||
| 115 | + | <arg name="capability" type="uint" enum="capability" /> | |||
| 116 | + | </event> | |||
| 117 | + | ||||
| 118 | + | <enum name="present_method"> | |||
| 119 | + | <description summary="different method to set the surface fullscreen"> | |||
| 120 | + | Hints to indicate to the compositor how to deal with a conflict | |||
| 121 | + | between the dimensions of the surface and the dimensions of the | |||
| 122 | + | output. The compositor is free to ignore this parameter. | |||
| 123 | + | </description> | |||
| 124 | + | <entry name="default" value="0" summary="no preference, apply default policy"/> | |||
| 125 | + | <entry name="center" value="1" summary="center the surface on the output"/> | |||
| 126 | + | <entry name="zoom" value="2" summary="scale the surface, preserving aspect ratio, to the largest size that will fit on the output" /> | |||
| 127 | + | <entry name="zoom_crop" value="3" summary="scale the surface, preserving aspect ratio, to fully fill the output cropping if needed" /> | |||
| 128 | + | <entry name="stretch" value="4" summary="scale the surface to the size of the output ignoring aspect ratio" /> | |||
| 129 | + | </enum> | |||
| 130 | + | ||||
| 131 | + | <request name="present_surface"> | |||
| 132 | + | <description summary="present surface for display"> | |||
| 133 | + | Present a surface on the given output. | |||
| 134 | + | ||||
| 135 | + | If the output is null, the compositor will present the surface on | |||
| 136 | + | whatever display (or displays) it thinks best. In particular, this | |||
| 137 | + | may replace any or all surfaces currently presented so it should | |||
| 138 | + | not be used in combination with placing surfaces on specific | |||
| 139 | + | outputs. | |||
| 140 | + | ||||
| 141 | + | The method parameter is a hint to the compositor for how the surface | |||
| 142 | + | is to be presented. In particular, it tells the compositor how to | |||
| 143 | + | handle a size mismatch between the presented surface and the | |||
| 144 | + | output. The compositor is free to ignore this parameter. | |||
| 145 | + | ||||
| 146 | + | The "zoom", "zoom_crop", and "stretch" methods imply a scaling | |||
| 147 | + | operation on the surface. This will override any kind of output | |||
| 148 | + | scaling, so the buffer_scale property of the surface is effectively | |||
| 149 | + | ignored. | |||
| 150 | + | ||||
| 151 | + | This request gives the surface the role of a fullscreen shell surface. | |||
| 152 | + | If the surface already has another role, it raises a role protocol | |||
| 153 | + | error. | |||
| 154 | + | </description> | |||
| 155 | + | <arg name="surface" type="object" interface="wl_surface" allow-null="true"/> | |||
| 156 | + | <arg name="method" type="uint" enum="present_method" /> | |||
| 157 | + | <arg name="output" type="object" interface="wl_output" allow-null="true"/> | |||
| 158 | + | </request> | |||
| 159 | + | ||||
| 160 | + | <request name="present_surface_for_mode"> | |||
| 161 | + | <description summary="present surface for display at a particular mode"> | |||
| 162 | + | Presents a surface on the given output for a particular mode. | |||
| 163 | + | ||||
| 164 | + | If the current size of the output differs from that of the surface, | |||
| 165 | + | the compositor will attempt to change the size of the output to | |||
| 166 | + | match the surface. The result of the mode-switch operation will be | |||
| 167 | + | returned via the provided wl_fullscreen_shell_mode_feedback object. | |||
| 168 | + | ||||
| 169 | + | If the current output mode matches the one requested or if the | |||
| 170 | + | compositor successfully switches the mode to match the surface, | |||
| 171 | + | then the mode_successful event will be sent and the output will | |||
| 172 | + | contain the contents of the given surface. If the compositor | |||
| 173 | + | cannot match the output size to the surface size, the mode_failed | |||
| 174 | + | will be sent and the output will contain the contents of the | |||
| 175 | + | previously presented surface (if any). If another surface is | |||
| 176 | + | presented on the given output before either of these has a chance | |||
| 177 | + | to happen, the present_cancelled event will be sent. | |||
| 178 | + | ||||
| 179 | + | Due to race conditions and other issues unknown to the client, no | |||
| 180 | + | mode-switch operation is guaranteed to succeed. However, if the | |||
| 181 | + | mode is one advertised by wl_output.mode or if the compositor | |||
| 182 | + | advertises the ARBITRARY_MODES capability, then the client should | |||
| 183 | + | expect that the mode-switch operation will usually succeed. | |||
| 184 | + | ||||
| 185 | + | If the size of the presented surface changes, the resulting output | |||
| 186 | + | is undefined. The compositor may attempt to change the output mode | |||
| 187 | + | to compensate. However, there is no guarantee that a suitable mode | |||
| 188 | + | will be found and the client has no way to be notified of success | |||
| 189 | + | or failure. | |||
| 190 | + | ||||
| 191 | + | The framerate parameter specifies the desired framerate for the | |||
| 192 | + | output in mHz. The compositor is free to ignore this parameter. A | |||
| 193 | + | value of 0 indicates that the client has no preference. | |||
| 194 | + | ||||
| 195 | + | If the value of wl_output.scale differs from wl_surface.buffer_scale, | |||
| 196 | + | then the compositor may choose a mode that matches either the buffer | |||
| 197 | + | size or the surface size. In either case, the surface will fill the | |||
| 198 | + | output. | |||
| 199 | + | ||||
| 200 | + | This request gives the surface the role of a fullscreen shell surface. | |||
| 201 | + | If the surface already has another role, it raises a role protocol | |||
| 202 | + | error. | |||
| 203 | + | </description> | |||
| 204 | + | <arg name="surface" type="object" interface="wl_surface"/> | |||
| 205 | + | <arg name="output" type="object" interface="wl_output"/> | |||
| 206 | + | <arg name="framerate" type="int"/> | |||
| 207 | + | <arg name="feedback" type="new_id" interface="zwp_fullscreen_shell_mode_feedback_v1"/> | |||
| 208 | + | </request> | |||
| 209 | + | ||||
| 210 | + | <enum name="error"> | |||
| 211 | + | <description summary="wl_fullscreen_shell error values"> | |||
| 212 | + | These errors can be emitted in response to wl_fullscreen_shell requests. | |||
| 213 | + | </description> | |||
| 214 | + | <entry name="invalid_method" value="0" summary="present_method is not known"/> | |||
| 215 | + | <entry name="role" value="1" summary="given wl_surface has another role"/> | |||
| 216 | + | </enum> | |||
| 217 | + | </interface> | |||
| 218 | + | ||||
| 219 | + | <interface name="zwp_fullscreen_shell_mode_feedback_v1" version="1"> | |||
| 220 | + | <event name="mode_successful" type="destructor"> | |||
| 221 | + | <description summary="mode switch succeeded"> | |||
| 222 | + | This event indicates that the attempted mode switch operation was | |||
| 223 | + | successful. A surface of the size requested in the mode switch | |||
| 224 | + | will fill the output without scaling. | |||
| 225 | + | ||||
| 226 | + | Upon receiving this event, the client should destroy the | |||
| 227 | + | wl_fullscreen_shell_mode_feedback object. | |||
| 228 | + | </description> | |||
| 229 | + | </event> | |||
| 230 | + | ||||
| 231 | + | <event name="mode_failed" type="destructor"> | |||
| 232 | + | <description summary="mode switch failed"> | |||
| 233 | + | This event indicates that the attempted mode switch operation | |||
| 234 | + | failed. This may be because the requested output mode is not | |||
| 235 | + | possible or it may mean that the compositor does not want to allow it. | |||
| 236 | + | ||||
| 237 | + | Upon receiving this event, the client should destroy the | |||
| 238 | + | wl_fullscreen_shell_mode_feedback object. | |||
| 239 | + | </description> | |||
| 240 | + | </event> | |||
| 241 | + | ||||
| 242 | + | <event name="present_cancelled" type="destructor"> | |||
| 243 | + | <description summary="mode switch cancelled"> | |||
| 244 | + | This event indicates that the attempted mode switch operation was | |||
| 245 | + | cancelled. Most likely this is because the client requested a | |||
| 246 | + | second mode switch before the first one completed. | |||
| 247 | + | ||||
| 248 | + | Upon receiving this event, the client should destroy the | |||
| 249 | + | wl_fullscreen_shell_mode_feedback object. | |||
| 250 | + | </description> | |||
| 251 | + | </event> | |||
| 252 | + | </interface> | |||
| 253 | + | ||||
| 254 | + | </protocol> | |||
A spec/xml/idleinhibit.xml +83 -0
| @@ -0,0 +1,83 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="idle_inhibit_unstable_v1"> | |||
| 3 | + | ||||
| 4 | + | <copyright> | |||
| 5 | + | Copyright © 2015 Samsung Electronics Co., Ltd | |||
| 6 | + | ||||
| 7 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 8 | + | copy of this software and associated documentation files (the "Software"), | |||
| 9 | + | to deal in the Software without restriction, including without limitation | |||
| 10 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 11 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 12 | + | Software is furnished to do so, subject to the following conditions: | |||
| 13 | + | ||||
| 14 | + | The above copyright notice and this permission notice (including the next | |||
| 15 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 16 | + | Software. | |||
| 17 | + | ||||
| 18 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 19 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 20 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 21 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 22 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 23 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 24 | + | DEALINGS IN THE SOFTWARE. | |||
| 25 | + | </copyright> | |||
| 26 | + | ||||
| 27 | + | <interface name="zwp_idle_inhibit_manager_v1" version="1"> | |||
| 28 | + | <description summary="control behavior when display idles"> | |||
| 29 | + | This interface permits inhibiting the idle behavior such as screen | |||
| 30 | + | blanking, locking, and screensaving. The client binds the idle manager | |||
| 31 | + | globally, then creates idle-inhibitor objects for each surface. | |||
| 32 | + | ||||
| 33 | + | Warning! The protocol described in this file is experimental and | |||
| 34 | + | backward incompatible changes may be made. Backward compatible changes | |||
| 35 | + | may be added together with the corresponding interface version bump. | |||
| 36 | + | Backward incompatible changes are done by bumping the version number in | |||
| 37 | + | the protocol and interface names and resetting the interface version. | |||
| 38 | + | Once the protocol is to be declared stable, the 'z' prefix and the | |||
| 39 | + | version number in the protocol and interface names are removed and the | |||
| 40 | + | interface version number is reset. | |||
| 41 | + | </description> | |||
| 42 | + | ||||
| 43 | + | <request name="destroy" type="destructor"> | |||
| 44 | + | <description summary="destroy the idle inhibitor object"> | |||
| 45 | + | Destroy the inhibit manager. | |||
| 46 | + | </description> | |||
| 47 | + | </request> | |||
| 48 | + | ||||
| 49 | + | <request name="create_inhibitor"> | |||
| 50 | + | <description summary="create a new inhibitor object"> | |||
| 51 | + | Create a new inhibitor object associated with the given surface. | |||
| 52 | + | </description> | |||
| 53 | + | <arg name="id" type="new_id" interface="zwp_idle_inhibitor_v1"/> | |||
| 54 | + | <arg name="surface" type="object" interface="wl_surface" | |||
| 55 | + | summary="the surface that inhibits the idle behavior"/> | |||
| 56 | + | </request> | |||
| 57 | + | ||||
| 58 | + | </interface> | |||
| 59 | + | ||||
| 60 | + | <interface name="zwp_idle_inhibitor_v1" version="1"> | |||
| 61 | + | <description summary="context object for inhibiting idle behavior"> | |||
| 62 | + | An idle inhibitor prevents the output that the associated surface is | |||
| 63 | + | visible on from being set to a state where it is not visually usable due | |||
| 64 | + | to lack of user interaction (e.g. blanked, dimmed, locked, set to power | |||
| 65 | + | save, etc.) Any screensaver processes are also blocked from displaying. | |||
| 66 | + | ||||
| 67 | + | If the surface is destroyed, unmapped, becomes occluded, loses | |||
| 68 | + | visibility, or otherwise becomes not visually relevant for the user, the | |||
| 69 | + | idle inhibitor will not be honored by the compositor; if the surface | |||
| 70 | + | subsequently regains visibility the inhibitor takes effect once again. | |||
| 71 | + | Likewise, the inhibitor isn't honored if the system was already idled at | |||
| 72 | + | the time the inhibitor was established, although if the system later | |||
| 73 | + | de-idles and re-idles the inhibitor will take effect. | |||
| 74 | + | </description> | |||
| 75 | + | ||||
| 76 | + | <request name="destroy" type="destructor"> | |||
| 77 | + | <description summary="destroy the idle inhibitor object"> | |||
| 78 | + | Remove the inhibitor effect from the associated wl_surface. | |||
| 79 | + | </description> | |||
| 80 | + | </request> | |||
| 81 | + | ||||
| 82 | + | </interface> | |||
| 83 | + | </protocol> | |||
A spec/xml/inputmethod.xml +494 -0
| @@ -0,0 +1,494 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="input_method_unstable_v2"> | |||
| 3 | + | ||||
| 4 | + | <copyright> | |||
| 5 | + | Copyright © 2008-2011 Kristian Høgsberg | |||
| 6 | + | Copyright © 2010-2011 Intel Corporation | |||
| 7 | + | Copyright © 2012-2013 Collabora, Ltd. | |||
| 8 | + | Copyright © 2012, 2013 Intel Corporation | |||
| 9 | + | Copyright © 2015, 2016 Jan Arne Petersen | |||
| 10 | + | Copyright © 2017, 2018 Red Hat, Inc. | |||
| 11 | + | Copyright © 2018 Purism SPC | |||
| 12 | + | ||||
| 13 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 14 | + | copy of this software and associated documentation files (the "Software"), | |||
| 15 | + | to deal in the Software without restriction, including without limitation | |||
| 16 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 17 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 18 | + | Software is furnished to do so, subject to the following conditions: | |||
| 19 | + | ||||
| 20 | + | The above copyright notice and this permission notice (including the next | |||
| 21 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 22 | + | Software. | |||
| 23 | + | ||||
| 24 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 25 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 26 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 27 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 28 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 29 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 30 | + | DEALINGS IN THE SOFTWARE. | |||
| 31 | + | </copyright> | |||
| 32 | + | ||||
| 33 | + | <description summary="Protocol for creating input methods"> | |||
| 34 | + | This protocol allows applications to act as input methods for compositors. | |||
| 35 | + | ||||
| 36 | + | An input method context is used to manage the state of the input method. | |||
| 37 | + | ||||
| 38 | + | Text strings are UTF-8 encoded, their indices and lengths are in bytes. | |||
| 39 | + | ||||
| 40 | + | This document adheres to the RFC 2119 when using words like "must", | |||
| 41 | + | "should", "may", etc. | |||
| 42 | + | ||||
| 43 | + | Warning! The protocol described in this file is experimental and | |||
| 44 | + | backward incompatible changes may be made. Backward compatible changes | |||
| 45 | + | may be added together with the corresponding interface version bump. | |||
| 46 | + | Backward incompatible changes are done by bumping the version number in | |||
| 47 | + | the protocol and interface names and resetting the interface version. | |||
| 48 | + | Once the protocol is to be declared stable, the 'z' prefix and the | |||
| 49 | + | version number in the protocol and interface names are removed and the | |||
| 50 | + | interface version number is reset. | |||
| 51 | + | </description> | |||
| 52 | + | ||||
| 53 | + | <interface name="zwp_input_method_v2" version="1"> | |||
| 54 | + | <description summary="input method"> | |||
| 55 | + | An input method object allows for clients to compose text. | |||
| 56 | + | ||||
| 57 | + | The objects connects the client to a text input in an application, and | |||
| 58 | + | lets the client to serve as an input method for a seat. | |||
| 59 | + | ||||
| 60 | + | The zwp_input_method_v2 object can occupy two distinct states: active and | |||
| 61 | + | inactive. In the active state, the object is associated to and | |||
| 62 | + | communicates with a text input. In the inactive state, there is no | |||
| 63 | + | associated text input, and the only communication is with the compositor. | |||
| 64 | + | Initially, the input method is in the inactive state. | |||
| 65 | + | ||||
| 66 | + | Requests issued in the inactive state must be accepted by the compositor. | |||
| 67 | + | Because of the serial mechanism, and the state reset on activate event, | |||
| 68 | + | they will not have any effect on the state of the next text input. | |||
| 69 | + | ||||
| 70 | + | There must be no more than one input method object per seat. | |||
| 71 | + | </description> | |||
| 72 | + | ||||
| 73 | + | <enum name="error"> | |||
| 74 | + | <entry name="role" value="0" summary="wl_surface has another role"/> | |||
| 75 | + | </enum> | |||
| 76 | + | ||||
| 77 | + | <event name="activate"> | |||
| 78 | + | <description summary="input method has been requested"> | |||
| 79 | + | Notification that a text input focused on this seat requested the input | |||
| 80 | + | method to be activated. | |||
| 81 | + | ||||
| 82 | + | This event serves the purpose of providing the compositor with an | |||
| 83 | + | active input method. | |||
| 84 | + | ||||
| 85 | + | This event resets all state associated with previous | |||
| 86 | + | surrounding_text, text_change_cause, and content_type events, as well | |||
| 87 | + | as the state associated with set_preedit_string, commit_string, and | |||
| 88 | + | delete_surrounding_text requests. In addition, it marks the | |||
| 89 | + | zwp_input_method_v2 object as active, and makes any existing | |||
| 90 | + | zwp_input_popup_surface_v2 objects visible. | |||
| 91 | + | ||||
| 92 | + | The surrounding_text, and content_type events must follow before the | |||
| 93 | + | next done event if the text input supports the respective | |||
| 94 | + | functionality. | |||
| 95 | + | ||||
| 96 | + | State set with this event is double-buffered. It will get applied on | |||
| 97 | + | the next zwp_input_method_v2.done event, and stay valid until changed. | |||
| 98 | + | </description> | |||
| 99 | + | </event> | |||
| 100 | + | ||||
| 101 | + | <event name="deactivate"> | |||
| 102 | + | <description summary="deactivate event"> | |||
| 103 | + | Notification that no focused text input currently needs an active | |||
| 104 | + | input method on this seat. | |||
| 105 | + | ||||
| 106 | + | This event marks the zwp_input_method_v2 object as inactive. The | |||
| 107 | + | compositor must make all existing zwp_input_popup_surface_v2 objects | |||
| 108 | + | invisible until the next activate event. | |||
| 109 | + | ||||
| 110 | + | State set with this event is double-buffered. It will get applied on | |||
| 111 | + | the next zwp_input_method_v2.done event, and stay valid until changed. | |||
| 112 | + | </description> | |||
| 113 | + | </event> | |||
| 114 | + | ||||
| 115 | + | <event name="surrounding_text"> | |||
| 116 | + | <description summary="surrounding text event"> | |||
| 117 | + | Updates the surrounding plain text around the cursor, excluding the | |||
| 118 | + | preedit text. | |||
| 119 | + | ||||
| 120 | + | If any preedit text is present, it is replaced with the cursor for the | |||
| 121 | + | purpose of this event. | |||
| 122 | + | ||||
| 123 | + | The argument text is a buffer containing the surrounding text, and must | |||
| 124 | + | include the cursor position, and the complete selection. It should | |||
| 125 | + | contain additional characters before and after these. There is a | |||
| 126 | + | maximum length of wayland messages, so text can not be longer than 4000 | |||
| 127 | + | bytes. | |||
| 128 | + | ||||
| 129 | + | cursor is the byte offset of the cursor within the text buffer. | |||
| 130 | + | ||||
| 131 | + | anchor is the byte offset of the selection anchor within the text | |||
| 132 | + | buffer. If there is no selected text, anchor must be the same as | |||
| 133 | + | cursor. | |||
| 134 | + | ||||
| 135 | + | If this event does not arrive before the first done event, the input | |||
| 136 | + | method may assume that the text input does not support this | |||
| 137 | + | functionality and ignore following surrounding_text events. | |||
| 138 | + | ||||
| 139 | + | Values set with this event are double-buffered. They will get applied | |||
| 140 | + | and set to initial values on the next zwp_input_method_v2.done | |||
| 141 | + | event. | |||
| 142 | + | ||||
| 143 | + | The initial state for affected fields is empty, meaning that the text | |||
| 144 | + | input does not support sending surrounding text. If the empty values | |||
| 145 | + | get applied, subsequent attempts to change them may have no effect. | |||
| 146 | + | </description> | |||
| 147 | + | <arg name="text" type="string"/> | |||
| 148 | + | <arg name="cursor" type="uint"/> | |||
| 149 | + | <arg name="anchor" type="uint"/> | |||
| 150 | + | </event> | |||
| 151 | + | ||||
| 152 | + | <event name="text_change_cause"> | |||
| 153 | + | <description summary="indicates the cause of surrounding text change"> | |||
| 154 | + | Tells the input method why the text surrounding the cursor changed. | |||
| 155 | + | ||||
| 156 | + | Whenever the client detects an external change in text, cursor, or | |||
| 157 | + | anchor position, it must issue this request to the compositor. This | |||
| 158 | + | request is intended to give the input method a chance to update the | |||
| 159 | + | preedit text in an appropriate way, e.g. by removing it when the user | |||
| 160 | + | starts typing with a keyboard. | |||
| 161 | + | ||||
| 162 | + | cause describes the source of the change. | |||
| 163 | + | ||||
| 164 | + | The value set with this event is double-buffered. It will get applied | |||
| 165 | + | and set to its initial value on the next zwp_input_method_v2.done | |||
| 166 | + | event. | |||
| 167 | + | ||||
| 168 | + | The initial value of cause is input_method. | |||
| 169 | + | </description> | |||
| 170 | + | <arg name="cause" type="uint" enum="zwp_text_input_v3.change_cause"/> | |||
| 171 | + | </event> | |||
| 172 | + | ||||
| 173 | + | <event name="content_type"> | |||
| 174 | + | <description summary="content purpose and hint"> | |||
| 175 | + | Indicates the content type and hint for the current | |||
| 176 | + | zwp_input_method_v2 instance. | |||
| 177 | + | ||||
| 178 | + | Values set with this event are double-buffered. They will get applied | |||
| 179 | + | on the next zwp_input_method_v2.done event. | |||
| 180 | + | ||||
| 181 | + | The initial value for hint is none, and the initial value for purpose | |||
| 182 | + | is normal. | |||
| 183 | + | </description> | |||
| 184 | + | <arg name="hint" type="uint" enum="zwp_text_input_v3.content_hint"/> | |||
| 185 | + | <arg name="purpose" type="uint" enum="zwp_text_input_v3.content_purpose"/> | |||
| 186 | + | </event> | |||
| 187 | + | ||||
| 188 | + | <event name="done"> | |||
| 189 | + | <description summary="apply state"> | |||
| 190 | + | Atomically applies state changes recently sent to the client. | |||
| 191 | + | ||||
| 192 | + | The done event establishes and updates the state of the client, and | |||
| 193 | + | must be issued after any changes to apply them. | |||
| 194 | + | ||||
| 195 | + | Text input state (content purpose, content hint, surrounding text, and | |||
| 196 | + | change cause) is conceptually double-buffered within an input method | |||
| 197 | + | context. | |||
| 198 | + | ||||
| 199 | + | Events modify the pending state, as opposed to the current state in use | |||
| 200 | + | by the input method. A done event atomically applies all pending state, | |||
| 201 | + | replacing the current state. After done, the new pending state is as | |||
| 202 | + | documented for each related request. | |||
| 203 | + | ||||
| 204 | + | Events must be applied in the order of arrival. | |||
| 205 | + | ||||
| 206 | + | Neither current nor pending state are modified unless noted otherwise. | |||
| 207 | + | </description> | |||
| 208 | + | </event> | |||
| 209 | + | ||||
| 210 | + | <request name="commit_string"> | |||
| 211 | + | <description summary="commit string"> | |||
| 212 | + | Send the commit string text for insertion to the application. | |||
| 213 | + | ||||
| 214 | + | Inserts a string at current cursor position (see commit event | |||
| 215 | + | sequence). The string to commit could be either just a single character | |||
| 216 | + | after a key press or the result of some composing. | |||
| 217 | + | ||||
| 218 | + | The argument text is a buffer containing the string to insert. There is | |||
| 219 | + | a maximum length of wayland messages, so text can not be longer than | |||
| 220 | + | 4000 bytes. | |||
| 221 | + | ||||
| 222 | + | Values set with this event are double-buffered. They must be applied | |||
| 223 | + | and reset to initial on the next zwp_text_input_v3.commit request. | |||
| 224 | + | ||||
| 225 | + | The initial value of text is an empty string. | |||
| 226 | + | </description> | |||
| 227 | + | <arg name="text" type="string"/> | |||
| 228 | + | </request> | |||
| 229 | + | ||||
| 230 | + | <request name="set_preedit_string"> | |||
| 231 | + | <description summary="pre-edit string"> | |||
| 232 | + | Send the pre-edit string text to the application text input. | |||
| 233 | + | ||||
| 234 | + | Place a new composing text (pre-edit) at the current cursor position. | |||
| 235 | + | Any previously set composing text must be removed. Any previously | |||
| 236 | + | existing selected text must be removed. The cursor is moved to a new | |||
| 237 | + | position within the preedit string. | |||
| 238 | + | ||||
| 239 | + | The argument text is a buffer containing the preedit string. There is | |||
| 240 | + | a maximum length of wayland messages, so text can not be longer than | |||
| 241 | + | 4000 bytes. | |||
| 242 | + | ||||
| 243 | + | The arguments cursor_begin and cursor_end are counted in bytes relative | |||
| 244 | + | to the beginning of the submitted string buffer. Cursor should be | |||
| 245 | + | hidden by the text input when both are equal to -1. | |||
| 246 | + | ||||
| 247 | + | cursor_begin indicates the beginning of the cursor. cursor_end | |||
| 248 | + | indicates the end of the cursor. It may be equal or different than | |||
| 249 | + | cursor_begin. | |||
| 250 | + | ||||
| 251 | + | Values set with this event are double-buffered. They must be applied on | |||
| 252 | + | the next zwp_input_method_v2.commit event. | |||
| 253 | + | ||||
| 254 | + | The initial value of text is an empty string. The initial value of | |||
| 255 | + | cursor_begin, and cursor_end are both 0. | |||
| 256 | + | </description> | |||
| 257 | + | <arg name="text" type="string"/> | |||
| 258 | + | <arg name="cursor_begin" type="int"/> | |||
| 259 | + | <arg name="cursor_end" type="int"/> | |||
| 260 | + | </request> | |||
| 261 | + | ||||
| 262 | + | <request name="delete_surrounding_text"> | |||
| 263 | + | <description summary="delete text"> | |||
| 264 | + | Remove the surrounding text. | |||
| 265 | + | ||||
| 266 | + | before_length and after_length are the number of bytes before and after | |||
| 267 | + | the current cursor index (excluding the preedit text) to delete. | |||
| 268 | + | ||||
| 269 | + | If any preedit text is present, it is replaced with the cursor for the | |||
| 270 | + | purpose of this event. In effect before_length is counted from the | |||
| 271 | + | beginning of preedit text, and after_length from its end (see commit | |||
| 272 | + | event sequence). | |||
| 273 | + | ||||
| 274 | + | Values set with this event are double-buffered. They must be applied | |||
| 275 | + | and reset to initial on the next zwp_input_method_v2.commit request. | |||
| 276 | + | ||||
| 277 | + | The initial values of both before_length and after_length are 0. | |||
| 278 | + | </description> | |||
| 279 | + | <arg name="before_length" type="uint"/> | |||
| 280 | + | <arg name="after_length" type="uint"/> | |||
| 281 | + | </request> | |||
| 282 | + | ||||
| 283 | + | <request name="commit"> | |||
| 284 | + | <description summary="apply state"> | |||
| 285 | + | Apply state changes from commit_string, set_preedit_string and | |||
| 286 | + | delete_surrounding_text requests. | |||
| 287 | + | ||||
| 288 | + | The state relating to these events is double-buffered, and each one | |||
| 289 | + | modifies the pending state. This request replaces the current state | |||
| 290 | + | with the pending state. | |||
| 291 | + | ||||
| 292 | + | The connected text input is expected to proceed by evaluating the | |||
| 293 | + | changes in the following order: | |||
| 294 | + | ||||
| 295 | + | 1. Replace existing preedit string with the cursor. | |||
| 296 | + | 2. Delete requested surrounding text. | |||
| 297 | + | 3. Insert commit string with the cursor at its end. | |||
| 298 | + | 4. Calculate surrounding text to send. | |||
| 299 | + | 5. Insert new preedit text in cursor position. | |||
| 300 | + | 6. Place cursor inside preedit text. | |||
| 301 | + | ||||
| 302 | + | The serial number reflects the last state of the zwp_input_method_v2 | |||
| 303 | + | object known to the client. The value of the serial argument must be | |||
| 304 | + | equal to the number of done events already issued by that object. When | |||
| 305 | + | the compositor receives a commit request with a serial different than | |||
| 306 | + | the number of past done events, it must proceed as normal, except it | |||
| 307 | + | should not change the current state of the zwp_input_method_v2 object. | |||
| 308 | + | </description> | |||
| 309 | + | <arg name="serial" type="uint"/> | |||
| 310 | + | </request> | |||
| 311 | + | ||||
| 312 | + | <request name="get_input_popup_surface"> | |||
| 313 | + | <description summary="create popup surface"> | |||
| 314 | + | Creates a new zwp_input_popup_surface_v2 object wrapping a given | |||
| 315 | + | surface. | |||
| 316 | + | ||||
| 317 | + | The surface gets assigned the "input_popup" role. If the surface | |||
| 318 | + | already has an assigned role, the compositor must issue a protocol | |||
| 319 | + | error. | |||
| 320 | + | </description> | |||
| 321 | + | <arg name="id" type="new_id" interface="zwp_input_popup_surface_v2"/> | |||
| 322 | + | <arg name="surface" type="object" interface="wl_surface"/> | |||
| 323 | + | </request> | |||
| 324 | + | ||||
| 325 | + | <request name="grab_keyboard"> | |||
| 326 | + | <description summary="grab hardware keyboard"> | |||
| 327 | + | Allow an input method to receive hardware keyboard input and process | |||
| 328 | + | key events to generate text events (with pre-edit) over the wire. This | |||
| 329 | + | allows input methods which compose multiple key events for inputting | |||
| 330 | + | text like it is done for CJK languages. | |||
| 331 | + | ||||
| 332 | + | The compositor should send all keyboard events on the seat to the grab | |||
| 333 | + | holder via the returned wl_keyboard object. Nevertheless, the | |||
| 334 | + | compositor may decide not to forward any particular event. The | |||
| 335 | + | compositor must not further process any event after it has been | |||
| 336 | + | forwarded to the grab holder. | |||
| 337 | + | ||||
| 338 | + | Releasing the resulting wl_keyboard object releases the grab. | |||
| 339 | + | </description> | |||
| 340 | + | <arg name="keyboard" type="new_id" | |||
| 341 | + | interface="zwp_input_method_keyboard_grab_v2"/> | |||
| 342 | + | </request> | |||
| 343 | + | ||||
| 344 | + | <event name="unavailable"> | |||
| 345 | + | <description summary="input method unavailable"> | |||
| 346 | + | The input method ceased to be available. | |||
| 347 | + | ||||
| 348 | + | The compositor must issue this event as the only event on the object if | |||
| 349 | + | there was another input_method object associated with the same seat at | |||
| 350 | + | the time of its creation. | |||
| 351 | + | ||||
| 352 | + | The compositor must issue this request when the object is no longer | |||
| 353 | + | usable, e.g. due to seat removal. | |||
| 354 | + | ||||
| 355 | + | The input method context becomes inert and should be destroyed after | |||
| 356 | + | deactivation is handled. Any further requests and events except for the | |||
| 357 | + | destroy request must be ignored. | |||
| 358 | + | </description> | |||
| 359 | + | </event> | |||
| 360 | + | ||||
| 361 | + | <request name="destroy" type="destructor"> | |||
| 362 | + | <description summary="destroy the text input"> | |||
| 363 | + | Destroys the zwp_text_input_v2 object and any associated child | |||
| 364 | + | objects, i.e. zwp_input_popup_surface_v2 and | |||
| 365 | + | zwp_input_method_keyboard_grab_v2. | |||
| 366 | + | </description> | |||
| 367 | + | </request> | |||
| 368 | + | </interface> | |||
| 369 | + | ||||
| 370 | + | <interface name="zwp_input_popup_surface_v2" version="1"> | |||
| 371 | + | <description summary="popup surface"> | |||
| 372 | + | This interface marks a surface as a popup for interacting with an input | |||
| 373 | + | method. | |||
| 374 | + | ||||
| 375 | + | The compositor should place it near the active text input area. It must | |||
| 376 | + | be visible if and only if the input method is in the active state. | |||
| 377 | + | ||||
| 378 | + | The client must not destroy the underlying wl_surface while the | |||
| 379 | + | zwp_input_popup_surface_v2 object exists. | |||
| 380 | + | </description> | |||
| 381 | + | ||||
| 382 | + | <event name="text_input_rectangle"> | |||
| 383 | + | <description summary="set text input area position"> | |||
| 384 | + | Notify about the position of the area of the text input expressed as a | |||
| 385 | + | rectangle in surface local coordinates. | |||
| 386 | + | ||||
| 387 | + | This is a hint to the input method telling it the relative position of | |||
| 388 | + | the text being entered. | |||
| 389 | + | </description> | |||
| 390 | + | <arg name="x" type="int"/> | |||
| 391 | + | <arg name="y" type="int"/> | |||
| 392 | + | <arg name="width" type="int"/> | |||
| 393 | + | <arg name="height" type="int"/> | |||
| 394 | + | </event> | |||
| 395 | + | ||||
| 396 | + | <request name="destroy" type="destructor"/> | |||
| 397 | + | </interface> | |||
| 398 | + | ||||
| 399 | + | <interface name="zwp_input_method_keyboard_grab_v2" version="1"> | |||
| 400 | + | <!-- Closely follows wl_keyboard version 6 --> | |||
| 401 | + | <description summary="keyboard grab"> | |||
| 402 | + | The zwp_input_method_keyboard_grab_v2 interface represents an exclusive | |||
| 403 | + | grab of the wl_keyboard interface associated with the seat. | |||
| 404 | + | </description> | |||
| 405 | + | ||||
| 406 | + | <event name="keymap"> | |||
| 407 | + | <description summary="keyboard mapping"> | |||
| 408 | + | This event provides a file descriptor to the client which can be | |||
| 409 | + | memory-mapped to provide a keyboard mapping description. | |||
| 410 | + | </description> | |||
| 411 | + | <arg name="format" type="uint" enum="wl_keyboard.keymap_format" | |||
| 412 | + | summary="keymap format"/> | |||
| 413 | + | <arg name="fd" type="fd" summary="keymap file descriptor"/> | |||
| 414 | + | <arg name="size" type="uint" summary="keymap size, in bytes"/> | |||
| 415 | + | </event> | |||
| 416 | + | ||||
| 417 | + | <event name="key"> | |||
| 418 | + | <description summary="key event"> | |||
| 419 | + | A key was pressed or released. | |||
| 420 | + | The time argument is a timestamp with millisecond granularity, with an | |||
| 421 | + | undefined base. | |||
| 422 | + | </description> | |||
| 423 | + | <arg name="serial" type="uint" summary="serial number of the key event"/> | |||
| 424 | + | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |||
| 425 | + | <arg name="key" type="uint" summary="key that produced the event"/> | |||
| 426 | + | <arg name="state" type="uint" enum="wl_keyboard.key_state" | |||
| 427 | + | summary="physical state of the key"/> | |||
| 428 | + | </event> | |||
| 429 | + | ||||
| 430 | + | <event name="modifiers"> | |||
| 431 | + | <description summary="modifier and group state"> | |||
| 432 | + | Notifies clients that the modifier and/or group state has changed, and | |||
| 433 | + | it should update its local state. | |||
| 434 | + | </description> | |||
| 435 | + | <arg name="serial" type="uint" summary="serial number of the modifiers event"/> | |||
| 436 | + | <arg name="mods_depressed" type="uint" summary="depressed modifiers"/> | |||
| 437 | + | <arg name="mods_latched" type="uint" summary="latched modifiers"/> | |||
| 438 | + | <arg name="mods_locked" type="uint" summary="locked modifiers"/> | |||
| 439 | + | <arg name="group" type="uint" summary="keyboard layout"/> | |||
| 440 | + | </event> | |||
| 441 | + | ||||
| 442 | + | <request name="release" type="destructor"> | |||
| 443 | + | <description summary="release the grab object"/> | |||
| 444 | + | </request> | |||
| 445 | + | ||||
| 446 | + | <event name="repeat_info"> | |||
| 447 | + | <description summary="repeat rate and delay"> | |||
| 448 | + | Informs the client about the keyboard's repeat rate and delay. | |||
| 449 | + | ||||
| 450 | + | This event is sent as soon as the zwp_input_method_keyboard_grab_v2 | |||
| 451 | + | object has been created, and is guaranteed to be received by the | |||
| 452 | + | client before any key press event. | |||
| 453 | + | ||||
| 454 | + | Negative values for either rate or delay are illegal. A rate of zero | |||
| 455 | + | will disable any repeating (regardless of the value of delay). | |||
| 456 | + | ||||
| 457 | + | This event can be sent later on as well with a new value if necessary, | |||
| 458 | + | so clients should continue listening for the event past the creation | |||
| 459 | + | of zwp_input_method_keyboard_grab_v2. | |||
| 460 | + | </description> | |||
| 461 | + | <arg name="rate" type="int" | |||
| 462 | + | summary="the rate of repeating keys in characters per second"/> | |||
| 463 | + | <arg name="delay" type="int" | |||
| 464 | + | summary="delay in milliseconds since key down until repeating starts"/> | |||
| 465 | + | </event> | |||
| 466 | + | </interface> | |||
| 467 | + | ||||
| 468 | + | <interface name="zwp_input_method_manager_v2" version="1"> | |||
| 469 | + | <description summary="input method manager"> | |||
| 470 | + | The input method manager allows the client to become the input method on | |||
| 471 | + | a chosen seat. | |||
| 472 | + | ||||
| 473 | + | No more than one input method must be associated with any seat at any | |||
| 474 | + | given time. | |||
| 475 | + | </description> | |||
| 476 | + | ||||
| 477 | + | <request name="get_input_method"> | |||
| 478 | + | <description summary="request an input method object"> | |||
| 479 | + | Request a new input zwp_input_method_v2 object associated with a given | |||
| 480 | + | seat. | |||
| 481 | + | </description> | |||
| 482 | + | <arg name="seat" type="object" interface="wl_seat"/> | |||
| 483 | + | <arg name="input_method" type="new_id" interface="zwp_input_method_v2"/> | |||
| 484 | + | </request> | |||
| 485 | + | ||||
| 486 | + | <request name="destroy" type="destructor"> | |||
| 487 | + | <description summary="destroy the input method manager"> | |||
| 488 | + | Destroys the zwp_input_method_manager_v2 object. | |||
| 489 | + | ||||
| 490 | + | The zwp_input_method_v2 objects originating from it remain valid. | |||
| 491 | + | </description> | |||
| 492 | + | </request> | |||
| 493 | + | </interface> | |||
| 494 | + | </protocol> | |||
A spec/xml/inputtimestamps.xml +145 -0
| @@ -0,0 +1,145 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="input_timestamps_unstable_v1"> | |||
| 3 | + | ||||
| 4 | + | <copyright> | |||
| 5 | + | Copyright © 2017 Collabora, Ltd. | |||
| 6 | + | ||||
| 7 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 8 | + | copy of this software and associated documentation files (the "Software"), | |||
| 9 | + | to deal in the Software without restriction, including without limitation | |||
| 10 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 11 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 12 | + | Software is furnished to do so, subject to the following conditions: | |||
| 13 | + | ||||
| 14 | + | The above copyright notice and this permission notice (including the next | |||
| 15 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 16 | + | Software. | |||
| 17 | + | ||||
| 18 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 19 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 20 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 21 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 22 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 23 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 24 | + | DEALINGS IN THE SOFTWARE. | |||
| 25 | + | </copyright> | |||
| 26 | + | ||||
| 27 | + | <description summary="High-resolution timestamps for input events"> | |||
| 28 | + | This protocol specifies a way for a client to request and receive | |||
| 29 | + | high-resolution timestamps for input events. | |||
| 30 | + | ||||
| 31 | + | Warning! The protocol described in this file is experimental and | |||
| 32 | + | backward incompatible changes may be made. Backward compatible changes | |||
| 33 | + | may be added together with the corresponding interface version bump. | |||
| 34 | + | Backward incompatible changes are done by bumping the version number in | |||
| 35 | + | the protocol and interface names and resetting the interface version. | |||
| 36 | + | Once the protocol is to be declared stable, the 'z' prefix and the | |||
| 37 | + | version number in the protocol and interface names are removed and the | |||
| 38 | + | interface version number is reset. | |||
| 39 | + | </description> | |||
| 40 | + | ||||
| 41 | + | <interface name="zwp_input_timestamps_manager_v1" version="1"> | |||
| 42 | + | <description summary="context object for high-resolution input timestamps"> | |||
| 43 | + | A global interface used for requesting high-resolution timestamps | |||
| 44 | + | for input events. | |||
| 45 | + | </description> | |||
| 46 | + | ||||
| 47 | + | <request name="destroy" type="destructor"> | |||
| 48 | + | <description summary="destroy the input timestamps manager object"> | |||
| 49 | + | Informs the server that the client will no longer be using this | |||
| 50 | + | protocol object. Existing objects created by this object are not | |||
| 51 | + | affected. | |||
| 52 | + | </description> | |||
| 53 | + | </request> | |||
| 54 | + | ||||
| 55 | + | <request name="get_keyboard_timestamps"> | |||
| 56 | + | <description summary="subscribe to high-resolution keyboard timestamp events"> | |||
| 57 | + | Creates a new input timestamps object that represents a subscription | |||
| 58 | + | to high-resolution timestamp events for all wl_keyboard events that | |||
| 59 | + | carry a timestamp. | |||
| 60 | + | ||||
| 61 | + | If the associated wl_keyboard object is invalidated, either through | |||
| 62 | + | client action (e.g. release) or server-side changes, the input | |||
| 63 | + | timestamps object becomes inert and the client should destroy it | |||
| 64 | + | by calling zwp_input_timestamps_v1.destroy. | |||
| 65 | + | </description> | |||
| 66 | + | <arg name="id" type="new_id" interface="zwp_input_timestamps_v1"/> | |||
| 67 | + | <arg name="keyboard" type="object" interface="wl_keyboard" | |||
| 68 | + | summary="the wl_keyboard object for which to get timestamp events"/> | |||
| 69 | + | </request> | |||
| 70 | + | ||||
| 71 | + | <request name="get_pointer_timestamps"> | |||
| 72 | + | <description summary="subscribe to high-resolution pointer timestamp events"> | |||
| 73 | + | Creates a new input timestamps object that represents a subscription | |||
| 74 | + | to high-resolution timestamp events for all wl_pointer events that | |||
| 75 | + | carry a timestamp. | |||
| 76 | + | ||||
| 77 | + | If the associated wl_pointer object is invalidated, either through | |||
| 78 | + | client action (e.g. release) or server-side changes, the input | |||
| 79 | + | timestamps object becomes inert and the client should destroy it | |||
| 80 | + | by calling zwp_input_timestamps_v1.destroy. | |||
| 81 | + | </description> | |||
| 82 | + | <arg name="id" type="new_id" interface="zwp_input_timestamps_v1"/> | |||
| 83 | + | <arg name="pointer" type="object" interface="wl_pointer" | |||
| 84 | + | summary="the wl_pointer object for which to get timestamp events"/> | |||
| 85 | + | </request> | |||
| 86 | + | ||||
| 87 | + | <request name="get_touch_timestamps"> | |||
| 88 | + | <description summary="subscribe to high-resolution touch timestamp events"> | |||
| 89 | + | Creates a new input timestamps object that represents a subscription | |||
| 90 | + | to high-resolution timestamp events for all wl_touch events that | |||
| 91 | + | carry a timestamp. | |||
| 92 | + | ||||
| 93 | + | If the associated wl_touch object becomes invalid, either through | |||
| 94 | + | client action (e.g. release) or server-side changes, the input | |||
| 95 | + | timestamps object becomes inert and the client should destroy it | |||
| 96 | + | by calling zwp_input_timestamps_v1.destroy. | |||
| 97 | + | </description> | |||
| 98 | + | <arg name="id" type="new_id" interface="zwp_input_timestamps_v1"/> | |||
| 99 | + | <arg name="touch" type="object" interface="wl_touch" | |||
| 100 | + | summary="the wl_touch object for which to get timestamp events"/> | |||
| 101 | + | </request> | |||
| 102 | + | </interface> | |||
| 103 | + | ||||
| 104 | + | <interface name="zwp_input_timestamps_v1" version="1"> | |||
| 105 | + | <description summary="context object for input timestamps"> | |||
| 106 | + | Provides high-resolution timestamp events for a set of subscribed input | |||
| 107 | + | events. The set of subscribed input events is determined by the | |||
| 108 | + | zwp_input_timestamps_manager_v1 request used to create this object. | |||
| 109 | + | </description> | |||
| 110 | + | ||||
| 111 | + | <request name="destroy" type="destructor"> | |||
| 112 | + | <description summary="destroy the input timestamps object"> | |||
| 113 | + | Informs the server that the client will no longer be using this | |||
| 114 | + | protocol object. After the server processes the request, no more | |||
| 115 | + | timestamp events will be emitted. | |||
| 116 | + | </description> | |||
| 117 | + | </request> | |||
| 118 | + | ||||
| 119 | + | <event name="timestamp"> | |||
| 120 | + | <description summary="high-resolution timestamp event"> | |||
| 121 | + | The timestamp event is associated with the first subsequent input event | |||
| 122 | + | carrying a timestamp which belongs to the set of input events this | |||
| 123 | + | object is subscribed to. | |||
| 124 | + | ||||
| 125 | + | The timestamp provided by this event is a high-resolution version of | |||
| 126 | + | the timestamp argument of the associated input event. The provided | |||
| 127 | + | timestamp is in the same clock domain and is at least as accurate as | |||
| 128 | + | the associated input event timestamp. | |||
| 129 | + | ||||
| 130 | + | The timestamp is expressed as tv_sec_hi, tv_sec_lo, tv_nsec triples, | |||
| 131 | + | each component being an unsigned 32-bit value. Whole seconds are in | |||
| 132 | + | tv_sec which is a 64-bit value combined from tv_sec_hi and tv_sec_lo, | |||
| 133 | + | and the additional fractional part in tv_nsec as nanoseconds. Hence, | |||
| 134 | + | for valid timestamps tv_nsec must be in [0, 999999999]. | |||
| 135 | + | </description> | |||
| 136 | + | <arg name="tv_sec_hi" type="uint" | |||
| 137 | + | summary="high 32 bits of the seconds part of the timestamp"/> | |||
| 138 | + | <arg name="tv_sec_lo" type="uint" | |||
| 139 | + | summary="low 32 bits of the seconds part of the timestamp"/> | |||
| 140 | + | <arg name="tv_nsec" type="uint" | |||
| 141 | + | summary="nanoseconds part of the timestamp"/> | |||
| 142 | + | </event> | |||
| 143 | + | </interface> | |||
| 144 | + | ||||
| 145 | + | </protocol> | |||
A spec/xml/keyboardshortcutsinhibit.xml +143 -0
| @@ -0,0 +1,143 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="keyboard_shortcuts_inhibit_unstable_v1"> | |||
| 3 | + | ||||
| 4 | + | <copyright> | |||
| 5 | + | Copyright © 2017 Red Hat Inc. | |||
| 6 | + | ||||
| 7 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 8 | + | copy of this software and associated documentation files (the "Software"), | |||
| 9 | + | to deal in the Software without restriction, including without limitation | |||
| 10 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 11 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 12 | + | Software is furnished to do so, subject to the following conditions: | |||
| 13 | + | ||||
| 14 | + | The above copyright notice and this permission notice (including the next | |||
| 15 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 16 | + | Software. | |||
| 17 | + | ||||
| 18 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 19 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 20 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 21 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 22 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 23 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 24 | + | DEALINGS IN THE SOFTWARE. | |||
| 25 | + | </copyright> | |||
| 26 | + | ||||
| 27 | + | <description summary="Protocol for inhibiting the compositor keyboard shortcuts"> | |||
| 28 | + | This protocol specifies a way for a client to request the compositor | |||
| 29 | + | to ignore its own keyboard shortcuts for a given seat, so that all | |||
| 30 | + | key events from that seat get forwarded to a surface. | |||
| 31 | + | ||||
| 32 | + | Warning! The protocol described in this file is experimental and | |||
| 33 | + | backward incompatible changes may be made. Backward compatible | |||
| 34 | + | changes may be added together with the corresponding interface | |||
| 35 | + | version bump. | |||
| 36 | + | Backward incompatible changes are done by bumping the version | |||
| 37 | + | number in the protocol and interface names and resetting the | |||
| 38 | + | interface version. Once the protocol is to be declared stable, | |||
| 39 | + | the 'z' prefix and the version number in the protocol and | |||
| 40 | + | interface names are removed and the interface version number is | |||
| 41 | + | reset. | |||
| 42 | + | </description> | |||
| 43 | + | ||||
| 44 | + | <interface name="zwp_keyboard_shortcuts_inhibit_manager_v1" version="1"> | |||
| 45 | + | <description summary="context object for keyboard grab_manager"> | |||
| 46 | + | A global interface used for inhibiting the compositor keyboard shortcuts. | |||
| 47 | + | </description> | |||
| 48 | + | ||||
| 49 | + | <request name="destroy" type="destructor"> | |||
| 50 | + | <description summary="destroy the keyboard shortcuts inhibitor object"> | |||
| 51 | + | Destroy the keyboard shortcuts inhibitor manager. | |||
| 52 | + | </description> | |||
| 53 | + | </request> | |||
| 54 | + | ||||
| 55 | + | <request name="inhibit_shortcuts"> | |||
| 56 | + | <description summary="create a new keyboard shortcuts inhibitor object"> | |||
| 57 | + | Create a new keyboard shortcuts inhibitor object associated with | |||
| 58 | + | the given surface for the given seat. | |||
| 59 | + | ||||
| 60 | + | If shortcuts are already inhibited for the specified seat and surface, | |||
| 61 | + | a protocol error "already_inhibited" is raised by the compositor. | |||
| 62 | + | </description> | |||
| 63 | + | <arg name="id" type="new_id" interface="zwp_keyboard_shortcuts_inhibitor_v1"/> | |||
| 64 | + | <arg name="surface" type="object" interface="wl_surface" | |||
| 65 | + | summary="the surface that inhibits the keyboard shortcuts behavior"/> | |||
| 66 | + | <arg name="seat" type="object" interface="wl_seat" | |||
| 67 | + | summary="the wl_seat for which keyboard shortcuts should be disabled"/> | |||
| 68 | + | </request> | |||
| 69 | + | ||||
| 70 | + | <enum name="error"> | |||
| 71 | + | <entry name="already_inhibited" | |||
| 72 | + | value="0" | |||
| 73 | + | summary="the shortcuts are already inhibited for this surface"/> | |||
| 74 | + | </enum> | |||
| 75 | + | </interface> | |||
| 76 | + | ||||
| 77 | + | <interface name="zwp_keyboard_shortcuts_inhibitor_v1" version="1"> | |||
| 78 | + | <description summary="context object for keyboard shortcuts inhibitor"> | |||
| 79 | + | A keyboard shortcuts inhibitor instructs the compositor to ignore | |||
| 80 | + | its own keyboard shortcuts when the associated surface has keyboard | |||
| 81 | + | focus. As a result, when the surface has keyboard focus on the given | |||
| 82 | + | seat, it will receive all key events originating from the specified | |||
| 83 | + | seat, even those which would normally be caught by the compositor for | |||
| 84 | + | its own shortcuts. | |||
| 85 | + | ||||
| 86 | + | The Wayland compositor is however under no obligation to disable | |||
| 87 | + | all of its shortcuts, and may keep some special key combo for its own | |||
| 88 | + | use, including but not limited to one allowing the user to forcibly | |||
| 89 | + | restore normal keyboard events routing in the case of an unwilling | |||
| 90 | + | client. The compositor may also use the same key combo to reactivate | |||
| 91 | + | an existing shortcut inhibitor that was previously deactivated on | |||
| 92 | + | user request. | |||
| 93 | + | ||||
| 94 | + | When the compositor restores its own keyboard shortcuts, an | |||
| 95 | + | "inactive" event is emitted to notify the client that the keyboard | |||
| 96 | + | shortcuts inhibitor is not effectively active for the surface and | |||
| 97 | + | seat any more, and the client should not expect to receive all | |||
| 98 | + | keyboard events. | |||
| 99 | + | ||||
| 100 | + | When the keyboard shortcuts inhibitor is inactive, the client has | |||
| 101 | + | no way to forcibly reactivate the keyboard shortcuts inhibitor. | |||
| 102 | + | ||||
| 103 | + | The user can chose to re-enable a previously deactivated keyboard | |||
| 104 | + | shortcuts inhibitor using any mechanism the compositor may offer, | |||
| 105 | + | in which case the compositor will send an "active" event to notify | |||
| 106 | + | the client. | |||
| 107 | + | ||||
| 108 | + | If the surface is destroyed, unmapped, or loses the seat's keyboard | |||
| 109 | + | focus, the keyboard shortcuts inhibitor becomes irrelevant and the | |||
| 110 | + | compositor will restore its own keyboard shortcuts but no "inactive" | |||
| 111 | + | event is emitted in this case. | |||
| 112 | + | </description> | |||
| 113 | + | ||||
| 114 | + | <request name="destroy" type="destructor"> | |||
| 115 | + | <description summary="destroy the keyboard shortcuts inhibitor object"> | |||
| 116 | + | Remove the keyboard shortcuts inhibitor from the associated wl_surface. | |||
| 117 | + | </description> | |||
| 118 | + | </request> | |||
| 119 | + | ||||
| 120 | + | <event name="active"> | |||
| 121 | + | <description summary="shortcuts are inhibited"> | |||
| 122 | + | This event indicates that the shortcut inhibitor is active. | |||
| 123 | + | ||||
| 124 | + | The compositor sends this event every time compositor shortcuts | |||
| 125 | + | are inhibited on behalf of the surface. When active, the client | |||
| 126 | + | may receive input events normally reserved by the compositor | |||
| 127 | + | (see zwp_keyboard_shortcuts_inhibitor_v1). | |||
| 128 | + | ||||
| 129 | + | This occurs typically when the initial request "inhibit_shortcuts" | |||
| 130 | + | first becomes active or when the user instructs the compositor to | |||
| 131 | + | re-enable and existing shortcuts inhibitor using any mechanism | |||
| 132 | + | offered by the compositor. | |||
| 133 | + | </description> | |||
| 134 | + | </event> | |||
| 135 | + | ||||
| 136 | + | <event name="inactive"> | |||
| 137 | + | <description summary="shortcuts are restored"> | |||
| 138 | + | This event indicates that the shortcuts inhibitor is inactive, | |||
| 139 | + | normal shortcuts processing is restored by the compositor. | |||
| 140 | + | </description> | |||
| 141 | + | </event> | |||
| 142 | + | </interface> | |||
| 143 | + | </protocol> | |||
A spec/xml/linuxdmabuf.xml +623 -0
| @@ -0,0 +1,623 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="linux_dmabuf_v1"> | |||
| 3 | + | ||||
| 4 | + | <copyright> | |||
| 5 | + | Copyright © 2014, 2015 Collabora, Ltd. | |||
| 6 | + | ||||
| 7 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 8 | + | copy of this software and associated documentation files (the "Software"), | |||
| 9 | + | to deal in the Software without restriction, including without limitation | |||
| 10 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 11 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 12 | + | Software is furnished to do so, subject to the following conditions: | |||
| 13 | + | ||||
| 14 | + | The above copyright notice and this permission notice (including the next | |||
| 15 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 16 | + | Software. | |||
| 17 | + | ||||
| 18 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 19 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 20 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 21 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 22 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 23 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 24 | + | DEALINGS IN THE SOFTWARE. | |||
| 25 | + | </copyright> | |||
| 26 | + | ||||
| 27 | + | <interface name="zwp_linux_dmabuf_v1" version="6"> | |||
| 28 | + | <description summary="factory for creating dmabuf-based wl_buffers"> | |||
| 29 | + | This interface offers ways to create generic dmabuf-based wl_buffers. | |||
| 30 | + | ||||
| 31 | + | For more information about dmabuf, see: | |||
| 32 | + | https://www.kernel.org/doc/html/next/userspace-api/dma-buf-alloc-exchange.html | |||
| 33 | + | ||||
| 34 | + | Clients can use the get_surface_feedback request to get dmabuf feedback | |||
| 35 | + | for a particular surface. If the client wants to retrieve feedback not | |||
| 36 | + | tied to a surface, they can use the get_default_feedback request. | |||
| 37 | + | ||||
| 38 | + | The following are required from clients: | |||
| 39 | + | ||||
| 40 | + | - Clients must ensure that either all data in the dma-buf is | |||
| 41 | + | coherent for all subsequent read access or that coherency is | |||
| 42 | + | correctly handled by the underlying kernel-side dma-buf | |||
| 43 | + | implementation. | |||
| 44 | + | ||||
| 45 | + | - Don't make any more attachments after sending the buffer to the | |||
| 46 | + | compositor. Making more attachments later increases the risk of | |||
| 47 | + | the compositor not being able to use (re-import) an existing | |||
| 48 | + | dmabuf-based wl_buffer. | |||
| 49 | + | ||||
| 50 | + | The underlying graphics stack must ensure the following: | |||
| 51 | + | ||||
| 52 | + | - The dmabuf file descriptors relayed to the server will stay valid | |||
| 53 | + | for the whole lifetime of the wl_buffer. This means the server may | |||
| 54 | + | at any time use those fds to import the dmabuf into any kernel | |||
| 55 | + | sub-system that might accept it. | |||
| 56 | + | ||||
| 57 | + | However, when the underlying graphics stack fails to deliver the | |||
| 58 | + | promise, because of e.g. a device hot-unplug which raises internal | |||
| 59 | + | errors, after the wl_buffer has been successfully created the | |||
| 60 | + | compositor must not raise protocol errors to the client when dmabuf | |||
| 61 | + | import later fails. | |||
| 62 | + | ||||
| 63 | + | To create a wl_buffer from one or more dmabufs, a client creates a | |||
| 64 | + | zwp_linux_buffer_params_v1 object with a zwp_linux_dmabuf_v1.create_params | |||
| 65 | + | request. All planes required by the intended format are added with | |||
| 66 | + | the 'add' request. Finally, a 'create' or 'create_immed' request is | |||
| 67 | + | issued, which has the following outcome depending on the import success. | |||
| 68 | + | ||||
| 69 | + | The 'create' request, | |||
| 70 | + | - on success, triggers a 'created' event which provides the final | |||
| 71 | + | wl_buffer to the client. | |||
| 72 | + | - on failure, triggers a 'failed' event to convey that the server | |||
| 73 | + | cannot use the dmabufs received from the client. | |||
| 74 | + | ||||
| 75 | + | For the 'create_immed' request, | |||
| 76 | + | - on success, the server immediately imports the added dmabufs to | |||
| 77 | + | create a wl_buffer. No event is sent from the server in this case. | |||
| 78 | + | - on failure, the server can choose to either: | |||
| 79 | + | - terminate the client by raising a fatal error. | |||
| 80 | + | - mark the wl_buffer as failed, and send a 'failed' event to the | |||
| 81 | + | client. If the client uses a failed wl_buffer as an argument to any | |||
| 82 | + | request, the behaviour is compositor implementation-defined. | |||
| 83 | + | ||||
| 84 | + | For all DRM formats and unless specified in another protocol extension, | |||
| 85 | + | pre-multiplied alpha is used for pixel values. | |||
| 86 | + | ||||
| 87 | + | Unless specified otherwise in another protocol extension, implicit | |||
| 88 | + | synchronization is used. In other words, compositors and clients must | |||
| 89 | + | wait and signal fences implicitly passed via the DMA-BUF's reservation | |||
| 90 | + | mechanism. | |||
| 91 | + | </description> | |||
| 92 | + | ||||
| 93 | + | <request name="destroy" type="destructor"> | |||
| 94 | + | <description summary="unbind the factory"> | |||
| 95 | + | Objects created through this interface, especially wl_buffers, will | |||
| 96 | + | remain valid. | |||
| 97 | + | </description> | |||
| 98 | + | </request> | |||
| 99 | + | ||||
| 100 | + | <request name="create_params"> | |||
| 101 | + | <description summary="create a temporary object for buffer parameters"> | |||
| 102 | + | This temporary object is used to collect multiple dmabuf handles into | |||
| 103 | + | a single batch to create a wl_buffer. It can only be used once and | |||
| 104 | + | should be destroyed after a 'created' or 'failed' event has been | |||
| 105 | + | received. | |||
| 106 | + | </description> | |||
| 107 | + | <arg name="params_id" type="new_id" interface="zwp_linux_buffer_params_v1" | |||
| 108 | + | summary="id for the newly created zwp_linux_buffer_params_v1"/> | |||
| 109 | + | </request> | |||
| 110 | + | ||||
| 111 | + | <event name="format" deprecated-since="4"> | |||
| 112 | + | <description summary="supported buffer format"> | |||
| 113 | + | This event advertises one buffer format that the server supports. | |||
| 114 | + | All the supported formats are advertised once when the client | |||
| 115 | + | binds to this interface. A roundtrip after binding guarantees | |||
| 116 | + | that the client has received all supported formats. | |||
| 117 | + | ||||
| 118 | + | For the definition of the format codes, see the | |||
| 119 | + | zwp_linux_buffer_params_v1::create request. | |||
| 120 | + | ||||
| 121 | + | Starting version 4, the format event is deprecated and must not be | |||
| 122 | + | sent by compositors. Instead, use get_default_feedback or | |||
| 123 | + | get_surface_feedback. | |||
| 124 | + | </description> | |||
| 125 | + | <arg name="format" type="uint" summary="DRM_FORMAT code"/> | |||
| 126 | + | </event> | |||
| 127 | + | ||||
| 128 | + | <event name="modifier" since="3" deprecated-since="4"> | |||
| 129 | + | <description summary="supported buffer format modifier"> | |||
| 130 | + | This event advertises the formats that the server supports, along with | |||
| 131 | + | the modifiers supported for each format. All the supported modifiers | |||
| 132 | + | for all the supported formats are advertised once when the client | |||
| 133 | + | binds to this interface. A roundtrip after binding guarantees that | |||
| 134 | + | the client has received all supported format-modifier pairs. | |||
| 135 | + | ||||
| 136 | + | For legacy support, DRM_FORMAT_MOD_INVALID (that is, modifier_hi == | |||
| 137 | + | 0x00ffffff and modifier_lo == 0xffffffff) is allowed in this event. | |||
| 138 | + | It indicates that the server can support the format with an implicit | |||
| 139 | + | modifier. When a plane has DRM_FORMAT_MOD_INVALID as its modifier, it | |||
| 140 | + | is as if no explicit modifier is specified. The effective modifier | |||
| 141 | + | will be derived from the dmabuf. | |||
| 142 | + | ||||
| 143 | + | A compositor that sends valid modifiers and DRM_FORMAT_MOD_INVALID for | |||
| 144 | + | a given format supports both explicit modifiers and implicit modifiers. | |||
| 145 | + | ||||
| 146 | + | For the definition of the format and modifier codes, see the | |||
| 147 | + | zwp_linux_buffer_params_v1::create and zwp_linux_buffer_params_v1::add | |||
| 148 | + | requests. | |||
| 149 | + | ||||
| 150 | + | Starting version 4, the modifier event is deprecated and must not be | |||
| 151 | + | sent by compositors. Instead, use get_default_feedback or | |||
| 152 | + | get_surface_feedback. | |||
| 153 | + | </description> | |||
| 154 | + | <arg name="format" type="uint" summary="DRM_FORMAT code"/> | |||
| 155 | + | <arg name="modifier_hi" type="uint" | |||
| 156 | + | summary="high 32 bits of layout modifier"/> | |||
| 157 | + | <arg name="modifier_lo" type="uint" | |||
| 158 | + | summary="low 32 bits of layout modifier"/> | |||
| 159 | + | </event> | |||
| 160 | + | ||||
| 161 | + | <!-- Version 4 additions --> | |||
| 162 | + | ||||
| 163 | + | <request name="get_default_feedback" since="4"> | |||
| 164 | + | <description summary="get default feedback"> | |||
| 165 | + | This request creates a new zwp_linux_dmabuf_feedback_v1 object not bound | |||
| 166 | + | to a particular surface. This object will deliver feedback about dmabuf | |||
| 167 | + | parameters to use if the client doesn't support per-surface feedback | |||
| 168 | + | (see get_surface_feedback). | |||
| 169 | + | </description> | |||
| 170 | + | <arg name="id" type="new_id" interface="zwp_linux_dmabuf_feedback_v1"/> | |||
| 171 | + | </request> | |||
| 172 | + | ||||
| 173 | + | <request name="get_surface_feedback" since="4"> | |||
| 174 | + | <description summary="get feedback for a surface"> | |||
| 175 | + | This request creates a new zwp_linux_dmabuf_feedback_v1 object for the | |||
| 176 | + | specified wl_surface. This object will deliver feedback about dmabuf | |||
| 177 | + | parameters to use for buffers attached to this surface. | |||
| 178 | + | ||||
| 179 | + | If the surface is destroyed before the zwp_linux_dmabuf_feedback_v1 object, | |||
| 180 | + | the feedback object becomes inert. | |||
| 181 | + | </description> | |||
| 182 | + | <arg name="id" type="new_id" interface="zwp_linux_dmabuf_feedback_v1"/> | |||
| 183 | + | <arg name="surface" type="object" interface="wl_surface"/> | |||
| 184 | + | </request> | |||
| 185 | + | </interface> | |||
| 186 | + | ||||
| 187 | + | <interface name="zwp_linux_buffer_params_v1" version="6"> | |||
| 188 | + | <description summary="parameters for creating a dmabuf-based wl_buffer"> | |||
| 189 | + | This temporary object is a collection of dmabufs and other | |||
| 190 | + | parameters that together form a single logical buffer. The temporary | |||
| 191 | + | object may eventually create one wl_buffer unless cancelled by | |||
| 192 | + | destroying it before requesting 'create'. | |||
| 193 | + | ||||
| 194 | + | Single-planar formats only require one dmabuf, however | |||
| 195 | + | multi-planar formats may require more than one dmabuf. For all | |||
| 196 | + | formats, an 'add' request must be called once per plane (even if the | |||
| 197 | + | underlying dmabuf fd is identical). | |||
| 198 | + | ||||
| 199 | + | You must use consecutive plane indices ('plane_idx' argument for 'add') | |||
| 200 | + | from zero to the number of planes used by the drm_fourcc format code. | |||
| 201 | + | All planes required by the format must be given exactly once, but can | |||
| 202 | + | be given in any order. Each plane index can only be set once; subsequent | |||
| 203 | + | calls with a plane index which has already been set will result in a | |||
| 204 | + | plane_set error being generated. | |||
| 205 | + | </description> | |||
| 206 | + | ||||
| 207 | + | <enum name="error"> | |||
| 208 | + | <entry name="already_used" value="0" | |||
| 209 | + | summary="the zwp_linux_buffer_params_v1 object has already been used to create a wl_buffer"/> | |||
| 210 | + | <entry name="plane_idx" value="1" | |||
| 211 | + | summary="plane index out of bounds"/> | |||
| 212 | + | <entry name="plane_set" value="2" | |||
| 213 | + | summary="the plane index was already set"/> | |||
| 214 | + | <entry name="incomplete" value="3" | |||
| 215 | + | summary="missing or too many planes to create a buffer"/> | |||
| 216 | + | <entry name="invalid_format" value="4" | |||
| 217 | + | summary="format not supported"/> | |||
| 218 | + | <entry name="invalid_dimensions" value="5" | |||
| 219 | + | summary="invalid width or height"/> | |||
| 220 | + | <entry name="out_of_bounds" value="6" | |||
| 221 | + | summary="offset + stride * height goes out of dmabuf bounds"/> | |||
| 222 | + | <entry name="invalid_wl_buffer" value="7" | |||
| 223 | + | summary="invalid wl_buffer resulted from importing dmabufs via | |||
| 224 | + | the create_immed request on given buffer_params"/> | |||
| 225 | + | <entry name="invalid_dev_t_size" value="8" | |||
| 226 | + | summary="an array with mismatching size for a dev_t was used"/> | |||
| 227 | + | </enum> | |||
| 228 | + | ||||
| 229 | + | <request name="destroy" type="destructor"> | |||
| 230 | + | <description summary="delete this object, used or not"> | |||
| 231 | + | Cleans up the temporary data sent to the server for dmabuf-based | |||
| 232 | + | wl_buffer creation. | |||
| 233 | + | </description> | |||
| 234 | + | </request> | |||
| 235 | + | ||||
| 236 | + | <request name="add"> | |||
| 237 | + | <description summary="add a dmabuf to the temporary set"> | |||
| 238 | + | This request adds one dmabuf to the set in this | |||
| 239 | + | zwp_linux_buffer_params_v1. | |||
| 240 | + | ||||
| 241 | + | The 64-bit unsigned value combined from modifier_hi and modifier_lo | |||
| 242 | + | is the dmabuf layout modifier. DRM AddFB2 ioctl calls this the | |||
| 243 | + | fb modifier, which is defined in drm_mode.h of Linux UAPI. | |||
| 244 | + | This is an opaque token. Drivers use this token to express tiling, | |||
| 245 | + | compression, etc. driver-specific modifications to the base format | |||
| 246 | + | defined by the DRM fourcc code. | |||
| 247 | + | ||||
| 248 | + | Starting from version 4, the invalid_format protocol error is sent if | |||
| 249 | + | the format + modifier pair was not advertised as supported. | |||
| 250 | + | ||||
| 251 | + | Starting from version 5, the invalid_format protocol error is sent if | |||
| 252 | + | all planes don't use the same modifier. | |||
| 253 | + | ||||
| 254 | + | This request raises the PLANE_IDX error if plane_idx is too large. | |||
| 255 | + | The error PLANE_SET is raised if attempting to set a plane that | |||
| 256 | + | was already set. | |||
| 257 | + | </description> | |||
| 258 | + | <arg name="fd" type="fd" summary="dmabuf fd"/> | |||
| 259 | + | <arg name="plane_idx" type="uint" summary="plane index"/> | |||
| 260 | + | <arg name="offset" type="uint" summary="offset in bytes"/> | |||
| 261 | + | <arg name="stride" type="uint" summary="stride in bytes"/> | |||
| 262 | + | <arg name="modifier_hi" type="uint" | |||
| 263 | + | summary="high 32 bits of layout modifier"/> | |||
| 264 | + | <arg name="modifier_lo" type="uint" | |||
| 265 | + | summary="low 32 bits of layout modifier"/> | |||
| 266 | + | </request> | |||
| 267 | + | ||||
| 268 | + | <enum name="flags" bitfield="true"> | |||
| 269 | + | <entry name="y_invert" value="1" summary="contents are y-inverted"/> | |||
| 270 | + | <entry name="interlaced" value="2" summary="content is interlaced"/> | |||
| 271 | + | <entry name="bottom_first" value="4" summary="bottom field first"/> | |||
| 272 | + | </enum> | |||
| 273 | + | ||||
| 274 | + | <request name="create"> | |||
| 275 | + | <description summary="create a wl_buffer from the given dmabufs"> | |||
| 276 | + | This asks for creation of a wl_buffer from the added dmabuf | |||
| 277 | + | buffers. The wl_buffer is not created immediately but returned via | |||
| 278 | + | the 'created' event if the dmabuf sharing succeeds. The sharing | |||
| 279 | + | may fail at runtime for reasons a client cannot predict, in | |||
| 280 | + | which case the 'failed' event is triggered. | |||
| 281 | + | ||||
| 282 | + | The 'format' argument is a DRM_FORMAT code, as defined by the | |||
| 283 | + | libdrm's drm_fourcc.h. The Linux kernel's DRM sub-system is the | |||
| 284 | + | authoritative source on how the format codes should work. | |||
| 285 | + | ||||
| 286 | + | The 'flags' is a bitfield of the flags defined in enum "flags". | |||
| 287 | + | 'y_invert' means that the image needs to be y-flipped. | |||
| 288 | + | ||||
| 289 | + | Flag 'interlaced' means that the frame in the buffer is not | |||
| 290 | + | progressive as usual, but interlaced. An interlaced buffer as | |||
| 291 | + | supported here must always contain both top and bottom fields. | |||
| 292 | + | The top field always begins on the first pixel row. The temporal | |||
| 293 | + | ordering between the two fields is top field first, unless | |||
| 294 | + | 'bottom_first' is specified. It is undefined whether 'bottom_first' | |||
| 295 | + | is ignored if 'interlaced' is not set. | |||
| 296 | + | ||||
| 297 | + | This protocol does not convey any information about field rate, | |||
| 298 | + | duration, or timing, other than the relative ordering between the | |||
| 299 | + | two fields in one buffer. A compositor may have to estimate the | |||
| 300 | + | intended field rate from the incoming buffer rate. It is undefined | |||
| 301 | + | whether the time of receiving wl_surface.commit with a new buffer | |||
| 302 | + | attached, applying the wl_surface state, wl_surface.frame callback | |||
| 303 | + | trigger, presentation, or any other point in the compositor cycle | |||
| 304 | + | is used to measure the frame or field times. There is no support | |||
| 305 | + | for detecting missed or late frames/fields/buffers either, and | |||
| 306 | + | there is no support whatsoever for cooperating with interlaced | |||
| 307 | + | compositor output. | |||
| 308 | + | ||||
| 309 | + | The composited image quality resulting from the use of interlaced | |||
| 310 | + | buffers is explicitly undefined. A compositor may use elaborate | |||
| 311 | + | hardware features or software to deinterlace and create progressive | |||
| 312 | + | output frames from a sequence of interlaced input buffers, or it | |||
| 313 | + | may produce substandard image quality. However, compositors that | |||
| 314 | + | cannot guarantee reasonable image quality in all cases are recommended | |||
| 315 | + | to just reject all interlaced buffers. | |||
| 316 | + | ||||
| 317 | + | Any argument errors, including non-positive width or height, | |||
| 318 | + | mismatch between the number of planes and the format, bad | |||
| 319 | + | format, bad offset or stride, may be indicated by fatal protocol | |||
| 320 | + | errors: INCOMPLETE, INVALID_FORMAT, INVALID_DIMENSIONS, | |||
| 321 | + | OUT_OF_BOUNDS. | |||
| 322 | + | ||||
| 323 | + | Dmabuf import errors in the server that are not obvious client | |||
| 324 | + | bugs are returned via the 'failed' event as non-fatal. This | |||
| 325 | + | allows attempting dmabuf sharing and falling back in the client | |||
| 326 | + | if it fails. | |||
| 327 | + | ||||
| 328 | + | This request can be sent only once in the object's lifetime, after | |||
| 329 | + | which the only legal request is destroy. This object should be | |||
| 330 | + | destroyed after issuing a 'create' request. Attempting to use this | |||
| 331 | + | object after issuing 'create' raises the ALREADY_USED protocol error. | |||
| 332 | + | ||||
| 333 | + | It is not mandatory to issue 'create'. If a client wants to | |||
| 334 | + | cancel the buffer creation, it can just destroy this object. | |||
| 335 | + | </description> | |||
| 336 | + | <arg name="width" type="int" summary="base plane width in pixels"/> | |||
| 337 | + | <arg name="height" type="int" summary="base plane height in pixels"/> | |||
| 338 | + | <arg name="format" type="uint" summary="DRM_FORMAT code"/> | |||
| 339 | + | <arg name="flags" type="uint" enum="flags" summary="see enum flags"/> | |||
| 340 | + | </request> | |||
| 341 | + | ||||
| 342 | + | <event name="created"> | |||
| 343 | + | <description summary="buffer creation succeeded"> | |||
| 344 | + | This event indicates that the attempted buffer creation was | |||
| 345 | + | successful. It provides the new wl_buffer referencing the dmabuf(s). | |||
| 346 | + | ||||
| 347 | + | Upon receiving this event, the client should destroy the | |||
| 348 | + | zwp_linux_buffer_params_v1 object. | |||
| 349 | + | </description> | |||
| 350 | + | <arg name="buffer" type="new_id" interface="wl_buffer" | |||
| 351 | + | summary="id for the the newly created wl_buffer"/> | |||
| 352 | + | </event> | |||
| 353 | + | ||||
| 354 | + | <event name="failed"> | |||
| 355 | + | <description summary="buffer creation failed"> | |||
| 356 | + | This event indicates that the attempted buffer creation has | |||
| 357 | + | failed. It usually means that one of the dmabuf constraints | |||
| 358 | + | has not been fulfilled. | |||
| 359 | + | ||||
| 360 | + | Upon receiving this event, the client should destroy the | |||
| 361 | + | zwp_linux_buffer_params_v1 object. | |||
| 362 | + | </description> | |||
| 363 | + | </event> | |||
| 364 | + | ||||
| 365 | + | <request name="create_immed" since="2"> | |||
| 366 | + | <description summary="immediately create a wl_buffer from the given | |||
| 367 | + | dmabufs"> | |||
| 368 | + | This asks for immediate creation of a wl_buffer by importing the | |||
| 369 | + | added dmabufs. | |||
| 370 | + | ||||
| 371 | + | In case of import success, no event is sent from the server, and the | |||
| 372 | + | wl_buffer is ready to be used by the client. | |||
| 373 | + | ||||
| 374 | + | Upon import failure, either of the following may happen, as seen fit | |||
| 375 | + | by the implementation: | |||
| 376 | + | - the client is terminated with one of the following fatal protocol | |||
| 377 | + | errors: | |||
| 378 | + | - INCOMPLETE, INVALID_FORMAT, INVALID_DIMENSIONS, OUT_OF_BOUNDS, | |||
| 379 | + | in case of argument errors such as mismatch between the number | |||
| 380 | + | of planes and the format, bad format, non-positive width or | |||
| 381 | + | height, or bad offset or stride. | |||
| 382 | + | - INVALID_WL_BUFFER, in case the cause for failure is unknown or | |||
| 383 | + | platform specific. | |||
| 384 | + | - the server creates an invalid wl_buffer, marks it as failed and | |||
| 385 | + | sends a 'failed' event to the client. The result of using this | |||
| 386 | + | invalid wl_buffer as an argument in any request by the client is | |||
| 387 | + | defined by the compositor implementation. | |||
| 388 | + | ||||
| 389 | + | This takes the same arguments as a 'create' request, and obeys the | |||
| 390 | + | same restrictions. | |||
| 391 | + | </description> | |||
| 392 | + | <arg name="buffer_id" type="new_id" interface="wl_buffer" | |||
| 393 | + | summary="id for the newly created wl_buffer"/> | |||
| 394 | + | <arg name="width" type="int" summary="base plane width in pixels"/> | |||
| 395 | + | <arg name="height" type="int" summary="base plane height in pixels"/> | |||
| 396 | + | <arg name="format" type="uint" summary="DRM_FORMAT code"/> | |||
| 397 | + | <arg name="flags" type="uint" enum="flags" summary="see enum flags"/> | |||
| 398 | + | </request> | |||
| 399 | + | ||||
| 400 | + | <request name="set_sampling_device" since="6"> | |||
| 401 | + | <description summary="set the target device of the wl_buffer"> | |||
| 402 | + | Set the device the compositor should import the dmabufs to for sampling | |||
| 403 | + | in the next create or create_immed request. | |||
| 404 | + | ||||
| 405 | + | To avoid race conditions when the compositor removes a device from the | |||
| 406 | + | tranches, it is not a protocol error if the device hasn't been advertised | |||
| 407 | + | by the compositor in a tranche with the sampling flag, but the import is | |||
| 408 | + | likely to fail in that case. | |||
| 409 | + | ||||
| 410 | + | If the client doesn't know a suitable target device, it shouldn't set one, | |||
| 411 | + | and the compositor should attempt import on all devices it supports. | |||
| 412 | + | ||||
| 413 | + | If the array is too small to contain a dev_t or larger than required, the | |||
| 414 | + | invalid_dev_t_size error will be emitted. | |||
| 415 | + | </description> | |||
| 416 | + | <arg name="device" type="array" summary="device dev_t value"/> | |||
| 417 | + | </request> | |||
| 418 | + | </interface> | |||
| 419 | + | ||||
| 420 | + | <interface name="zwp_linux_dmabuf_feedback_v1" version="6"> | |||
| 421 | + | <description summary="dmabuf feedback"> | |||
| 422 | + | This object advertises dmabuf parameters feedback. This includes the | |||
| 423 | + | preferred devices and the supported formats/modifiers. | |||
| 424 | + | ||||
| 425 | + | The parameters are sent once when this object is created and whenever they | |||
| 426 | + | change. The done event is always sent once after all parameters have been | |||
| 427 | + | sent. When a single parameter changes, all parameters are re-sent by the | |||
| 428 | + | compositor. | |||
| 429 | + | ||||
| 430 | + | Compositors can re-send the parameters when the current client buffer | |||
| 431 | + | allocations are sub-optimal. Compositors should not re-send the | |||
| 432 | + | parameters if re-allocating the buffers would not result in a more optimal | |||
| 433 | + | configuration. In particular, compositors should avoid sending the exact | |||
| 434 | + | same parameters multiple times in a row. | |||
| 435 | + | ||||
| 436 | + | The tranche_target_device and tranche_formats events are grouped by | |||
| 437 | + | tranches of preference. For each tranche, a tranche_target_device, one | |||
| 438 | + | tranche_flags and one or more tranche_formats events are sent, followed | |||
| 439 | + | by a tranche_done event finishing the list. The tranches are sent in | |||
| 440 | + | descending order of preference. All formats and modifiers in the same | |||
| 441 | + | tranche have the same preference. | |||
| 442 | + | ||||
| 443 | + | To send parameters, the compositor sends one main_device event (unless | |||
| 444 | + | the client bound version 6 or above), tranches (each consisting of one | |||
| 445 | + | tranche_target_device event, one tranche_flags event, tranche_formats | |||
| 446 | + | events and then a tranche_done event), then one done event. | |||
| 447 | + | ||||
| 448 | + | With version 6 and above, the compositor must always advertise at least | |||
| 449 | + | one tranche with the sampling flag set. | |||
| 450 | + | </description> | |||
| 451 | + | ||||
| 452 | + | <request name="destroy" type="destructor"> | |||
| 453 | + | <description summary="destroy the feedback object"> | |||
| 454 | + | Using this request a client can tell the server that it is not going to | |||
| 455 | + | use the zwp_linux_dmabuf_feedback_v1 object anymore. | |||
| 456 | + | </description> | |||
| 457 | + | </request> | |||
| 458 | + | ||||
| 459 | + | <event name="done"> | |||
| 460 | + | <description summary="all feedback has been sent"> | |||
| 461 | + | This event is sent after all parameters of a zwp_linux_dmabuf_feedback_v1 | |||
| 462 | + | object have been sent. | |||
| 463 | + | ||||
| 464 | + | This allows changes to the zwp_linux_dmabuf_feedback_v1 parameters to be | |||
| 465 | + | seen as atomic, even if they happen via multiple events. | |||
| 466 | + | </description> | |||
| 467 | + | </event> | |||
| 468 | + | ||||
| 469 | + | <event name="format_table"> | |||
| 470 | + | <description summary="format and modifier table"> | |||
| 471 | + | This event provides a file descriptor which can be memory-mapped to | |||
| 472 | + | access the format and modifier table. | |||
| 473 | + | ||||
| 474 | + | The table contains a tightly packed array of consecutive format + | |||
| 475 | + | modifier pairs. Each pair is 16 bytes wide. It contains a format as a | |||
| 476 | + | 32-bit unsigned integer, followed by 4 bytes of unused padding, and a | |||
| 477 | + | modifier as a 64-bit unsigned integer. The native endianness is used. | |||
| 478 | + | ||||
| 479 | + | The client must map the file descriptor in read-only private mode. | |||
| 480 | + | ||||
| 481 | + | Compositors are not allowed to mutate the table file contents once this | |||
| 482 | + | event has been sent. Instead, compositors must create a new, separate | |||
| 483 | + | table file and re-send feedback parameters. Compositors are allowed to | |||
| 484 | + | store duplicate format + modifier pairs in the table. | |||
| 485 | + | </description> | |||
| 486 | + | <arg name="fd" type="fd" summary="table file descriptor"/> | |||
| 487 | + | <arg name="size" type="uint" summary="table size, in bytes"/> | |||
| 488 | + | </event> | |||
| 489 | + | ||||
| 490 | + | <event name="main_device" deprecated-since="6"> | |||
| 491 | + | <description summary="preferred main device"> | |||
| 492 | + | This event advertises the main device that the server prefers to use | |||
| 493 | + | when direct scan-out to the target device isn't possible. The | |||
| 494 | + | advertised main device may be different for each | |||
| 495 | + | zwp_linux_dmabuf_feedback_v1 object, and may change over time. | |||
| 496 | + | ||||
| 497 | + | There is exactly one main device. The compositor must send at least | |||
| 498 | + | one preference tranche with tranche_target_device equal to main_device. | |||
| 499 | + | ||||
| 500 | + | Clients need to create buffers that the main device can import and | |||
| 501 | + | read from, otherwise creating the dmabuf wl_buffer will fail (see the | |||
| 502 | + | zwp_linux_buffer_params_v1.create and create_immed requests for details). | |||
| 503 | + | The main device will also likely be kept active by the compositor, | |||
| 504 | + | so clients can use it instead of waking up another device for power | |||
| 505 | + | savings. | |||
| 506 | + | ||||
| 507 | + | In general the device is a DRM node. The DRM node type (primary vs. | |||
| 508 | + | render) is unspecified. Clients must not rely on the compositor sending | |||
| 509 | + | a particular node type. Clients cannot check two devices for equality | |||
| 510 | + | by comparing the dev_t value. | |||
| 511 | + | ||||
| 512 | + | If explicit modifiers are not supported and the client performs buffer | |||
| 513 | + | allocations on a different device than the main device, then the client | |||
| 514 | + | must force the buffer to have a linear layout. | |||
| 515 | + | ||||
| 516 | + | With version 6 and above, this event is no longer sent. Clients should | |||
| 517 | + | use a device with the sampling flag in the tranches instead. | |||
| 518 | + | </description> | |||
| 519 | + | <arg name="device" type="array" summary="device dev_t value"/> | |||
| 520 | + | </event> | |||
| 521 | + | ||||
| 522 | + | <event name="tranche_done"> | |||
| 523 | + | <description summary="a preference tranche has been sent"> | |||
| 524 | + | This event splits tranche_target_device and tranche_formats events into | |||
| 525 | + | preference tranches. It is sent after a set of tranche_target_device | |||
| 526 | + | and tranche_formats events; it represents the end of a tranche. The | |||
| 527 | + | next tranche will have a lower preference. | |||
| 528 | + | </description> | |||
| 529 | + | </event> | |||
| 530 | + | ||||
| 531 | + | <event name="tranche_target_device"> | |||
| 532 | + | <description summary="target device"> | |||
| 533 | + | This event advertises the target device that the server prefers to use | |||
| 534 | + | for a buffer created given this tranche. The advertised target device | |||
| 535 | + | may be different for each preference tranche, and may change over time. | |||
| 536 | + | ||||
| 537 | + | There is exactly one target device per tranche. | |||
| 538 | + | ||||
| 539 | + | The target device may be a scan-out device, for example if the | |||
| 540 | + | compositor prefers to directly scan-out a buffer created given this | |||
| 541 | + | tranche. The target device may be a rendering device, for example if | |||
| 542 | + | the compositor prefers to texture from said buffer. | |||
| 543 | + | ||||
| 544 | + | The client can use this hint to allocate the buffer in a way that makes | |||
| 545 | + | it accessible from the target device, ideally directly. The buffer must | |||
| 546 | + | still be accessible from a device with the sampling flag, either through | |||
| 547 | + | direct import or a potentially more expensive fallback path. If the | |||
| 548 | + | buffer can't be directly imported for sampling, then clients must be | |||
| 549 | + | prepared for the compositor changing the tranche priority or making | |||
| 550 | + | wl_buffer creation fail (see the zwp_linux_buffer_params_v1.create and | |||
| 551 | + | create_immed requests for details). | |||
| 552 | + | ||||
| 553 | + | If the device is a DRM node, the DRM node type (primary vs. render) is | |||
| 554 | + | unspecified. Clients must not rely on the compositor sending a | |||
| 555 | + | particular node type. Clients cannot check two devices for equality by | |||
| 556 | + | comparing the dev_t value. | |||
| 557 | + | ||||
| 558 | + | This event is tied to a preference tranche, see the tranche_done event. | |||
| 559 | + | </description> | |||
| 560 | + | <arg name="device" type="array" summary="device dev_t value"/> | |||
| 561 | + | </event> | |||
| 562 | + | ||||
| 563 | + | <event name="tranche_formats"> | |||
| 564 | + | <description summary="supported buffer format modifiers"> | |||
| 565 | + | This event advertises the format + modifier combinations that the | |||
| 566 | + | compositor supports. | |||
| 567 | + | ||||
| 568 | + | It carries an array of indices, each referring to a format + modifier | |||
| 569 | + | pair in the last received format table (see the format_table event). | |||
| 570 | + | Each index is a 16-bit unsigned integer in native endianness. | |||
| 571 | + | ||||
| 572 | + | For legacy support, DRM_FORMAT_MOD_INVALID is an allowed modifier. | |||
| 573 | + | It indicates that the server can support the format with an implicit | |||
| 574 | + | modifier. When a buffer has DRM_FORMAT_MOD_INVALID as its modifier, it | |||
| 575 | + | is as if no explicit modifier is specified. The effective modifier | |||
| 576 | + | will be derived from the dmabuf. | |||
| 577 | + | ||||
| 578 | + | A compositor that sends valid modifiers and DRM_FORMAT_MOD_INVALID for | |||
| 579 | + | a given format supports both explicit modifiers and implicit modifiers. | |||
| 580 | + | ||||
| 581 | + | Compositors must not send duplicate format + modifier pairs within the | |||
| 582 | + | same tranche or across two different tranches with the same target | |||
| 583 | + | device and flags. | |||
| 584 | + | ||||
| 585 | + | This event is tied to a preference tranche, see the tranche_done event. | |||
| 586 | + | ||||
| 587 | + | For the definition of the format and modifier codes, see the | |||
| 588 | + | zwp_linux_buffer_params_v1.create request. | |||
| 589 | + | </description> | |||
| 590 | + | <arg name="indices" type="array" summary="array of 16-bit indexes"/> | |||
| 591 | + | </event> | |||
| 592 | + | ||||
| 593 | + | <enum name="tranche_flags" bitfield="true"> | |||
| 594 | + | <entry name="scanout" value="1" since="4"> | |||
| 595 | + | <description summary="direct scan-out tranche"> | |||
| 596 | + | The scanout flag is a hint that direct scan-out may be attempted by | |||
| 597 | + | the compositor on the target device if the client appropriately | |||
| 598 | + | allocates a buffer. How to allocate a buffer that can be scanned out | |||
| 599 | + | on the target device is implementation-defined. | |||
| 600 | + | </description> | |||
| 601 | + | </entry> | |||
| 602 | + | <entry name="sampling" value="2" since="6"> | |||
| 603 | + | <description summary="sampling tranche"> | |||
| 604 | + | The sampling flag describes that the compositor is able to efficiently | |||
| 605 | + | sample from buffers imported to the target device if the client | |||
| 606 | + | appropriately allocates a buffer. How to allocate a buffer that can be | |||
| 607 | + | efficiently sampled on the target device is implementation defined. | |||
| 608 | + | </description> | |||
| 609 | + | </entry> | |||
| 610 | + | </enum> | |||
| 611 | + | ||||
| 612 | + | <event name="tranche_flags"> | |||
| 613 | + | <description summary="tranche flags"> | |||
| 614 | + | This event sets tranche-specific flags. This event is tied to a | |||
| 615 | + | preference tranche, see the tranche_done event. | |||
| 616 | + | With version 6 and above, the compositor must set at least one flag | |||
| 617 | + | in each tranche. | |||
| 618 | + | </description> | |||
| 619 | + | <arg name="flags" type="uint" enum="tranche_flags" summary="tranche flags"/> | |||
| 620 | + | </event> | |||
| 621 | + | </interface> | |||
| 622 | + | ||||
| 623 | + | </protocol> | |||
A spec/xml/linuxdrmsyncobj.xml +261 -0
| @@ -0,0 +1,261 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="linux_drm_syncobj_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright 2016 The Chromium Authors. | |||
| 5 | + | Copyright 2017 Intel Corporation | |||
| 6 | + | Copyright 2018 Collabora, Ltd | |||
| 7 | + | Copyright 2021 Simon Ser | |||
| 8 | + | ||||
| 9 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 10 | + | copy of this software and associated documentation files (the "Software"), | |||
| 11 | + | to deal in the Software without restriction, including without limitation | |||
| 12 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 13 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 14 | + | Software is furnished to do so, subject to the following conditions: | |||
| 15 | + | ||||
| 16 | + | The above copyright notice and this permission notice (including the next | |||
| 17 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 18 | + | Software. | |||
| 19 | + | ||||
| 20 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 21 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 22 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 23 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 24 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 25 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 26 | + | DEALINGS IN THE SOFTWARE. | |||
| 27 | + | </copyright> | |||
| 28 | + | ||||
| 29 | + | <description summary="protocol for providing explicit synchronization"> | |||
| 30 | + | This protocol allows clients to request explicit synchronization for | |||
| 31 | + | buffers. It is tied to the Linux DRM synchronization object framework. | |||
| 32 | + | ||||
| 33 | + | Synchronization refers to co-ordination of pipelined operations performed | |||
| 34 | + | on buffers. Most GPU clients will schedule an asynchronous operation to | |||
| 35 | + | render to the buffer, then immediately send the buffer to the compositor | |||
| 36 | + | to be attached to a surface. | |||
| 37 | + | ||||
| 38 | + | With implicit synchronization, ensuring that the rendering operation is | |||
| 39 | + | complete before the compositor displays the buffer is an implementation | |||
| 40 | + | detail handled by either the kernel or userspace graphics driver. | |||
| 41 | + | ||||
| 42 | + | By contrast, with explicit synchronization, DRM synchronization object | |||
| 43 | + | timeline points mark when the asynchronous operations are complete. When | |||
| 44 | + | submitting a buffer, the client provides a timeline point which will be | |||
| 45 | + | waited on before the compositor accesses the buffer, and another timeline | |||
| 46 | + | point that the compositor will signal when it no longer needs to access the | |||
| 47 | + | buffer contents for the purposes of the surface commit. | |||
| 48 | + | ||||
| 49 | + | Linux DRM synchronization objects are documented at: | |||
| 50 | + | https://dri.freedesktop.org/docs/drm/gpu/drm-mm.html#drm-sync-objects | |||
| 51 | + | ||||
| 52 | + | Warning! The protocol described in this file is currently in the testing | |||
| 53 | + | phase. Backward compatible changes may be added together with the | |||
| 54 | + | corresponding interface version bump. Backward incompatible changes can | |||
| 55 | + | only be done by creating a new major version of the extension. | |||
| 56 | + | </description> | |||
| 57 | + | ||||
| 58 | + | <interface name="wp_linux_drm_syncobj_manager_v1" version="1"> | |||
| 59 | + | <description summary="global for providing explicit synchronization"> | |||
| 60 | + | This global is a factory interface, allowing clients to request | |||
| 61 | + | explicit synchronization for buffers on a per-surface basis. | |||
| 62 | + | ||||
| 63 | + | See wp_linux_drm_syncobj_surface_v1 for more information. | |||
| 64 | + | </description> | |||
| 65 | + | ||||
| 66 | + | <request name="destroy" type="destructor"> | |||
| 67 | + | <description summary="destroy explicit synchronization factory object"> | |||
| 68 | + | Destroy this explicit synchronization factory object. Other objects | |||
| 69 | + | shall not be affected by this request. | |||
| 70 | + | </description> | |||
| 71 | + | </request> | |||
| 72 | + | ||||
| 73 | + | <enum name="error"> | |||
| 74 | + | <entry name="surface_exists" value="0" | |||
| 75 | + | summary="the surface already has a synchronization object associated"/> | |||
| 76 | + | <entry name="invalid_timeline" value="1" | |||
| 77 | + | summary="the timeline object could not be imported"/> | |||
| 78 | + | </enum> | |||
| 79 | + | ||||
| 80 | + | <request name="get_surface"> | |||
| 81 | + | <description summary="extend surface interface for explicit synchronization"> | |||
| 82 | + | Instantiate an interface extension for the given wl_surface to provide | |||
| 83 | + | explicit synchronization. | |||
| 84 | + | ||||
| 85 | + | If the given wl_surface already has an explicit synchronization object | |||
| 86 | + | associated, the surface_exists protocol error is raised. | |||
| 87 | + | ||||
| 88 | + | Graphics APIs, like EGL or Vulkan, that manage the buffer queue and | |||
| 89 | + | commits of a wl_surface themselves, are likely to be using this | |||
| 90 | + | extension internally. If a client is using such an API for a | |||
| 91 | + | wl_surface, it should not directly use this extension on that surface, | |||
| 92 | + | to avoid raising a surface_exists protocol error. | |||
| 93 | + | </description> | |||
| 94 | + | <arg name="id" type="new_id" interface="wp_linux_drm_syncobj_surface_v1" | |||
| 95 | + | summary="the new synchronization surface object id"/> | |||
| 96 | + | <arg name="surface" type="object" interface="wl_surface" | |||
| 97 | + | summary="the surface"/> | |||
| 98 | + | </request> | |||
| 99 | + | ||||
| 100 | + | <request name="import_timeline"> | |||
| 101 | + | <description summary="import a DRM syncobj timeline"> | |||
| 102 | + | Import a DRM synchronization object timeline. | |||
| 103 | + | ||||
| 104 | + | If the FD cannot be imported, the invalid_timeline error is raised. | |||
| 105 | + | </description> | |||
| 106 | + | <arg name="id" type="new_id" interface="wp_linux_drm_syncobj_timeline_v1"/> | |||
| 107 | + | <arg name="fd" type="fd" summary="drm_syncobj file descriptor"/> | |||
| 108 | + | </request> | |||
| 109 | + | </interface> | |||
| 110 | + | ||||
| 111 | + | <interface name="wp_linux_drm_syncobj_timeline_v1" version="1"> | |||
| 112 | + | <description summary="synchronization object timeline"> | |||
| 113 | + | This object represents an explicit synchronization object timeline | |||
| 114 | + | imported by the client to the compositor. | |||
| 115 | + | </description> | |||
| 116 | + | ||||
| 117 | + | <request name="destroy" type="destructor"> | |||
| 118 | + | <description summary="destroy the timeline"> | |||
| 119 | + | Destroy the synchronization object timeline. Other objects are not | |||
| 120 | + | affected by this request, in particular timeline points set by | |||
| 121 | + | set_acquire_point and set_release_point are not unset. | |||
| 122 | + | </description> | |||
| 123 | + | </request> | |||
| 124 | + | </interface> | |||
| 125 | + | ||||
| 126 | + | <interface name="wp_linux_drm_syncobj_surface_v1" version="1"> | |||
| 127 | + | <description summary="per-surface explicit synchronization"> | |||
| 128 | + | This object is an add-on interface for wl_surface to enable explicit | |||
| 129 | + | synchronization. | |||
| 130 | + | ||||
| 131 | + | Each surface can be associated with only one object of this interface at | |||
| 132 | + | any time. | |||
| 133 | + | ||||
| 134 | + | Explicit synchronization is guaranteed to be supported for buffers | |||
| 135 | + | created with any version of the linux-dmabuf protocol. Compositors are | |||
| 136 | + | free to support explicit synchronization for additional buffer types. | |||
| 137 | + | If at surface commit time the attached buffer does not support explicit | |||
| 138 | + | synchronization, an unsupported_buffer error is raised. | |||
| 139 | + | ||||
| 140 | + | As long as the wp_linux_drm_syncobj_surface_v1 object is alive, the | |||
| 141 | + | compositor may ignore implicit synchronization for buffers attached and | |||
| 142 | + | committed to the wl_surface. The delivery of wl_buffer.release events | |||
| 143 | + | for buffers attached to the surface becomes undefined. | |||
| 144 | + | ||||
| 145 | + | Clients must set both acquire and release points if and only if a | |||
| 146 | + | non-null buffer is attached in the same surface commit. See the | |||
| 147 | + | no_buffer, no_acquire_point and no_release_point protocol errors. | |||
| 148 | + | ||||
| 149 | + | If at surface commit time the acquire and release DRM syncobj timelines | |||
| 150 | + | are identical, the acquire point value must be strictly less than the | |||
| 151 | + | release point value, or else the conflicting_points protocol error is | |||
| 152 | + | raised. | |||
| 153 | + | </description> | |||
| 154 | + | ||||
| 155 | + | <request name="destroy" type="destructor"> | |||
| 156 | + | <description summary="destroy the surface synchronization object"> | |||
| 157 | + | Destroy this surface synchronization object. | |||
| 158 | + | ||||
| 159 | + | Any timeline point set by this object with set_acquire_point or | |||
| 160 | + | set_release_point since the last commit may be discarded by the | |||
| 161 | + | compositor. Any timeline point set by this object before the last | |||
| 162 | + | commit will not be affected. | |||
| 163 | + | </description> | |||
| 164 | + | </request> | |||
| 165 | + | ||||
| 166 | + | <enum name="error"> | |||
| 167 | + | <entry name="no_surface" value="1" | |||
| 168 | + | summary="the associated wl_surface was destroyed"/> | |||
| 169 | + | <entry name="unsupported_buffer" value="2" | |||
| 170 | + | summary="the buffer does not support explicit synchronization"/> | |||
| 171 | + | <entry name="no_buffer" value="3" summary="no buffer was attached"/> | |||
| 172 | + | <entry name="no_acquire_point" value="4" | |||
| 173 | + | summary="no acquire timeline point was set"/> | |||
| 174 | + | <entry name="no_release_point" value="5" | |||
| 175 | + | summary="no release timeline point was set"/> | |||
| 176 | + | <entry name="conflicting_points" value="6" | |||
| 177 | + | summary="acquire and release timeline points are in conflict"/> | |||
| 178 | + | </enum> | |||
| 179 | + | ||||
| 180 | + | <request name="set_acquire_point"> | |||
| 181 | + | <description summary="set the acquire timeline point"> | |||
| 182 | + | Set the timeline point that must be signalled before the compositor may | |||
| 183 | + | sample from the buffer attached with wl_surface.attach. | |||
| 184 | + | ||||
| 185 | + | The 64-bit unsigned value combined from point_hi and point_lo is the | |||
| 186 | + | point value. | |||
| 187 | + | ||||
| 188 | + | The acquire point is double-buffered state, and will be applied on the | |||
| 189 | + | next wl_surface.commit request for the associated surface. Thus, it | |||
| 190 | + | applies only to the buffer that is attached to the surface at commit | |||
| 191 | + | time. | |||
| 192 | + | ||||
| 193 | + | If an acquire point has already been attached during the same commit | |||
| 194 | + | cycle, the new point replaces the old one. | |||
| 195 | + | ||||
| 196 | + | If the associated wl_surface was destroyed, a no_surface error is | |||
| 197 | + | raised. | |||
| 198 | + | ||||
| 199 | + | If at surface commit time there is a pending acquire timeline point set | |||
| 200 | + | but no pending buffer attached, a no_buffer error is raised. If at | |||
| 201 | + | surface commit time there is a pending buffer attached but no pending | |||
| 202 | + | acquire timeline point set, the no_acquire_point protocol error is | |||
| 203 | + | raised. | |||
| 204 | + | </description> | |||
| 205 | + | <arg name="timeline" type="object" interface="wp_linux_drm_syncobj_timeline_v1"/> | |||
| 206 | + | <arg name="point_hi" type="uint" summary="high 32 bits of the point value"/> | |||
| 207 | + | <arg name="point_lo" type="uint" summary="low 32 bits of the point value"/> | |||
| 208 | + | </request> | |||
| 209 | + | ||||
| 210 | + | <request name="set_release_point"> | |||
| 211 | + | <description summary="set the release timeline point"> | |||
| 212 | + | Set the timeline point that must be signalled by the compositor when it | |||
| 213 | + | has finished its usage of the buffer attached with wl_surface.attach | |||
| 214 | + | for the relevant commit. | |||
| 215 | + | ||||
| 216 | + | Once the timeline point is signaled, and assuming the associated buffer | |||
| 217 | + | is not pending release from other wl_surface.commit requests, no | |||
| 218 | + | additional explicit or implicit synchronization with the compositor is | |||
| 219 | + | required to safely re-use the buffer. | |||
| 220 | + | ||||
| 221 | + | Note that clients cannot rely on the release point being always | |||
| 222 | + | signaled after the acquire point: compositors may release buffers | |||
| 223 | + | without ever reading from them. In addition, the compositor may use | |||
| 224 | + | different presentation paths for different commits, which may have | |||
| 225 | + | different release behavior. As a result, the compositor may signal the | |||
| 226 | + | release points in a different order than the client committed them. | |||
| 227 | + | ||||
| 228 | + | Because signaling a timeline point also signals every previous point, | |||
| 229 | + | it is generally not safe to use the same timeline object for the | |||
| 230 | + | release points of multiple buffers. The out-of-order signaling | |||
| 231 | + | described above may lead to a release point being signaled before the | |||
| 232 | + | compositor has finished reading. To avoid this, it is strongly | |||
| 233 | + | recommended that each buffer should use a separate timeline for its | |||
| 234 | + | release points. | |||
| 235 | + | ||||
| 236 | + | The 64-bit unsigned value combined from point_hi and point_lo is the | |||
| 237 | + | point value. | |||
| 238 | + | ||||
| 239 | + | The release point is double-buffered state, and will be applied on the | |||
| 240 | + | next wl_surface.commit request for the associated surface. Thus, it | |||
| 241 | + | applies only to the buffer that is attached to the surface at commit | |||
| 242 | + | time. | |||
| 243 | + | ||||
| 244 | + | If a release point has already been attached during the same commit | |||
| 245 | + | cycle, the new point replaces the old one. | |||
| 246 | + | ||||
| 247 | + | If the associated wl_surface was destroyed, a no_surface error is | |||
| 248 | + | raised. | |||
| 249 | + | ||||
| 250 | + | If at surface commit time there is a pending release timeline point set | |||
| 251 | + | but no pending buffer attached, a no_buffer error is raised. If at | |||
| 252 | + | surface commit time there is a pending buffer attached but no pending | |||
| 253 | + | release timeline point set, the no_release_point protocol error is | |||
| 254 | + | raised. | |||
| 255 | + | </description> | |||
| 256 | + | <arg name="timeline" type="object" interface="wp_linux_drm_syncobj_timeline_v1"/> | |||
| 257 | + | <arg name="point_hi" type="uint" summary="high 32 bits of the point value"/> | |||
| 258 | + | <arg name="point_lo" type="uint" summary="low 32 bits of the point value"/> | |||
| 259 | + | </request> | |||
| 260 | + | </interface> | |||
| 261 | + | </protocol> | |||
A spec/xml/linuxexplicitsynchronization.xml +258 -0
| @@ -0,0 +1,258 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="zwp_linux_explicit_synchronization_unstable_v1"> | |||
| 3 | + | ||||
| 4 | + | <copyright> | |||
| 5 | + | Copyright 2016 The Chromium Authors. | |||
| 6 | + | Copyright 2017 Intel Corporation | |||
| 7 | + | Copyright 2018 Collabora, Ltd | |||
| 8 | + | ||||
| 9 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 10 | + | copy of this software and associated documentation files (the "Software"), | |||
| 11 | + | to deal in the Software without restriction, including without limitation | |||
| 12 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 13 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 14 | + | Software is furnished to do so, subject to the following conditions: | |||
| 15 | + | ||||
| 16 | + | The above copyright notice and this permission notice (including the next | |||
| 17 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 18 | + | Software. | |||
| 19 | + | ||||
| 20 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 21 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 22 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 23 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 24 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 25 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 26 | + | DEALINGS IN THE SOFTWARE. | |||
| 27 | + | </copyright> | |||
| 28 | + | ||||
| 29 | + | <interface name="zwp_linux_explicit_synchronization_v1" version="2"> | |||
| 30 | + | <description summary="protocol for providing explicit synchronization"> | |||
| 31 | + | This global is a factory interface, allowing clients to request | |||
| 32 | + | explicit synchronization for buffers on a per-surface basis. | |||
| 33 | + | ||||
| 34 | + | See zwp_linux_surface_synchronization_v1 for more information. | |||
| 35 | + | ||||
| 36 | + | This interface is derived from Chromium's | |||
| 37 | + | zcr_linux_explicit_synchronization_v1. | |||
| 38 | + | ||||
| 39 | + | Note: this protocol is superseded by linux-drm-syncobj. | |||
| 40 | + | ||||
| 41 | + | Warning! The protocol described in this file is experimental and | |||
| 42 | + | backward incompatible changes may be made. Backward compatible changes | |||
| 43 | + | may be added together with the corresponding interface version bump. | |||
| 44 | + | Backward incompatible changes are done by bumping the version number in | |||
| 45 | + | the protocol and interface names and resetting the interface version. | |||
| 46 | + | Once the protocol is to be declared stable, the 'z' prefix and the | |||
| 47 | + | version number in the protocol and interface names are removed and the | |||
| 48 | + | interface version number is reset. | |||
| 49 | + | </description> | |||
| 50 | + | ||||
| 51 | + | <request name="destroy" type="destructor"> | |||
| 52 | + | <description summary="destroy explicit synchronization factory object"> | |||
| 53 | + | Destroy this explicit synchronization factory object. Other objects, | |||
| 54 | + | including zwp_linux_surface_synchronization_v1 objects created by this | |||
| 55 | + | factory, shall not be affected by this request. | |||
| 56 | + | </description> | |||
| 57 | + | </request> | |||
| 58 | + | ||||
| 59 | + | <enum name="error"> | |||
| 60 | + | <entry name="synchronization_exists" value="0" | |||
| 61 | + | summary="the surface already has a synchronization object associated"/> | |||
| 62 | + | </enum> | |||
| 63 | + | ||||
| 64 | + | <request name="get_synchronization"> | |||
| 65 | + | <description summary="extend surface interface for explicit synchronization"> | |||
| 66 | + | Instantiate an interface extension for the given wl_surface to provide | |||
| 67 | + | explicit synchronization. | |||
| 68 | + | ||||
| 69 | + | If the given wl_surface already has an explicit synchronization object | |||
| 70 | + | associated, the synchronization_exists protocol error is raised. | |||
| 71 | + | ||||
| 72 | + | Graphics APIs, like EGL or Vulkan, that manage the buffer queue and | |||
| 73 | + | commits of a wl_surface themselves, are likely to be using this | |||
| 74 | + | extension internally. If a client is using such an API for a | |||
| 75 | + | wl_surface, it should not directly use this extension on that surface, | |||
| 76 | + | to avoid raising a synchronization_exists protocol error. | |||
| 77 | + | </description> | |||
| 78 | + | ||||
| 79 | + | <arg name="id" type="new_id" | |||
| 80 | + | interface="zwp_linux_surface_synchronization_v1" | |||
| 81 | + | summary="the new synchronization interface id"/> | |||
| 82 | + | <arg name="surface" type="object" interface="wl_surface" | |||
| 83 | + | summary="the surface"/> | |||
| 84 | + | </request> | |||
| 85 | + | </interface> | |||
| 86 | + | ||||
| 87 | + | <interface name="zwp_linux_surface_synchronization_v1" version="2"> | |||
| 88 | + | <description summary="per-surface explicit synchronization support"> | |||
| 89 | + | This object implements per-surface explicit synchronization. | |||
| 90 | + | ||||
| 91 | + | Synchronization refers to co-ordination of pipelined operations performed | |||
| 92 | + | on buffers. Most GPU clients will schedule an asynchronous operation to | |||
| 93 | + | render to the buffer, then immediately send the buffer to the compositor | |||
| 94 | + | to be attached to a surface. | |||
| 95 | + | ||||
| 96 | + | In implicit synchronization, ensuring that the rendering operation is | |||
| 97 | + | complete before the compositor displays the buffer is an implementation | |||
| 98 | + | detail handled by either the kernel or userspace graphics driver. | |||
| 99 | + | ||||
| 100 | + | By contrast, in explicit synchronization, dma_fence objects mark when the | |||
| 101 | + | asynchronous operations are complete. When submitting a buffer, the | |||
| 102 | + | client provides an acquire fence which will be waited on before the | |||
| 103 | + | compositor accesses the buffer. The Wayland server, through a | |||
| 104 | + | zwp_linux_buffer_release_v1 object, will inform the client with an event | |||
| 105 | + | which may be accompanied by a release fence, when the compositor will no | |||
| 106 | + | longer access the buffer contents due to the specific commit that | |||
| 107 | + | requested the release event. | |||
| 108 | + | ||||
| 109 | + | Each surface can be associated with only one object of this interface at | |||
| 110 | + | any time. | |||
| 111 | + | ||||
| 112 | + | In version 1 of this interface, explicit synchronization is only | |||
| 113 | + | guaranteed to be supported for buffers created with any version of the | |||
| 114 | + | wp_linux_dmabuf buffer factory. Version 2 additionally guarantees | |||
| 115 | + | explicit synchronization support for opaque EGL buffers, which is a type | |||
| 116 | + | of platform specific buffers described in the EGL_WL_bind_wayland_display | |||
| 117 | + | extension. Compositors are free to support explicit synchronization for | |||
| 118 | + | additional buffer types. | |||
| 119 | + | </description> | |||
| 120 | + | ||||
| 121 | + | <request name="destroy" type="destructor"> | |||
| 122 | + | <description summary="destroy synchronization object"> | |||
| 123 | + | Destroy this explicit synchronization object. | |||
| 124 | + | ||||
| 125 | + | Any fence set by this object with set_acquire_fence since the last | |||
| 126 | + | commit will be discarded by the server. Any fences set by this object | |||
| 127 | + | before the last commit are not affected. | |||
| 128 | + | ||||
| 129 | + | zwp_linux_buffer_release_v1 objects created by this object are not | |||
| 130 | + | affected by this request. | |||
| 131 | + | </description> | |||
| 132 | + | </request> | |||
| 133 | + | ||||
| 134 | + | <enum name="error"> | |||
| 135 | + | <entry name="invalid_fence" value="0" | |||
| 136 | + | summary="the fence specified by the client could not be imported"/> | |||
| 137 | + | <entry name="duplicate_fence" value="1" | |||
| 138 | + | summary="multiple fences added for a single surface commit"/> | |||
| 139 | + | <entry name="duplicate_release" value="2" | |||
| 140 | + | summary="multiple releases added for a single surface commit"/> | |||
| 141 | + | <entry name="no_surface" value="3" | |||
| 142 | + | summary="the associated wl_surface was destroyed"/> | |||
| 143 | + | <entry name="unsupported_buffer" value="4" | |||
| 144 | + | summary="the buffer does not support explicit synchronization"/> | |||
| 145 | + | <entry name="no_buffer" value="5" | |||
| 146 | + | summary="no buffer was attached"/> | |||
| 147 | + | </enum> | |||
| 148 | + | ||||
| 149 | + | <request name="set_acquire_fence"> | |||
| 150 | + | <description summary="set the acquire fence"> | |||
| 151 | + | Set the acquire fence that must be signaled before the compositor | |||
| 152 | + | may sample from the buffer attached with wl_surface.attach. The fence | |||
| 153 | + | is a dma_fence kernel object. | |||
| 154 | + | ||||
| 155 | + | The acquire fence is double-buffered state, and will be applied on the | |||
| 156 | + | next wl_surface.commit request for the associated surface. Thus, it | |||
| 157 | + | applies only to the buffer that is attached to the surface at commit | |||
| 158 | + | time. | |||
| 159 | + | ||||
| 160 | + | If the provided fd is not a valid dma_fence fd, then an INVALID_FENCE | |||
| 161 | + | error is raised. | |||
| 162 | + | ||||
| 163 | + | If a fence has already been attached during the same commit cycle, a | |||
| 164 | + | DUPLICATE_FENCE error is raised. | |||
| 165 | + | ||||
| 166 | + | If the associated wl_surface was destroyed, a NO_SURFACE error is | |||
| 167 | + | raised. | |||
| 168 | + | ||||
| 169 | + | If at surface commit time the attached buffer does not support explicit | |||
| 170 | + | synchronization, an UNSUPPORTED_BUFFER error is raised. | |||
| 171 | + | ||||
| 172 | + | If at surface commit time there is no buffer attached, a NO_BUFFER | |||
| 173 | + | error is raised. | |||
| 174 | + | </description> | |||
| 175 | + | <arg name="fd" type="fd" summary="acquire fence fd"/> | |||
| 176 | + | </request> | |||
| 177 | + | ||||
| 178 | + | <request name="get_release"> | |||
| 179 | + | <description summary="release fence for last-attached buffer"> | |||
| 180 | + | Create a listener for the release of the buffer attached by the | |||
| 181 | + | client with wl_surface.attach. See zwp_linux_buffer_release_v1 | |||
| 182 | + | documentation for more information. | |||
| 183 | + | ||||
| 184 | + | The release object is double-buffered state, and will be associated | |||
| 185 | + | with the buffer that is attached to the surface at wl_surface.commit | |||
| 186 | + | time. | |||
| 187 | + | ||||
| 188 | + | If a zwp_linux_buffer_release_v1 object has already been requested for | |||
| 189 | + | the surface in the same commit cycle, a DUPLICATE_RELEASE error is | |||
| 190 | + | raised. | |||
| 191 | + | ||||
| 192 | + | If the associated wl_surface was destroyed, a NO_SURFACE error | |||
| 193 | + | is raised. | |||
| 194 | + | ||||
| 195 | + | If at surface commit time there is no buffer attached, a NO_BUFFER | |||
| 196 | + | error is raised. | |||
| 197 | + | </description> | |||
| 198 | + | <arg name="release" type="new_id" interface="zwp_linux_buffer_release_v1" | |||
| 199 | + | summary="new zwp_linux_buffer_release_v1 object"/> | |||
| 200 | + | </request> | |||
| 201 | + | </interface> | |||
| 202 | + | ||||
| 203 | + | <interface name="zwp_linux_buffer_release_v1" version="1"> | |||
| 204 | + | <description summary="buffer release explicit synchronization"> | |||
| 205 | + | This object is instantiated in response to a | |||
| 206 | + | zwp_linux_surface_synchronization_v1.get_release request. | |||
| 207 | + | ||||
| 208 | + | It provides an alternative to wl_buffer.release events, providing a | |||
| 209 | + | unique release from a single wl_surface.commit request. The release event | |||
| 210 | + | also supports explicit synchronization, providing a fence FD for the | |||
| 211 | + | client to synchronize against. | |||
| 212 | + | ||||
| 213 | + | Exactly one event, either a fenced_release or an immediate_release, will | |||
| 214 | + | be emitted for the wl_surface.commit request. The compositor can choose | |||
| 215 | + | release by release which event it uses. | |||
| 216 | + | ||||
| 217 | + | This event does not replace wl_buffer.release events; servers are still | |||
| 218 | + | required to send those events. | |||
| 219 | + | ||||
| 220 | + | Once a buffer release object has delivered a 'fenced_release' or an | |||
| 221 | + | 'immediate_release' event it is automatically destroyed. | |||
| 222 | + | </description> | |||
| 223 | + | ||||
| 224 | + | <event name="fenced_release" type="destructor"> | |||
| 225 | + | <description summary="release buffer with fence"> | |||
| 226 | + | Sent when the compositor has finalised its usage of the associated | |||
| 227 | + | buffer for the relevant commit, providing a dma_fence which will be | |||
| 228 | + | signaled when all operations by the compositor on that buffer for that | |||
| 229 | + | commit have finished. | |||
| 230 | + | ||||
| 231 | + | Once the fence has signaled, and assuming the associated buffer is not | |||
| 232 | + | pending release from other wl_surface.commit requests, no additional | |||
| 233 | + | explicit or implicit synchronization is required to safely reuse or | |||
| 234 | + | destroy the buffer. | |||
| 235 | + | ||||
| 236 | + | This event destroys the zwp_linux_buffer_release_v1 object. | |||
| 237 | + | </description> | |||
| 238 | + | <arg name="fence" type="fd" summary="fence for last operation on buffer"/> | |||
| 239 | + | </event> | |||
| 240 | + | ||||
| 241 | + | <event name="immediate_release" type="destructor"> | |||
| 242 | + | <description summary="release buffer immediately"> | |||
| 243 | + | Sent when the compositor has finalised its usage of the associated | |||
| 244 | + | buffer for the relevant commit, and either performed no operations | |||
| 245 | + | using it, or has a guarantee that all its operations on that buffer for | |||
| 246 | + | that commit have finished. | |||
| 247 | + | ||||
| 248 | + | Once this event is received, and assuming the associated buffer is not | |||
| 249 | + | pending release from other wl_surface.commit requests, no additional | |||
| 250 | + | explicit or implicit synchronization is required to safely reuse or | |||
| 251 | + | destroy the buffer. | |||
| 252 | + | ||||
| 253 | + | This event destroys the zwp_linux_buffer_release_v1 object. | |||
| 254 | + | </description> | |||
| 255 | + | </event> | |||
| 256 | + | </interface> | |||
| 257 | + | ||||
| 258 | + | </protocol> | |||
A spec/xml/pointerconstraints.xml +334 -0
| @@ -0,0 +1,334 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="pointer_constraints_unstable_v1"> | |||
| 3 | + | ||||
| 4 | + | <copyright> | |||
| 5 | + | Copyright © 2014 Jonas Ådahl | |||
| 6 | + | Copyright © 2015 Red Hat Inc. | |||
| 7 | + | ||||
| 8 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 9 | + | copy of this software and associated documentation files (the "Software"), | |||
| 10 | + | to deal in the Software without restriction, including without limitation | |||
| 11 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 12 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 13 | + | Software is furnished to do so, subject to the following conditions: | |||
| 14 | + | ||||
| 15 | + | The above copyright notice and this permission notice (including the next | |||
| 16 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 17 | + | Software. | |||
| 18 | + | ||||
| 19 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 20 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 21 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 22 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 23 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 24 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 25 | + | DEALINGS IN THE SOFTWARE. | |||
| 26 | + | </copyright> | |||
| 27 | + | ||||
| 28 | + | <description summary="protocol for constraining pointer motions"> | |||
| 29 | + | This protocol specifies a set of interfaces used for adding constraints to | |||
| 30 | + | the motion of a pointer. Possible constraints include confining pointer | |||
| 31 | + | motions to a given region, or locking it to its current position. | |||
| 32 | + | ||||
| 33 | + | In order to constrain the pointer, a client must first bind the global | |||
| 34 | + | interface "wp_pointer_constraints" which, if a compositor supports pointer | |||
| 35 | + | constraints, is exposed by the registry. Using the bound global object, the | |||
| 36 | + | client uses the request that corresponds to the type of constraint it wants | |||
| 37 | + | to make. See wp_pointer_constraints for more details. | |||
| 38 | + | ||||
| 39 | + | Warning! The protocol described in this file is experimental and backward | |||
| 40 | + | incompatible changes may be made. Backward compatible changes may be added | |||
| 41 | + | together with the corresponding interface version bump. Backward | |||
| 42 | + | incompatible changes are done by bumping the version number in the protocol | |||
| 43 | + | and interface names and resetting the interface version. Once the protocol | |||
| 44 | + | is to be declared stable, the 'z' prefix and the version number in the | |||
| 45 | + | protocol and interface names are removed and the interface version number is | |||
| 46 | + | reset. | |||
| 47 | + | </description> | |||
| 48 | + | ||||
| 49 | + | <interface name="zwp_pointer_constraints_v1" version="1"> | |||
| 50 | + | <description summary="constrain the movement of a pointer"> | |||
| 51 | + | The global interface exposing pointer constraining functionality. It | |||
| 52 | + | exposes two requests: lock_pointer for locking the pointer to its | |||
| 53 | + | position, and confine_pointer for locking the pointer to a region. | |||
| 54 | + | ||||
| 55 | + | The lock_pointer and confine_pointer requests create the objects | |||
| 56 | + | wp_locked_pointer and wp_confined_pointer respectively, and the client can | |||
| 57 | + | use these objects to interact with the lock. | |||
| 58 | + | ||||
| 59 | + | For any surface, only one lock or confinement may be active across all | |||
| 60 | + | wl_pointer objects of the same seat. If a lock or confinement is requested | |||
| 61 | + | when another lock or confinement is active or requested on the same surface | |||
| 62 | + | and with any of the wl_pointer objects of the same seat, an | |||
| 63 | + | 'already_constrained' error will be raised. | |||
| 64 | + | </description> | |||
| 65 | + | ||||
| 66 | + | <enum name="error"> | |||
| 67 | + | <description summary="wp_pointer_constraints error values"> | |||
| 68 | + | These errors can be emitted in response to wp_pointer_constraints | |||
| 69 | + | requests. | |||
| 70 | + | </description> | |||
| 71 | + | <entry name="already_constrained" value="1" | |||
| 72 | + | summary="pointer constraint already requested on that surface"/> | |||
| 73 | + | </enum> | |||
| 74 | + | ||||
| 75 | + | <enum name="lifetime"> | |||
| 76 | + | <description summary="constraint lifetime"> | |||
| 77 | + | These values represent different lifetime semantics. They are passed | |||
| 78 | + | as arguments to the factory requests to specify how the constraint | |||
| 79 | + | lifetimes should be managed. | |||
| 80 | + | </description> | |||
| 81 | + | <entry name="oneshot" value="1"> | |||
| 82 | + | <description summary="the pointer constraint is defunct once deactivated"> | |||
| 83 | + | A oneshot pointer constraint will never reactivate once it has been | |||
| 84 | + | deactivated. See the corresponding deactivation event | |||
| 85 | + | (wp_locked_pointer.unlocked and wp_confined_pointer.unconfined) for | |||
| 86 | + | details. | |||
| 87 | + | </description> | |||
| 88 | + | </entry> | |||
| 89 | + | <entry name="persistent" value="2"> | |||
| 90 | + | <description summary="the pointer constraint may reactivate"> | |||
| 91 | + | A persistent pointer constraint may again reactivate once it has | |||
| 92 | + | been deactivated. See the corresponding deactivation event | |||
| 93 | + | (wp_locked_pointer.unlocked and wp_confined_pointer.unconfined) for | |||
| 94 | + | details. | |||
| 95 | + | </description> | |||
| 96 | + | </entry> | |||
| 97 | + | </enum> | |||
| 98 | + | ||||
| 99 | + | <request name="destroy" type="destructor"> | |||
| 100 | + | <description summary="destroy the pointer constraints manager object"> | |||
| 101 | + | Used by the client to notify the server that it will no longer use this | |||
| 102 | + | pointer constraints object. | |||
| 103 | + | </description> | |||
| 104 | + | </request> | |||
| 105 | + | ||||
| 106 | + | <request name="lock_pointer"> | |||
| 107 | + | <description summary="lock pointer to a position"> | |||
| 108 | + | The lock_pointer request lets the client request to disable movements of | |||
| 109 | + | the virtual pointer (i.e. the cursor), effectively locking the pointer | |||
| 110 | + | to a position. This request may not take effect immediately; in the | |||
| 111 | + | future, when the compositor deems implementation-specific constraints | |||
| 112 | + | are satisfied, the pointer lock will be activated and the compositor | |||
| 113 | + | sends a locked event. | |||
| 114 | + | ||||
| 115 | + | The protocol provides no guarantee that the constraints are ever | |||
| 116 | + | satisfied, and does not require the compositor to send an error if the | |||
| 117 | + | constraints cannot ever be satisfied. It is thus possible to request a | |||
| 118 | + | lock that will never activate. | |||
| 119 | + | ||||
| 120 | + | There may not be another pointer constraint of any kind requested or | |||
| 121 | + | active on the surface for any of the wl_pointer objects of the seat of | |||
| 122 | + | the passed pointer when requesting a lock. If there is, an error will be | |||
| 123 | + | raised. See general pointer lock documentation for more details. | |||
| 124 | + | ||||
| 125 | + | The intersection of the region passed with this request and the input | |||
| 126 | + | region of the surface is used to determine where the pointer must be | |||
| 127 | + | in order for the lock to activate. It is up to the compositor whether to | |||
| 128 | + | warp the pointer or require some kind of user interaction for the lock | |||
| 129 | + | to activate. If the region is null the surface input region is used. | |||
| 130 | + | ||||
| 131 | + | A surface may receive pointer focus without the lock being activated. | |||
| 132 | + | ||||
| 133 | + | The request creates a new object wp_locked_pointer which is used to | |||
| 134 | + | interact with the lock as well as receive updates about its state. See | |||
| 135 | + | the the description of wp_locked_pointer for further information. | |||
| 136 | + | ||||
| 137 | + | Note that while a pointer is locked, the wl_pointer objects of the | |||
| 138 | + | corresponding seat will not emit any wl_pointer.motion events, but | |||
| 139 | + | relative motion events will still be emitted via wp_relative_pointer | |||
| 140 | + | objects of the same seat. wl_pointer.axis and wl_pointer.button events | |||
| 141 | + | are unaffected. | |||
| 142 | + | </description> | |||
| 143 | + | <arg name="id" type="new_id" interface="zwp_locked_pointer_v1"/> | |||
| 144 | + | <arg name="surface" type="object" interface="wl_surface" | |||
| 145 | + | summary="surface to lock pointer to"/> | |||
| 146 | + | <arg name="pointer" type="object" interface="wl_pointer" | |||
| 147 | + | summary="the pointer that should be locked"/> | |||
| 148 | + | <arg name="region" type="object" interface="wl_region" allow-null="true" | |||
| 149 | + | summary="region of surface"/> | |||
| 150 | + | <arg name="lifetime" type="uint" enum="lifetime" summary="lock lifetime"/> | |||
| 151 | + | </request> | |||
| 152 | + | ||||
| 153 | + | <request name="confine_pointer"> | |||
| 154 | + | <description summary="confine pointer to a region"> | |||
| 155 | + | The confine_pointer request lets the client request to confine the | |||
| 156 | + | pointer cursor to a given region. This request may not take effect | |||
| 157 | + | immediately; in the future, when the compositor deems implementation- | |||
| 158 | + | specific constraints are satisfied, the pointer confinement will be | |||
| 159 | + | activated and the compositor sends a confined event. | |||
| 160 | + | ||||
| 161 | + | The intersection of the region passed with this request and the input | |||
| 162 | + | region of the surface is used to determine where the pointer must be | |||
| 163 | + | in order for the confinement to activate. It is up to the compositor | |||
| 164 | + | whether to warp the pointer or require some kind of user interaction for | |||
| 165 | + | the confinement to activate. If the region is null the surface input | |||
| 166 | + | region is used. | |||
| 167 | + | ||||
| 168 | + | The request will create a new object wp_confined_pointer which is used | |||
| 169 | + | to interact with the confinement as well as receive updates about its | |||
| 170 | + | state. See the the description of wp_confined_pointer for further | |||
| 171 | + | information. | |||
| 172 | + | </description> | |||
| 173 | + | <arg name="id" type="new_id" interface="zwp_confined_pointer_v1"/> | |||
| 174 | + | <arg name="surface" type="object" interface="wl_surface" | |||
| 175 | + | summary="surface to lock pointer to"/> | |||
| 176 | + | <arg name="pointer" type="object" interface="wl_pointer" | |||
| 177 | + | summary="the pointer that should be confined"/> | |||
| 178 | + | <arg name="region" type="object" interface="wl_region" allow-null="true" | |||
| 179 | + | summary="region of surface"/> | |||
| 180 | + | <arg name="lifetime" type="uint" enum="lifetime" summary="confinement lifetime"/> | |||
| 181 | + | </request> | |||
| 182 | + | </interface> | |||
| 183 | + | ||||
| 184 | + | <interface name="zwp_locked_pointer_v1" version="1"> | |||
| 185 | + | <description summary="receive relative pointer motion events"> | |||
| 186 | + | The wp_locked_pointer interface represents a locked pointer state. | |||
| 187 | + | ||||
| 188 | + | While the lock of this object is active, the wl_pointer objects of the | |||
| 189 | + | associated seat will not emit any wl_pointer.motion events. | |||
| 190 | + | ||||
| 191 | + | This object will send the event 'locked' when the lock is activated. | |||
| 192 | + | Whenever the lock is activated, it is guaranteed that the locked surface | |||
| 193 | + | will already have received pointer focus and that the pointer will be | |||
| 194 | + | within the region passed to the request creating this object. | |||
| 195 | + | ||||
| 196 | + | To unlock the pointer, send the destroy request. This will also destroy | |||
| 197 | + | the wp_locked_pointer object. | |||
| 198 | + | ||||
| 199 | + | If the compositor decides to unlock the pointer the unlocked event is | |||
| 200 | + | sent. See wp_locked_pointer.unlock for details. | |||
| 201 | + | ||||
| 202 | + | When unlocking, the compositor may warp the cursor position to the set | |||
| 203 | + | cursor position hint. If it does, it will not result in any relative | |||
| 204 | + | motion events emitted via wp_relative_pointer. | |||
| 205 | + | ||||
| 206 | + | If the surface the lock was requested on is destroyed and the lock is not | |||
| 207 | + | yet activated, the wp_locked_pointer object is now defunct and must be | |||
| 208 | + | destroyed. | |||
| 209 | + | </description> | |||
| 210 | + | ||||
| 211 | + | <request name="destroy" type="destructor"> | |||
| 212 | + | <description summary="destroy the locked pointer object"> | |||
| 213 | + | Destroy the locked pointer object. If applicable, the compositor will | |||
| 214 | + | unlock the pointer. | |||
| 215 | + | </description> | |||
| 216 | + | </request> | |||
| 217 | + | ||||
| 218 | + | <request name="set_cursor_position_hint"> | |||
| 219 | + | <description summary="set the pointer cursor position hint"> | |||
| 220 | + | Set the cursor position hint relative to the top left corner of the | |||
| 221 | + | surface. | |||
| 222 | + | ||||
| 223 | + | If the client is drawing its own cursor, it should update the position | |||
| 224 | + | hint to the position of its own cursor. A compositor may use this | |||
| 225 | + | information to warp the pointer upon unlock in order to avoid pointer | |||
| 226 | + | jumps. | |||
| 227 | + | ||||
| 228 | + | The cursor position hint is double-buffered state, see | |||
| 229 | + | wl_surface.commit. | |||
| 230 | + | </description> | |||
| 231 | + | <arg name="surface_x" type="fixed" | |||
| 232 | + | summary="surface-local x coordinate"/> | |||
| 233 | + | <arg name="surface_y" type="fixed" | |||
| 234 | + | summary="surface-local y coordinate"/> | |||
| 235 | + | </request> | |||
| 236 | + | ||||
| 237 | + | <request name="set_region"> | |||
| 238 | + | <description summary="set a new lock region"> | |||
| 239 | + | Set a new region used to lock the pointer. | |||
| 240 | + | ||||
| 241 | + | The new lock region is double-buffered, see wl_surface.commit. | |||
| 242 | + | ||||
| 243 | + | For details about the lock region, see wp_locked_pointer. | |||
| 244 | + | </description> | |||
| 245 | + | <arg name="region" type="object" interface="wl_region" allow-null="true" | |||
| 246 | + | summary="region of surface"/> | |||
| 247 | + | </request> | |||
| 248 | + | ||||
| 249 | + | <event name="locked"> | |||
| 250 | + | <description summary="lock activation event"> | |||
| 251 | + | Notification that the pointer lock of the seat's pointer is activated. | |||
| 252 | + | </description> | |||
| 253 | + | </event> | |||
| 254 | + | ||||
| 255 | + | <event name="unlocked"> | |||
| 256 | + | <description summary="lock deactivation event"> | |||
| 257 | + | Notification that the pointer lock of the seat's pointer is no longer | |||
| 258 | + | active. If this is a oneshot pointer lock (see | |||
| 259 | + | wp_pointer_constraints.lifetime) this object is now defunct and should | |||
| 260 | + | be destroyed. If this is a persistent pointer lock (see | |||
| 261 | + | wp_pointer_constraints.lifetime) this pointer lock may again | |||
| 262 | + | reactivate in the future. | |||
| 263 | + | </description> | |||
| 264 | + | </event> | |||
| 265 | + | </interface> | |||
| 266 | + | ||||
| 267 | + | <interface name="zwp_confined_pointer_v1" version="1"> | |||
| 268 | + | <description summary="confined pointer object"> | |||
| 269 | + | The wp_confined_pointer interface represents a confined pointer state. | |||
| 270 | + | ||||
| 271 | + | This object will send the event 'confined' when the confinement is | |||
| 272 | + | activated. Whenever the confinement is activated, it is guaranteed that | |||
| 273 | + | the surface the pointer is confined to will already have received pointer | |||
| 274 | + | focus and that the pointer will be within the region passed to the request | |||
| 275 | + | creating this object. It is up to the compositor to decide whether this | |||
| 276 | + | requires some user interaction and if the pointer will warp to within the | |||
| 277 | + | passed region if outside. | |||
| 278 | + | ||||
| 279 | + | To unconfine the pointer, send the destroy request. This will also destroy | |||
| 280 | + | the wp_confined_pointer object. | |||
| 281 | + | ||||
| 282 | + | If the compositor decides to unconfine the pointer the unconfined event is | |||
| 283 | + | sent. The wp_confined_pointer object is at this point defunct and should | |||
| 284 | + | be destroyed. | |||
| 285 | + | </description> | |||
| 286 | + | ||||
| 287 | + | <request name="destroy" type="destructor"> | |||
| 288 | + | <description summary="destroy the confined pointer object"> | |||
| 289 | + | Destroy the confined pointer object. If applicable, the compositor will | |||
| 290 | + | unconfine the pointer. | |||
| 291 | + | </description> | |||
| 292 | + | </request> | |||
| 293 | + | ||||
| 294 | + | <request name="set_region"> | |||
| 295 | + | <description summary="set a new confine region"> | |||
| 296 | + | Set a new region used to confine the pointer. | |||
| 297 | + | ||||
| 298 | + | The new confine region is double-buffered, see wl_surface.commit. | |||
| 299 | + | ||||
| 300 | + | If the confinement is active when the new confinement region is applied | |||
| 301 | + | and the pointer ends up outside of newly applied region, the pointer may | |||
| 302 | + | warped to a position within the new confinement region. If warped, a | |||
| 303 | + | wl_pointer.motion event will be emitted, but no | |||
| 304 | + | wp_relative_pointer.relative_motion event. | |||
| 305 | + | ||||
| 306 | + | The compositor may also, instead of using the new region, unconfine the | |||
| 307 | + | pointer. | |||
| 308 | + | ||||
| 309 | + | For details about the confine region, see wp_confined_pointer. | |||
| 310 | + | </description> | |||
| 311 | + | <arg name="region" type="object" interface="wl_region" allow-null="true" | |||
| 312 | + | summary="region of surface"/> | |||
| 313 | + | </request> | |||
| 314 | + | ||||
| 315 | + | <event name="confined"> | |||
| 316 | + | <description summary="pointer confined"> | |||
| 317 | + | Notification that the pointer confinement of the seat's pointer is | |||
| 318 | + | activated. | |||
| 319 | + | </description> | |||
| 320 | + | </event> | |||
| 321 | + | ||||
| 322 | + | <event name="unconfined"> | |||
| 323 | + | <description summary="pointer unconfined"> | |||
| 324 | + | Notification that the pointer confinement of the seat's pointer is no | |||
| 325 | + | longer active. If this is a oneshot pointer confinement (see | |||
| 326 | + | wp_pointer_constraints.lifetime) this object is now defunct and should | |||
| 327 | + | be destroyed. If this is a persistent pointer confinement (see | |||
| 328 | + | wp_pointer_constraints.lifetime) this pointer confinement may again | |||
| 329 | + | reactivate in the future. | |||
| 330 | + | </description> | |||
| 331 | + | </event> | |||
| 332 | + | </interface> | |||
| 333 | + | ||||
| 334 | + | </protocol> | |||
A spec/xml/pointergestures.xml +277 -0
| @@ -0,0 +1,277 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="pointer_gestures_unstable_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2015, 2021 Red Hat Inc. | |||
| 5 | + | ||||
| 6 | + | Permission to use, copy, modify, distribute, and sell this | |||
| 7 | + | software and its documentation for any purpose is hereby granted | |||
| 8 | + | without fee, provided that the above copyright notice appear in | |||
| 9 | + | all copies and that both that copyright notice and this permission | |||
| 10 | + | notice appear in supporting documentation, and that the name of | |||
| 11 | + | the copyright holders not be used in advertising or publicity | |||
| 12 | + | pertaining to distribution of the software without specific, | |||
| 13 | + | written prior permission. The copyright holders make no | |||
| 14 | + | representations about the suitability of this software for any | |||
| 15 | + | purpose. It is provided "as is" without express or implied | |||
| 16 | + | warranty. | |||
| 17 | + | ||||
| 18 | + | THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | |||
| 19 | + | SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||
| 20 | + | FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | |||
| 21 | + | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||
| 22 | + | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | |||
| 23 | + | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |||
| 24 | + | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |||
| 25 | + | THIS SOFTWARE. | |||
| 26 | + | </copyright> | |||
| 27 | + | ||||
| 28 | + | <interface name="zwp_pointer_gestures_v1" version="3"> | |||
| 29 | + | <description summary="touchpad gestures"> | |||
| 30 | + | A global interface to provide semantic touchpad gestures for a given | |||
| 31 | + | pointer. | |||
| 32 | + | ||||
| 33 | + | Three gestures are currently supported: swipe, pinch, and hold. | |||
| 34 | + | Pinch and swipe gestures follow a three-stage cycle: begin, update, | |||
| 35 | + | end. Hold gestures follow a two-stage cycle: begin and end. All | |||
| 36 | + | gestures are identified by a unique id. | |||
| 37 | + | ||||
| 38 | + | Warning! The protocol described in this file is experimental and | |||
| 39 | + | backward incompatible changes may be made. Backward compatible changes | |||
| 40 | + | may be added together with the corresponding interface version bump. | |||
| 41 | + | Backward incompatible changes are done by bumping the version number in | |||
| 42 | + | the protocol and interface names and resetting the interface version. | |||
| 43 | + | Once the protocol is to be declared stable, the 'z' prefix and the | |||
| 44 | + | version number in the protocol and interface names are removed and the | |||
| 45 | + | interface version number is reset. | |||
| 46 | + | </description> | |||
| 47 | + | ||||
| 48 | + | <request name="get_swipe_gesture"> | |||
| 49 | + | <description summary="get swipe gesture"> | |||
| 50 | + | Create a swipe gesture object. See the | |||
| 51 | + | wl_pointer_gesture_swipe interface for details. | |||
| 52 | + | </description> | |||
| 53 | + | <arg name="id" type="new_id" interface="zwp_pointer_gesture_swipe_v1"/> | |||
| 54 | + | <arg name="pointer" type="object" interface="wl_pointer"/> | |||
| 55 | + | </request> | |||
| 56 | + | ||||
| 57 | + | <request name="get_pinch_gesture"> | |||
| 58 | + | <description summary="get pinch gesture"> | |||
| 59 | + | Create a pinch gesture object. See the | |||
| 60 | + | wl_pointer_gesture_pinch interface for details. | |||
| 61 | + | </description> | |||
| 62 | + | <arg name="id" type="new_id" interface="zwp_pointer_gesture_pinch_v1"/> | |||
| 63 | + | <arg name="pointer" type="object" interface="wl_pointer"/> | |||
| 64 | + | </request> | |||
| 65 | + | ||||
| 66 | + | <!-- Version 2 additions --> | |||
| 67 | + | ||||
| 68 | + | <request name="release" type="destructor" since="2"> | |||
| 69 | + | <description summary="destroy the pointer gesture object"> | |||
| 70 | + | Destroy the pointer gesture object. Swipe, pinch and hold objects | |||
| 71 | + | created via this gesture object remain valid. | |||
| 72 | + | </description> | |||
| 73 | + | </request> | |||
| 74 | + | ||||
| 75 | + | <!-- Version 3 additions --> | |||
| 76 | + | ||||
| 77 | + | <request name="get_hold_gesture" since="3"> | |||
| 78 | + | <description summary="get hold gesture"> | |||
| 79 | + | Create a hold gesture object. See the | |||
| 80 | + | wl_pointer_gesture_hold interface for details. | |||
| 81 | + | </description> | |||
| 82 | + | <arg name="id" type="new_id" interface="zwp_pointer_gesture_hold_v1"/> | |||
| 83 | + | <arg name="pointer" type="object" interface="wl_pointer"/> | |||
| 84 | + | </request> | |||
| 85 | + | ||||
| 86 | + | </interface> | |||
| 87 | + | ||||
| 88 | + | <interface name="zwp_pointer_gesture_swipe_v1" version="3"> | |||
| 89 | + | <description summary="a swipe gesture object"> | |||
| 90 | + | A swipe gesture object notifies a client about a multi-finger swipe | |||
| 91 | + | gesture detected on an indirect input device such as a touchpad. | |||
| 92 | + | The gesture is usually initiated by multiple fingers moving in the | |||
| 93 | + | same direction but once initiated the direction may change. | |||
| 94 | + | The precise conditions of when such a gesture is detected are | |||
| 95 | + | implementation-dependent. | |||
| 96 | + | ||||
| 97 | + | A gesture consists of three stages: begin, update (optional) and end. | |||
| 98 | + | There cannot be multiple simultaneous hold, pinch or swipe gestures on a | |||
| 99 | + | same pointer/seat, how compositors prevent these situations is | |||
| 100 | + | implementation-dependent. | |||
| 101 | + | ||||
| 102 | + | A gesture may be cancelled by the compositor or the hardware. | |||
| 103 | + | Clients should not consider performing permanent or irreversible | |||
| 104 | + | actions until the end of a gesture has been received. | |||
| 105 | + | </description> | |||
| 106 | + | ||||
| 107 | + | <request name="destroy" type="destructor"> | |||
| 108 | + | <description summary="destroy the pointer swipe gesture object"/> | |||
| 109 | + | </request> | |||
| 110 | + | ||||
| 111 | + | <event name="begin"> | |||
| 112 | + | <description summary="multi-finger swipe begin"> | |||
| 113 | + | This event is sent when a multi-finger swipe gesture is detected | |||
| 114 | + | on the device. | |||
| 115 | + | </description> | |||
| 116 | + | <arg name="serial" type="uint"/> | |||
| 117 | + | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |||
| 118 | + | <arg name="surface" type="object" interface="wl_surface"/> | |||
| 119 | + | <arg name="fingers" type="uint" summary="number of fingers"/> | |||
| 120 | + | </event> | |||
| 121 | + | ||||
| 122 | + | <event name="update"> | |||
| 123 | + | <description summary="multi-finger swipe motion"> | |||
| 124 | + | This event is sent when a multi-finger swipe gesture changes the | |||
| 125 | + | position of the logical center. | |||
| 126 | + | ||||
| 127 | + | The dx and dy coordinates are relative coordinates of the logical | |||
| 128 | + | center of the gesture compared to the previous event. | |||
| 129 | + | </description> | |||
| 130 | + | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |||
| 131 | + | <arg name="dx" type="fixed" summary="delta x coordinate in surface coordinate space"/> | |||
| 132 | + | <arg name="dy" type="fixed" summary="delta y coordinate in surface coordinate space"/> | |||
| 133 | + | </event> | |||
| 134 | + | ||||
| 135 | + | <event name="end"> | |||
| 136 | + | <description summary="multi-finger swipe end"> | |||
| 137 | + | This event is sent when a multi-finger swipe gesture ceases to | |||
| 138 | + | be valid. This may happen when one or more fingers are lifted or | |||
| 139 | + | the gesture is cancelled. | |||
| 140 | + | ||||
| 141 | + | When a gesture is cancelled, the client should undo state changes | |||
| 142 | + | caused by this gesture. What causes a gesture to be cancelled is | |||
| 143 | + | implementation-dependent. | |||
| 144 | + | </description> | |||
| 145 | + | <arg name="serial" type="uint"/> | |||
| 146 | + | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |||
| 147 | + | <arg name="cancelled" type="int" summary="1 if the gesture was cancelled, 0 otherwise"/> | |||
| 148 | + | </event> | |||
| 149 | + | </interface> | |||
| 150 | + | ||||
| 151 | + | <interface name="zwp_pointer_gesture_pinch_v1" version="3"> | |||
| 152 | + | <description summary="a pinch gesture object"> | |||
| 153 | + | A pinch gesture object notifies a client about a multi-finger pinch | |||
| 154 | + | gesture detected on an indirect input device such as a touchpad. | |||
| 155 | + | The gesture is usually initiated by multiple fingers moving towards | |||
| 156 | + | each other or away from each other, or by two or more fingers rotating | |||
| 157 | + | around a logical center of gravity. The precise conditions of when | |||
| 158 | + | such a gesture is detected are implementation-dependent. | |||
| 159 | + | ||||
| 160 | + | A gesture consists of three stages: begin, update (optional) and end. | |||
| 161 | + | There cannot be multiple simultaneous hold, pinch or swipe gestures on a | |||
| 162 | + | same pointer/seat, how compositors prevent these situations is | |||
| 163 | + | implementation-dependent. | |||
| 164 | + | ||||
| 165 | + | A gesture may be cancelled by the compositor or the hardware. | |||
| 166 | + | Clients should not consider performing permanent or irreversible | |||
| 167 | + | actions until the end of a gesture has been received. | |||
| 168 | + | </description> | |||
| 169 | + | ||||
| 170 | + | <request name="destroy" type="destructor"> | |||
| 171 | + | <description summary="destroy the pinch gesture object"/> | |||
| 172 | + | </request> | |||
| 173 | + | ||||
| 174 | + | <event name="begin"> | |||
| 175 | + | <description summary="multi-finger pinch begin"> | |||
| 176 | + | This event is sent when a multi-finger pinch gesture is detected | |||
| 177 | + | on the device. | |||
| 178 | + | </description> | |||
| 179 | + | <arg name="serial" type="uint"/> | |||
| 180 | + | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |||
| 181 | + | <arg name="surface" type="object" interface="wl_surface"/> | |||
| 182 | + | <arg name="fingers" type="uint" summary="number of fingers"/> | |||
| 183 | + | </event> | |||
| 184 | + | ||||
| 185 | + | <event name="update"> | |||
| 186 | + | <description summary="multi-finger pinch motion"> | |||
| 187 | + | This event is sent when a multi-finger pinch gesture changes the | |||
| 188 | + | position of the logical center, the rotation or the relative scale. | |||
| 189 | + | ||||
| 190 | + | The dx and dy coordinates are relative coordinates in the | |||
| 191 | + | surface coordinate space of the logical center of the gesture. | |||
| 192 | + | ||||
| 193 | + | The scale factor is an absolute scale compared to the | |||
| 194 | + | pointer_gesture_pinch.begin event, e.g. a scale of 2 means the fingers | |||
| 195 | + | are now twice as far apart as on pointer_gesture_pinch.begin. | |||
| 196 | + | ||||
| 197 | + | The rotation is the relative angle in degrees clockwise compared to the previous | |||
| 198 | + | pointer_gesture_pinch.begin or pointer_gesture_pinch.update event. | |||
| 199 | + | </description> | |||
| 200 | + | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |||
| 201 | + | <arg name="dx" type="fixed" summary="delta x coordinate in surface coordinate space"/> | |||
| 202 | + | <arg name="dy" type="fixed" summary="delta y coordinate in surface coordinate space"/> | |||
| 203 | + | <arg name="scale" type="fixed" summary="scale relative to the initial finger position"/> | |||
| 204 | + | <arg name="rotation" type="fixed" summary="angle in degrees cw relative to the previous event"/> | |||
| 205 | + | </event> | |||
| 206 | + | ||||
| 207 | + | <event name="end"> | |||
| 208 | + | <description summary="multi-finger pinch end"> | |||
| 209 | + | This event is sent when a multi-finger pinch gesture ceases to | |||
| 210 | + | be valid. This may happen when one or more fingers are lifted or | |||
| 211 | + | the gesture is cancelled. | |||
| 212 | + | ||||
| 213 | + | When a gesture is cancelled, the client should undo state changes | |||
| 214 | + | caused by this gesture. What causes a gesture to be cancelled is | |||
| 215 | + | implementation-dependent. | |||
| 216 | + | </description> | |||
| 217 | + | <arg name="serial" type="uint"/> | |||
| 218 | + | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |||
| 219 | + | <arg name="cancelled" type="int" summary="1 if the gesture was cancelled, 0 otherwise"/> | |||
| 220 | + | </event> | |||
| 221 | + | ||||
| 222 | + | </interface> | |||
| 223 | + | ||||
| 224 | + | <interface name="zwp_pointer_gesture_hold_v1" version="3"> | |||
| 225 | + | <description summary="a hold gesture object"> | |||
| 226 | + | A hold gesture object notifies a client about a single- or | |||
| 227 | + | multi-finger hold gesture detected on an indirect input device such as | |||
| 228 | + | a touchpad. The gesture is usually initiated by one or more fingers | |||
| 229 | + | being held down without significant movement. The precise conditions | |||
| 230 | + | of when such a gesture is detected are implementation-dependent. | |||
| 231 | + | ||||
| 232 | + | In particular, this gesture may be used to cancel kinetic scrolling. | |||
| 233 | + | ||||
| 234 | + | A hold gesture consists of two stages: begin and end. Unlike pinch and | |||
| 235 | + | swipe there is no update stage. | |||
| 236 | + | There cannot be multiple simultaneous hold, pinch or swipe gestures on a | |||
| 237 | + | same pointer/seat, how compositors prevent these situations is | |||
| 238 | + | implementation-dependent. | |||
| 239 | + | ||||
| 240 | + | A gesture may be cancelled by the compositor or the hardware. | |||
| 241 | + | Clients should not consider performing permanent or irreversible | |||
| 242 | + | actions until the end of a gesture has been received. | |||
| 243 | + | </description> | |||
| 244 | + | ||||
| 245 | + | <request name="destroy" type="destructor" since="3"> | |||
| 246 | + | <description summary="destroy the hold gesture object"/> | |||
| 247 | + | </request> | |||
| 248 | + | ||||
| 249 | + | <event name="begin" since="3"> | |||
| 250 | + | <description summary="multi-finger hold begin"> | |||
| 251 | + | This event is sent when a hold gesture is detected on the device. | |||
| 252 | + | </description> | |||
| 253 | + | <arg name="serial" type="uint"/> | |||
| 254 | + | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |||
| 255 | + | <arg name="surface" type="object" interface="wl_surface"/> | |||
| 256 | + | <arg name="fingers" type="uint" summary="number of fingers"/> | |||
| 257 | + | </event> | |||
| 258 | + | ||||
| 259 | + | <event name="end" since="3"> | |||
| 260 | + | <description summary="multi-finger hold end"> | |||
| 261 | + | This event is sent when a hold gesture ceases to | |||
| 262 | + | be valid. This may happen when the holding fingers are lifted or | |||
| 263 | + | the gesture is cancelled, for example if the fingers move past an | |||
| 264 | + | implementation-defined threshold, the finger count changes or the hold | |||
| 265 | + | gesture changes into a different type of gesture. | |||
| 266 | + | ||||
| 267 | + | When a gesture is cancelled, the client may need to undo state changes | |||
| 268 | + | caused by this gesture. What causes a gesture to be cancelled is | |||
| 269 | + | implementation-dependent. | |||
| 270 | + | </description> | |||
| 271 | + | <arg name="serial" type="uint"/> | |||
| 272 | + | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |||
| 273 | + | <arg name="cancelled" type="int" summary="1 if the gesture was cancelled, 0 otherwise"/> | |||
| 274 | + | </event> | |||
| 275 | + | ||||
| 276 | + | </interface> | |||
| 277 | + | </protocol> | |||
A spec/xml/pointerwarp.xml +72 -0
| @@ -0,0 +1,72 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="pointer_warp_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2024 Neal Gompa | |||
| 5 | + | Copyright © 2024 Xaver Hugl | |||
| 6 | + | Copyright © 2024 Matthias Klumpp | |||
| 7 | + | Copyright © 2024 Vlad Zahorodnii | |||
| 8 | + | ||||
| 9 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 10 | + | copy of this software and associated documentation files (the "Software"), | |||
| 11 | + | to deal in the Software without restriction, including without limitation | |||
| 12 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 13 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 14 | + | Software is furnished to do so, subject to the following conditions: | |||
| 15 | + | The above copyright notice and this permission notice (including the next | |||
| 16 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 17 | + | Software. | |||
| 18 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 19 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 20 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 21 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 22 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 23 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 24 | + | DEALINGS IN THE SOFTWARE. | |||
| 25 | + | </copyright> | |||
| 26 | + | ||||
| 27 | + | <interface name="wp_pointer_warp_v1" version="1"> | |||
| 28 | + | <description summary="reposition the pointer to a location on a surface"> | |||
| 29 | + | This global interface allows applications to request the pointer to be | |||
| 30 | + | moved to a position relative to a wl_surface. | |||
| 31 | + | ||||
| 32 | + | Note that if the desired behavior is to constrain the pointer to an area | |||
| 33 | + | or lock it to a position, this protocol does not provide a reliable way | |||
| 34 | + | to do that. The pointer constraint and pointer lock protocols should be | |||
| 35 | + | used for those use cases instead. | |||
| 36 | + | ||||
| 37 | + | Warning! The protocol described in this file is currently in the testing | |||
| 38 | + | phase. Backward compatible changes may be added together with the | |||
| 39 | + | corresponding interface version bump. Backward incompatible changes can | |||
| 40 | + | only be done by creating a new major version of the extension. | |||
| 41 | + | </description> | |||
| 42 | + | ||||
| 43 | + | <request name="destroy" type="destructor"> | |||
| 44 | + | <description summary="destroy the warp manager"> | |||
| 45 | + | Destroy the pointer warp manager. | |||
| 46 | + | </description> | |||
| 47 | + | </request> | |||
| 48 | + | ||||
| 49 | + | <request name="warp_pointer"> | |||
| 50 | + | <description summary="reposition the pointer"> | |||
| 51 | + | Request the compositor to move the pointer to a surface-local position. | |||
| 52 | + | Whether or not the compositor honors the request is implementation defined, | |||
| 53 | + | but it should | |||
| 54 | + | - honor it if the surface has pointer focus, including | |||
| 55 | + | when it has an implicit pointer grab | |||
| 56 | + | - reject it if the enter serial is incorrect | |||
| 57 | + | - reject it if the requested position is outside of the surface | |||
| 58 | + | ||||
| 59 | + | Note that the enter serial is valid for any surface of the client, | |||
| 60 | + | and does not have to be from the surface the pointer is warped to. | |||
| 61 | + | ||||
| 62 | + | </description> | |||
| 63 | + | <arg name="surface" type="object" interface="wl_surface" | |||
| 64 | + | summary="surface to position the pointer on"/> | |||
| 65 | + | <arg name="pointer" type="object" interface="wl_pointer" | |||
| 66 | + | summary="the pointer that should be repositioned"/> | |||
| 67 | + | <arg name="x" type="fixed"/> | |||
| 68 | + | <arg name="y" type="fixed"/> | |||
| 69 | + | <arg name="serial" type="uint" summary="serial number of the enter event"/> | |||
| 70 | + | </request> | |||
| 71 | + | </interface> | |||
| 72 | + | </protocol> | |||
A spec/xml/presentationtime.xml +268 -0
| @@ -0,0 +1,268 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="presentation_time"> | |||
| 3 | + | <!-- wrap:70 --> | |||
| 4 | + | ||||
| 5 | + | <copyright> | |||
| 6 | + | Copyright © 2013-2014 Collabora, Ltd. | |||
| 7 | + | ||||
| 8 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 9 | + | copy of this software and associated documentation files (the "Software"), | |||
| 10 | + | to deal in the Software without restriction, including without limitation | |||
| 11 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 12 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 13 | + | Software is furnished to do so, subject to the following conditions: | |||
| 14 | + | ||||
| 15 | + | The above copyright notice and this permission notice (including the next | |||
| 16 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 17 | + | Software. | |||
| 18 | + | ||||
| 19 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 20 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 21 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 22 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 23 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 24 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 25 | + | DEALINGS IN THE SOFTWARE. | |||
| 26 | + | </copyright> | |||
| 27 | + | ||||
| 28 | + | <interface name="wp_presentation" version="2"> | |||
| 29 | + | <description summary="timed presentation related wl_surface requests"> | |||
| 30 | + | ||||
| 31 | + | <!-- Introduction --> | |||
| 32 | + | ||||
| 33 | + | The main feature of this interface is accurate presentation | |||
| 34 | + | timing feedback to ensure smooth video playback while maintaining | |||
| 35 | + | audio/video synchronization. Some features use the concept of a | |||
| 36 | + | presentation clock, which is defined in the | |||
| 37 | + | presentation.clock_id event. | |||
| 38 | + | ||||
| 39 | + | A content update for a wl_surface is submitted by a | |||
| 40 | + | wl_surface.commit request. Request 'feedback' associates with | |||
| 41 | + | the wl_surface.commit and provides feedback on the content | |||
| 42 | + | update, particularly the final realized presentation time. | |||
| 43 | + | ||||
| 44 | + | <!-- Completing presentation --> | |||
| 45 | + | ||||
| 46 | + | When the final realized presentation time is available, e.g. | |||
| 47 | + | after a framebuffer flip completes, the requested | |||
| 48 | + | presentation_feedback.presented events are sent. The final | |||
| 49 | + | presentation time can differ from the compositor's predicted | |||
| 50 | + | display update time and the update's target time, especially | |||
| 51 | + | when the compositor misses its target vertical blanking period. | |||
| 52 | + | </description> | |||
| 53 | + | ||||
| 54 | + | <enum name="error"> | |||
| 55 | + | <description summary="fatal presentation errors"> | |||
| 56 | + | These fatal protocol errors may be emitted in response to | |||
| 57 | + | illegal presentation requests. | |||
| 58 | + | </description> | |||
| 59 | + | <entry name="invalid_timestamp" value="0" | |||
| 60 | + | summary="invalid value in tv_nsec"/> | |||
| 61 | + | <entry name="invalid_flag" value="1" | |||
| 62 | + | summary="invalid flag"/> | |||
| 63 | + | </enum> | |||
| 64 | + | ||||
| 65 | + | <request name="destroy" type="destructor"> | |||
| 66 | + | <description summary="unbind from the presentation interface"> | |||
| 67 | + | Informs the server that the client will no longer be using | |||
| 68 | + | this protocol object. Existing objects created by this object | |||
| 69 | + | are not affected. | |||
| 70 | + | </description> | |||
| 71 | + | </request> | |||
| 72 | + | ||||
| 73 | + | <request name="feedback"> | |||
| 74 | + | <description summary="request presentation feedback information"> | |||
| 75 | + | Request presentation feedback for the current content submission | |||
| 76 | + | on the given surface. This creates a new presentation_feedback | |||
| 77 | + | object, which will deliver the feedback information once. If | |||
| 78 | + | multiple presentation_feedback objects are created for the same | |||
| 79 | + | submission, they will all deliver the same information. | |||
| 80 | + | ||||
| 81 | + | For details on what information is returned, see the | |||
| 82 | + | presentation_feedback interface. | |||
| 83 | + | </description> | |||
| 84 | + | <arg name="surface" type="object" interface="wl_surface" | |||
| 85 | + | summary="target surface"/> | |||
| 86 | + | <arg name="callback" type="new_id" interface="wp_presentation_feedback" | |||
| 87 | + | summary="new feedback object"/> | |||
| 88 | + | </request> | |||
| 89 | + | ||||
| 90 | + | <event name="clock_id"> | |||
| 91 | + | <description summary="clock ID for timestamps"> | |||
| 92 | + | This event tells the client in which clock domain the | |||
| 93 | + | compositor interprets the timestamps used by the presentation | |||
| 94 | + | extension. This clock is called the presentation clock. | |||
| 95 | + | ||||
| 96 | + | The compositor sends this event when the client binds to the | |||
| 97 | + | presentation interface. The presentation clock does not change | |||
| 98 | + | during the lifetime of the client connection. | |||
| 99 | + | ||||
| 100 | + | The clock identifier is platform dependent. On POSIX platforms, the | |||
| 101 | + | identifier value is one of the clockid_t values accepted by | |||
| 102 | + | clock_gettime(). clock_gettime() is defined by POSIX.1-2001. | |||
| 103 | + | ||||
| 104 | + | Timestamps in this clock domain are expressed as tv_sec_hi, | |||
| 105 | + | tv_sec_lo, tv_nsec triples, each component being an unsigned | |||
| 106 | + | 32-bit value. Whole seconds are in tv_sec which is a 64-bit | |||
| 107 | + | value combined from tv_sec_hi and tv_sec_lo, and the | |||
| 108 | + | additional fractional part in tv_nsec as nanoseconds. Hence, | |||
| 109 | + | for valid timestamps tv_nsec must be in [0, 999999999]. | |||
| 110 | + | ||||
| 111 | + | Note that clock_id applies only to the presentation clock, | |||
| 112 | + | and implies nothing about e.g. the timestamps used in the | |||
| 113 | + | Wayland core protocol input events. | |||
| 114 | + | ||||
| 115 | + | Compositors should prefer a clock which does not jump and is | |||
| 116 | + | not slewed e.g. by NTP. The absolute value of the clock is | |||
| 117 | + | irrelevant. Precision of one millisecond or better is | |||
| 118 | + | recommended. Clients must be able to query the current clock | |||
| 119 | + | value directly, not by asking the compositor. | |||
| 120 | + | </description> | |||
| 121 | + | <arg name="clk_id" type="uint" summary="platform clock identifier"/> | |||
| 122 | + | </event> | |||
| 123 | + | ||||
| 124 | + | </interface> | |||
| 125 | + | ||||
| 126 | + | <interface name="wp_presentation_feedback" version="2"> | |||
| 127 | + | <description summary="presentation time feedback event"> | |||
| 128 | + | A presentation_feedback object returns an indication that a | |||
| 129 | + | wl_surface content update has become visible to the user. | |||
| 130 | + | One object corresponds to one content update submission | |||
| 131 | + | (wl_surface.commit). There are two possible outcomes: the | |||
| 132 | + | content update is presented to the user, and a presentation | |||
| 133 | + | timestamp delivered; or, the user did not see the content | |||
| 134 | + | update because it was superseded or its surface destroyed, | |||
| 135 | + | and the content update is discarded. | |||
| 136 | + | ||||
| 137 | + | Once a presentation_feedback object has delivered a 'presented' | |||
| 138 | + | or 'discarded' event it is automatically destroyed. | |||
| 139 | + | </description> | |||
| 140 | + | ||||
| 141 | + | <event name="sync_output"> | |||
| 142 | + | <description summary="presentation synchronized to this output"> | |||
| 143 | + | As presentation can be synchronized to only one output at a | |||
| 144 | + | time, this event tells which output it was. This event is only | |||
| 145 | + | sent prior to the presented event. | |||
| 146 | + | ||||
| 147 | + | As clients may bind to the same global wl_output multiple | |||
| 148 | + | times, this event is sent for each bound instance that matches | |||
| 149 | + | the synchronized output. If a client has not bound to the | |||
| 150 | + | right wl_output global at all, this event is not sent. | |||
| 151 | + | </description> | |||
| 152 | + | <arg name="output" type="object" interface="wl_output" | |||
| 153 | + | summary="presentation output"/> | |||
| 154 | + | </event> | |||
| 155 | + | ||||
| 156 | + | <enum name="kind" bitfield="true"> | |||
| 157 | + | <description summary="bitmask of flags in presented event"> | |||
| 158 | + | These flags provide information about how the presentation of | |||
| 159 | + | the related content update was done. The intent is to help | |||
| 160 | + | clients assess the reliability of the feedback and the visual | |||
| 161 | + | quality with respect to possible tearing and timings. | |||
| 162 | + | </description> | |||
| 163 | + | <entry name="vsync" value="0x1"> | |||
| 164 | + | <description summary="presentation was vsync'd"> | |||
| 165 | + | The presentation was synchronized to the "vertical retrace" by | |||
| 166 | + | the display hardware such that tearing does not happen. | |||
| 167 | + | Relying on software scheduling is not acceptable for this | |||
| 168 | + | flag. If presentation is done by a copy to the active | |||
| 169 | + | frontbuffer, then it must guarantee that tearing cannot | |||
| 170 | + | happen. | |||
| 171 | + | </description> | |||
| 172 | + | </entry> | |||
| 173 | + | <entry name="hw_clock" value="0x2"> | |||
| 174 | + | <description summary="hardware provided the presentation timestamp"> | |||
| 175 | + | The display hardware provided measurements that the hardware | |||
| 176 | + | driver converted into a presentation timestamp. Sampling a | |||
| 177 | + | clock in software is not acceptable for this flag. | |||
| 178 | + | </description> | |||
| 179 | + | </entry> | |||
| 180 | + | <entry name="hw_completion" value="0x4"> | |||
| 181 | + | <description summary="hardware signalled the start of the presentation"> | |||
| 182 | + | The display hardware signalled that it started using the new | |||
| 183 | + | image content. The opposite of this is e.g. a timer being used | |||
| 184 | + | to guess when the display hardware has switched to the new | |||
| 185 | + | image content. | |||
| 186 | + | </description> | |||
| 187 | + | </entry> | |||
| 188 | + | <entry name="zero_copy" value="0x8"> | |||
| 189 | + | <description summary="presentation was done zero-copy"> | |||
| 190 | + | The presentation of this update was done zero-copy. This means | |||
| 191 | + | the buffer from the client was given to display hardware as | |||
| 192 | + | is, without copying it. Compositing with OpenGL counts as | |||
| 193 | + | copying, even if textured directly from the client buffer. | |||
| 194 | + | Possible zero-copy cases include direct scanout of a | |||
| 195 | + | fullscreen surface and a surface on a hardware overlay. | |||
| 196 | + | </description> | |||
| 197 | + | </entry> | |||
| 198 | + | </enum> | |||
| 199 | + | ||||
| 200 | + | <event name="presented" type="destructor"> | |||
| 201 | + | <description summary="the content update was displayed"> | |||
| 202 | + | The associated content update was displayed to the user at the | |||
| 203 | + | indicated time (tv_sec_hi/lo, tv_nsec). For the interpretation of | |||
| 204 | + | the timestamp, see presentation.clock_id event. | |||
| 205 | + | ||||
| 206 | + | The timestamp corresponds to the time when the content update | |||
| 207 | + | turned into light the first time on the surface's main output. | |||
| 208 | + | Compositors may approximate this from the framebuffer flip | |||
| 209 | + | completion events from the system, and the latency of the | |||
| 210 | + | physical display path if known. | |||
| 211 | + | ||||
| 212 | + | This event is preceded by all related sync_output events | |||
| 213 | + | telling which output's refresh cycle the feedback corresponds | |||
| 214 | + | to, i.e. the main output for the surface. Compositors are | |||
| 215 | + | recommended to choose the output containing the largest part | |||
| 216 | + | of the wl_surface, or keeping the output they previously | |||
| 217 | + | chose. Having a stable presentation output association helps | |||
| 218 | + | clients predict future output refreshes (vblank). | |||
| 219 | + | ||||
| 220 | + | The 'refresh' argument gives the compositor's prediction of how | |||
| 221 | + | many nanoseconds after tv_sec, tv_nsec the very next output | |||
| 222 | + | refresh may occur. This is to further aid clients in | |||
| 223 | + | predicting future refreshes, i.e., estimating the timestamps | |||
| 224 | + | targeting the next few vblanks. If such prediction cannot | |||
| 225 | + | usefully be done, the argument is zero. | |||
| 226 | + | ||||
| 227 | + | For version 2 and later, if the output does not have a constant | |||
| 228 | + | refresh rate, explicit video mode switches excluded, then the | |||
| 229 | + | refresh argument must be either an appropriate rate picked by the | |||
| 230 | + | compositor (e.g. fastest rate), or 0 if no such rate exists. | |||
| 231 | + | For version 1, if the output does not have a constant refresh rate, | |||
| 232 | + | the refresh argument must be zero. | |||
| 233 | + | ||||
| 234 | + | The 64-bit value combined from seq_hi and seq_lo is the value | |||
| 235 | + | of the output's vertical retrace counter when the content | |||
| 236 | + | update was first scanned out to the display. This value must | |||
| 237 | + | be compatible with the definition of MSC in | |||
| 238 | + | GLX_OML_sync_control specification. Note, that if the display | |||
| 239 | + | path has a non-zero latency, the time instant specified by | |||
| 240 | + | this counter may differ from the timestamp's. | |||
| 241 | + | ||||
| 242 | + | If the output does not have a concept of vertical retrace or a | |||
| 243 | + | refresh cycle, or the output device is self-refreshing without | |||
| 244 | + | a way to query the refresh count, then the arguments seq_hi | |||
| 245 | + | and seq_lo must be zero. | |||
| 246 | + | </description> | |||
| 247 | + | <arg name="tv_sec_hi" type="uint" | |||
| 248 | + | summary="high 32 bits of the seconds part of the presentation timestamp"/> | |||
| 249 | + | <arg name="tv_sec_lo" type="uint" | |||
| 250 | + | summary="low 32 bits of the seconds part of the presentation timestamp"/> | |||
| 251 | + | <arg name="tv_nsec" type="uint" | |||
| 252 | + | summary="nanoseconds part of the presentation timestamp"/> | |||
| 253 | + | <arg name="refresh" type="uint" summary="nanoseconds till next refresh"/> | |||
| 254 | + | <arg name="seq_hi" type="uint" | |||
| 255 | + | summary="high 32 bits of refresh counter"/> | |||
| 256 | + | <arg name="seq_lo" type="uint" | |||
| 257 | + | summary="low 32 bits of refresh counter"/> | |||
| 258 | + | <arg name="flags" type="uint" enum="kind" summary="combination of 'kind' values"/> | |||
| 259 | + | </event> | |||
| 260 | + | ||||
| 261 | + | <event name="discarded" type="destructor"> | |||
| 262 | + | <description summary="the content update was not displayed"> | |||
| 263 | + | The content update was never displayed to the user. | |||
| 264 | + | </description> | |||
| 265 | + | </event> | |||
| 266 | + | </interface> | |||
| 267 | + | ||||
| 268 | + | </protocol> | |||
A spec/xml/primaryselection.xml +225 -0
| @@ -0,0 +1,225 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="wp_primary_selection_unstable_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2015, 2016 Red Hat | |||
| 5 | + | ||||
| 6 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 7 | + | copy of this software and associated documentation files (the "Software"), | |||
| 8 | + | to deal in the Software without restriction, including without limitation | |||
| 9 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 10 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 11 | + | Software is furnished to do so, subject to the following conditions: | |||
| 12 | + | ||||
| 13 | + | The above copyright notice and this permission notice (including the next | |||
| 14 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 15 | + | Software. | |||
| 16 | + | ||||
| 17 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 18 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 19 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 20 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 21 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 22 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 23 | + | DEALINGS IN THE SOFTWARE. | |||
| 24 | + | </copyright> | |||
| 25 | + | ||||
| 26 | + | <description summary="Primary selection protocol"> | |||
| 27 | + | This protocol provides the ability to have a primary selection device to | |||
| 28 | + | match that of the X server. This primary selection is a shortcut to the | |||
| 29 | + | common clipboard selection, where text just needs to be selected in order | |||
| 30 | + | to allow copying it elsewhere. The de facto way to perform this action | |||
| 31 | + | is the middle mouse button, although it is not limited to this one. | |||
| 32 | + | ||||
| 33 | + | Clients wishing to honor primary selection should create a primary | |||
| 34 | + | selection source and set it as the selection through | |||
| 35 | + | wp_primary_selection_device.set_selection whenever the text selection | |||
| 36 | + | changes. In order to minimize calls in pointer-driven text selection, | |||
| 37 | + | it should happen only once after the operation finished. Similarly, | |||
| 38 | + | a NULL source should be set when text is unselected. | |||
| 39 | + | ||||
| 40 | + | wp_primary_selection_offer objects are first announced through the | |||
| 41 | + | wp_primary_selection_device.data_offer event. Immediately after this event, | |||
| 42 | + | the primary data offer will emit wp_primary_selection_offer.offer events | |||
| 43 | + | to let know of the mime types being offered. | |||
| 44 | + | ||||
| 45 | + | When the primary selection changes, the client with the keyboard focus | |||
| 46 | + | will receive wp_primary_selection_device.selection events. Only the client | |||
| 47 | + | with the keyboard focus will receive such events with a non-NULL | |||
| 48 | + | wp_primary_selection_offer. Across keyboard focus changes, previously | |||
| 49 | + | focused clients will receive wp_primary_selection_device.events with a | |||
| 50 | + | NULL wp_primary_selection_offer. | |||
| 51 | + | ||||
| 52 | + | In order to request the primary selection data, the client must pass | |||
| 53 | + | a recent serial pertaining to the press event that is triggering the | |||
| 54 | + | operation, if the compositor deems the serial valid and recent, the | |||
| 55 | + | wp_primary_selection_source.send event will happen in the other end | |||
| 56 | + | to let the transfer begin. The client owning the primary selection | |||
| 57 | + | should write the requested data, and close the file descriptor | |||
| 58 | + | immediately. | |||
| 59 | + | ||||
| 60 | + | If the primary selection owner client disappeared during the transfer, | |||
| 61 | + | the client reading the data will receive a | |||
| 62 | + | wp_primary_selection_device.selection event with a NULL | |||
| 63 | + | wp_primary_selection_offer, the client should take this as a hint | |||
| 64 | + | to finish the reads related to the no longer existing offer. | |||
| 65 | + | ||||
| 66 | + | The primary selection owner should be checking for errors during | |||
| 67 | + | writes, merely cancelling the ongoing transfer if any happened. | |||
| 68 | + | </description> | |||
| 69 | + | ||||
| 70 | + | <interface name="zwp_primary_selection_device_manager_v1" version="1"> | |||
| 71 | + | <description summary="X primary selection emulation"> | |||
| 72 | + | The primary selection device manager is a singleton global object that | |||
| 73 | + | provides access to the primary selection. It allows to create | |||
| 74 | + | wp_primary_selection_source objects, as well as retrieving the per-seat | |||
| 75 | + | wp_primary_selection_device objects. | |||
| 76 | + | </description> | |||
| 77 | + | ||||
| 78 | + | <request name="create_source"> | |||
| 79 | + | <description summary="create a new primary selection source"> | |||
| 80 | + | Create a new primary selection source. | |||
| 81 | + | </description> | |||
| 82 | + | <arg name="id" type="new_id" interface="zwp_primary_selection_source_v1"/> | |||
| 83 | + | </request> | |||
| 84 | + | ||||
| 85 | + | <request name="get_device"> | |||
| 86 | + | <description summary="create a new primary selection device"> | |||
| 87 | + | Create a new data device for a given seat. | |||
| 88 | + | </description> | |||
| 89 | + | <arg name="id" type="new_id" interface="zwp_primary_selection_device_v1"/> | |||
| 90 | + | <arg name="seat" type="object" interface="wl_seat"/> | |||
| 91 | + | </request> | |||
| 92 | + | ||||
| 93 | + | <request name="destroy" type="destructor"> | |||
| 94 | + | <description summary="destroy the primary selection device manager"> | |||
| 95 | + | Destroy the primary selection device manager. | |||
| 96 | + | </description> | |||
| 97 | + | </request> | |||
| 98 | + | </interface> | |||
| 99 | + | ||||
| 100 | + | <interface name="zwp_primary_selection_device_v1" version="1"> | |||
| 101 | + | <request name="set_selection"> | |||
| 102 | + | <description summary="set the primary selection"> | |||
| 103 | + | Replaces the current selection. The previous owner of the primary | |||
| 104 | + | selection will receive a wp_primary_selection_source.cancelled event. | |||
| 105 | + | ||||
| 106 | + | To unset the selection, set the source to NULL. | |||
| 107 | + | </description> | |||
| 108 | + | <arg name="source" type="object" interface="zwp_primary_selection_source_v1" allow-null="true"/> | |||
| 109 | + | <arg name="serial" type="uint" summary="serial of the event that triggered this request"/> | |||
| 110 | + | </request> | |||
| 111 | + | ||||
| 112 | + | <event name="data_offer"> | |||
| 113 | + | <description summary="introduce a new wp_primary_selection_offer"> | |||
| 114 | + | Introduces a new wp_primary_selection_offer object that may be used | |||
| 115 | + | to receive the current primary selection. Immediately following this | |||
| 116 | + | event, the new wp_primary_selection_offer object will send | |||
| 117 | + | wp_primary_selection_offer.offer events to describe the offered mime | |||
| 118 | + | types. | |||
| 119 | + | </description> | |||
| 120 | + | <arg name="offer" type="new_id" interface="zwp_primary_selection_offer_v1"/> | |||
| 121 | + | </event> | |||
| 122 | + | ||||
| 123 | + | <event name="selection"> | |||
| 124 | + | <description summary="advertise a new primary selection"> | |||
| 125 | + | The wp_primary_selection_device.selection event is sent to notify the | |||
| 126 | + | client of a new primary selection. This event is sent after the | |||
| 127 | + | wp_primary_selection.data_offer event introducing this object, and after | |||
| 128 | + | the offer has announced its mimetypes through | |||
| 129 | + | wp_primary_selection_offer.offer. | |||
| 130 | + | ||||
| 131 | + | The data_offer is valid until a new offer or NULL is received | |||
| 132 | + | or until the client loses keyboard focus. The client must destroy the | |||
| 133 | + | previous selection data_offer, if any, upon receiving this event. | |||
| 134 | + | </description> | |||
| 135 | + | <arg name="id" type="object" interface="zwp_primary_selection_offer_v1" allow-null="true"/> | |||
| 136 | + | </event> | |||
| 137 | + | ||||
| 138 | + | <request name="destroy" type="destructor"> | |||
| 139 | + | <description summary="destroy the primary selection device"> | |||
| 140 | + | Destroy the primary selection device. | |||
| 141 | + | </description> | |||
| 142 | + | </request> | |||
| 143 | + | </interface> | |||
| 144 | + | ||||
| 145 | + | <interface name="zwp_primary_selection_offer_v1" version="1"> | |||
| 146 | + | <description summary="offer to transfer primary selection contents"> | |||
| 147 | + | A wp_primary_selection_offer represents an offer to transfer the contents | |||
| 148 | + | of the primary selection clipboard to the client. Similar to | |||
| 149 | + | wl_data_offer, the offer also describes the mime types that the data can | |||
| 150 | + | be converted to and provides the mechanisms for transferring the data | |||
| 151 | + | directly to the client. | |||
| 152 | + | </description> | |||
| 153 | + | ||||
| 154 | + | <request name="receive"> | |||
| 155 | + | <description summary="request that the data is transferred"> | |||
| 156 | + | To transfer the contents of the primary selection clipboard, the client | |||
| 157 | + | issues this request and indicates the mime type that it wants to | |||
| 158 | + | receive. The transfer happens through the passed file descriptor | |||
| 159 | + | (typically created with the pipe system call). The source client writes | |||
| 160 | + | the data in the mime type representation requested and then closes the | |||
| 161 | + | file descriptor. | |||
| 162 | + | ||||
| 163 | + | The receiving client reads from the read end of the pipe until EOF and | |||
| 164 | + | closes its end, at which point the transfer is complete. | |||
| 165 | + | </description> | |||
| 166 | + | <arg name="mime_type" type="string"/> | |||
| 167 | + | <arg name="fd" type="fd"/> | |||
| 168 | + | </request> | |||
| 169 | + | ||||
| 170 | + | <request name="destroy" type="destructor"> | |||
| 171 | + | <description summary="destroy the primary selection offer"> | |||
| 172 | + | Destroy the primary selection offer. | |||
| 173 | + | </description> | |||
| 174 | + | </request> | |||
| 175 | + | ||||
| 176 | + | <event name="offer"> | |||
| 177 | + | <description summary="advertise offered mime type"> | |||
| 178 | + | Sent immediately after creating announcing the | |||
| 179 | + | wp_primary_selection_offer through | |||
| 180 | + | wp_primary_selection_device.data_offer. One event is sent per offered | |||
| 181 | + | mime type. | |||
| 182 | + | </description> | |||
| 183 | + | <arg name="mime_type" type="string"/> | |||
| 184 | + | </event> | |||
| 185 | + | </interface> | |||
| 186 | + | ||||
| 187 | + | <interface name="zwp_primary_selection_source_v1" version="1"> | |||
| 188 | + | <description summary="offer to replace the contents of the primary selection"> | |||
| 189 | + | The source side of a wp_primary_selection_offer, it provides a way to | |||
| 190 | + | describe the offered data and respond to requests to transfer the | |||
| 191 | + | requested contents of the primary selection clipboard. | |||
| 192 | + | </description> | |||
| 193 | + | ||||
| 194 | + | <request name="offer"> | |||
| 195 | + | <description summary="add an offered mime type"> | |||
| 196 | + | This request adds a mime type to the set of mime types advertised to | |||
| 197 | + | targets. Can be called several times to offer multiple types. | |||
| 198 | + | </description> | |||
| 199 | + | <arg name="mime_type" type="string"/> | |||
| 200 | + | </request> | |||
| 201 | + | ||||
| 202 | + | <request name="destroy" type="destructor"> | |||
| 203 | + | <description summary="destroy the primary selection source"> | |||
| 204 | + | Destroy the primary selection source. | |||
| 205 | + | </description> | |||
| 206 | + | </request> | |||
| 207 | + | ||||
| 208 | + | <event name="send"> | |||
| 209 | + | <description summary="send the primary selection contents"> | |||
| 210 | + | Request for the current primary selection contents from the client. | |||
| 211 | + | Send the specified mime type over the passed file descriptor, then | |||
| 212 | + | close it. | |||
| 213 | + | </description> | |||
| 214 | + | <arg name="mime_type" type="string"/> | |||
| 215 | + | <arg name="fd" type="fd"/> | |||
| 216 | + | </event> | |||
| 217 | + | ||||
| 218 | + | <event name="cancelled"> | |||
| 219 | + | <description summary="request for primary selection contents was canceled"> | |||
| 220 | + | This primary selection source is no longer valid. The client should | |||
| 221 | + | clean up and destroy this primary selection source. | |||
| 222 | + | </description> | |||
| 223 | + | </event> | |||
| 224 | + | </interface> | |||
| 225 | + | </protocol> | |||
A spec/xml/relativepointer.xml +136 -0
| @@ -0,0 +1,136 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="relative_pointer_unstable_v1"> | |||
| 3 | + | ||||
| 4 | + | <copyright> | |||
| 5 | + | Copyright © 2014 Jonas Ådahl | |||
| 6 | + | Copyright © 2015 Red Hat Inc. | |||
| 7 | + | ||||
| 8 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 9 | + | copy of this software and associated documentation files (the "Software"), | |||
| 10 | + | to deal in the Software without restriction, including without limitation | |||
| 11 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 12 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 13 | + | Software is furnished to do so, subject to the following conditions: | |||
| 14 | + | ||||
| 15 | + | The above copyright notice and this permission notice (including the next | |||
| 16 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 17 | + | Software. | |||
| 18 | + | ||||
| 19 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 20 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 21 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 22 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 23 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 24 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 25 | + | DEALINGS IN THE SOFTWARE. | |||
| 26 | + | </copyright> | |||
| 27 | + | ||||
| 28 | + | <description summary="protocol for relative pointer motion events"> | |||
| 29 | + | This protocol specifies a set of interfaces used for making clients able to | |||
| 30 | + | receive relative pointer events not obstructed by barriers (such as the | |||
| 31 | + | monitor edge or other pointer barriers). | |||
| 32 | + | ||||
| 33 | + | To start receiving relative pointer events, a client must first bind the | |||
| 34 | + | global interface "wp_relative_pointer_manager" which, if a compositor | |||
| 35 | + | supports relative pointer motion events, is exposed by the registry. After | |||
| 36 | + | having created the relative pointer manager proxy object, the client uses | |||
| 37 | + | it to create the actual relative pointer object using the | |||
| 38 | + | "get_relative_pointer" request given a wl_pointer. The relative pointer | |||
| 39 | + | motion events will then, when applicable, be transmitted via the proxy of | |||
| 40 | + | the newly created relative pointer object. See the documentation of the | |||
| 41 | + | relative pointer interface for more details. | |||
| 42 | + | ||||
| 43 | + | Warning! The protocol described in this file is experimental and backward | |||
| 44 | + | incompatible changes may be made. Backward compatible changes may be added | |||
| 45 | + | together with the corresponding interface version bump. Backward | |||
| 46 | + | incompatible changes are done by bumping the version number in the protocol | |||
| 47 | + | and interface names and resetting the interface version. Once the protocol | |||
| 48 | + | is to be declared stable, the 'z' prefix and the version number in the | |||
| 49 | + | protocol and interface names are removed and the interface version number is | |||
| 50 | + | reset. | |||
| 51 | + | </description> | |||
| 52 | + | ||||
| 53 | + | <interface name="zwp_relative_pointer_manager_v1" version="1"> | |||
| 54 | + | <description summary="get relative pointer objects"> | |||
| 55 | + | A global interface used for getting the relative pointer object for a | |||
| 56 | + | given pointer. | |||
| 57 | + | </description> | |||
| 58 | + | ||||
| 59 | + | <request name="destroy" type="destructor"> | |||
| 60 | + | <description summary="destroy the relative pointer manager object"> | |||
| 61 | + | Used by the client to notify the server that it will no longer use this | |||
| 62 | + | relative pointer manager object. | |||
| 63 | + | </description> | |||
| 64 | + | </request> | |||
| 65 | + | ||||
| 66 | + | <request name="get_relative_pointer"> | |||
| 67 | + | <description summary="get a relative pointer object"> | |||
| 68 | + | Create a relative pointer interface given a wl_pointer object. See the | |||
| 69 | + | wp_relative_pointer interface for more details. | |||
| 70 | + | </description> | |||
| 71 | + | <arg name="id" type="new_id" interface="zwp_relative_pointer_v1"/> | |||
| 72 | + | <arg name="pointer" type="object" interface="wl_pointer"/> | |||
| 73 | + | </request> | |||
| 74 | + | </interface> | |||
| 75 | + | ||||
| 76 | + | <interface name="zwp_relative_pointer_v1" version="1"> | |||
| 77 | + | <description summary="relative pointer object"> | |||
| 78 | + | A wp_relative_pointer object is an extension to the wl_pointer interface | |||
| 79 | + | used for emitting relative pointer events. It shares the same focus as | |||
| 80 | + | wl_pointer objects of the same seat and will only emit events when it has | |||
| 81 | + | focus. | |||
| 82 | + | </description> | |||
| 83 | + | ||||
| 84 | + | <request name="destroy" type="destructor"> | |||
| 85 | + | <description summary="release the relative pointer object"/> | |||
| 86 | + | </request> | |||
| 87 | + | ||||
| 88 | + | <event name="relative_motion"> | |||
| 89 | + | <description summary="relative pointer motion"> | |||
| 90 | + | Relative x/y pointer motion from the pointer of the seat associated with | |||
| 91 | + | this object. | |||
| 92 | + | ||||
| 93 | + | A relative motion is in the same dimension as regular wl_pointer motion | |||
| 94 | + | events, except they do not represent an absolute position. For example, | |||
| 95 | + | moving a pointer from (x, y) to (x', y') would have the equivalent | |||
| 96 | + | relative motion (x' - x, y' - y). If a pointer motion caused the | |||
| 97 | + | absolute pointer position to be clipped by for example the edge of the | |||
| 98 | + | monitor, the relative motion is unaffected by the clipping and will | |||
| 99 | + | represent the unclipped motion. | |||
| 100 | + | ||||
| 101 | + | This event also contains non-accelerated motion deltas. The | |||
| 102 | + | non-accelerated delta is, when applicable, the regular pointer motion | |||
| 103 | + | delta as it was before having applied motion acceleration and other | |||
| 104 | + | transformations such as normalization. | |||
| 105 | + | ||||
| 106 | + | Note that the non-accelerated delta does not represent 'raw' events as | |||
| 107 | + | they were read from some device. Pointer motion acceleration is device- | |||
| 108 | + | and configuration-specific and non-accelerated deltas and accelerated | |||
| 109 | + | deltas may have the same value on some devices. | |||
| 110 | + | ||||
| 111 | + | Relative motions are not coupled to wl_pointer.motion events, and can be | |||
| 112 | + | sent in combination with such events, but also independently. There may | |||
| 113 | + | also be scenarios where wl_pointer.motion is sent, but there is no | |||
| 114 | + | relative motion. The order of an absolute and relative motion event | |||
| 115 | + | originating from the same physical motion is not guaranteed. | |||
| 116 | + | ||||
| 117 | + | If the client needs button events or focus state, it can receive them | |||
| 118 | + | from a wl_pointer object of the same seat that the wp_relative_pointer | |||
| 119 | + | object is associated with. | |||
| 120 | + | </description> | |||
| 121 | + | <arg name="utime_hi" type="uint" | |||
| 122 | + | summary="high 32 bits of a 64 bit timestamp with microsecond granularity"/> | |||
| 123 | + | <arg name="utime_lo" type="uint" | |||
| 124 | + | summary="low 32 bits of a 64 bit timestamp with microsecond granularity"/> | |||
| 125 | + | <arg name="dx" type="fixed" | |||
| 126 | + | summary="the x component of the motion vector"/> | |||
| 127 | + | <arg name="dy" type="fixed" | |||
| 128 | + | summary="the y component of the motion vector"/> | |||
| 129 | + | <arg name="dx_unaccel" type="fixed" | |||
| 130 | + | summary="the x component of the unaccelerated motion vector"/> | |||
| 131 | + | <arg name="dy_unaccel" type="fixed" | |||
| 132 | + | summary="the y component of the unaccelerated motion vector"/> | |||
| 133 | + | </event> | |||
| 134 | + | </interface> | |||
| 135 | + | ||||
| 136 | + | </protocol> | |||
A spec/xml/securitycontext.xml +180 -0
| @@ -0,0 +1,180 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="security_context_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2021 Simon Ser | |||
| 5 | + | ||||
| 6 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 7 | + | copy of this software and associated documentation files (the "Software"), | |||
| 8 | + | to deal in the Software without restriction, including without limitation | |||
| 9 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 10 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 11 | + | Software is furnished to do so, subject to the following conditions: | |||
| 12 | + | ||||
| 13 | + | The above copyright notice and this permission notice (including the next | |||
| 14 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 15 | + | Software. | |||
| 16 | + | ||||
| 17 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 18 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 19 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 20 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 21 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 22 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 23 | + | DEALINGS IN THE SOFTWARE. | |||
| 24 | + | </copyright> | |||
| 25 | + | ||||
| 26 | + | <interface name="wp_security_context_manager_v1" version="1"> | |||
| 27 | + | <description summary="client security context manager"> | |||
| 28 | + | This interface allows a client to register a new Wayland connection to | |||
| 29 | + | the compositor and attach a security context to it. | |||
| 30 | + | ||||
| 31 | + | This is intended to be used by sandboxes. Sandbox engines attach a | |||
| 32 | + | security context to all connections coming from inside the sandbox. The | |||
| 33 | + | compositor can then restrict the features that the sandboxed connections | |||
| 34 | + | can use. | |||
| 35 | + | ||||
| 36 | + | Compositors should forbid nesting multiple security contexts by not | |||
| 37 | + | exposing wp_security_context_manager_v1 global to clients with a security | |||
| 38 | + | context attached, or by sending the nested protocol error. Nested | |||
| 39 | + | security contexts are dangerous because they can potentially allow | |||
| 40 | + | privilege escalation of a sandboxed client. | |||
| 41 | + | ||||
| 42 | + | Warning! The protocol described in this file is currently in the testing | |||
| 43 | + | phase. Backward compatible changes may be added together with the | |||
| 44 | + | corresponding interface version bump. Backward incompatible changes can | |||
| 45 | + | only be done by creating a new major version of the extension. | |||
| 46 | + | </description> | |||
| 47 | + | ||||
| 48 | + | <enum name="error"> | |||
| 49 | + | <entry name="invalid_listen_fd" value="1" | |||
| 50 | + | summary="listening socket FD is invalid"/> | |||
| 51 | + | <entry name="nested" value="2" | |||
| 52 | + | summary="nested security contexts are forbidden"/> | |||
| 53 | + | </enum> | |||
| 54 | + | ||||
| 55 | + | <request name="destroy" type="destructor"> | |||
| 56 | + | <description summary="destroy the manager object"> | |||
| 57 | + | Destroy the manager. This doesn't destroy objects created with the | |||
| 58 | + | manager. | |||
| 59 | + | </description> | |||
| 60 | + | </request> | |||
| 61 | + | ||||
| 62 | + | <request name="create_listener"> | |||
| 63 | + | <description summary="create a new security context"> | |||
| 64 | + | Creates a new security context with a socket listening FD. | |||
| 65 | + | ||||
| 66 | + | The compositor will accept new client connections on listen_fd. | |||
| 67 | + | listen_fd must be ready to accept new connections when this request is | |||
| 68 | + | sent by the client. In other words, the client must call bind(2) and | |||
| 69 | + | listen(2) before sending the FD. | |||
| 70 | + | ||||
| 71 | + | close_fd is a FD that will signal hangup when the compositor should stop | |||
| 72 | + | accepting new connections on listen_fd. | |||
| 73 | + | ||||
| 74 | + | The compositor must continue to accept connections on listen_fd when | |||
| 75 | + | the Wayland client which created the security context disconnects. | |||
| 76 | + | ||||
| 77 | + | After sending this request, closing listen_fd and close_fd remains the | |||
| 78 | + | only valid operation on them. | |||
| 79 | + | </description> | |||
| 80 | + | <arg name="id" type="new_id" interface="wp_security_context_v1"/> | |||
| 81 | + | <arg name="listen_fd" type="fd" summary="listening socket FD"/> | |||
| 82 | + | <arg name="close_fd" type="fd" summary="FD signaling when done"/> | |||
| 83 | + | </request> | |||
| 84 | + | </interface> | |||
| 85 | + | ||||
| 86 | + | <interface name="wp_security_context_v1" version="1"> | |||
| 87 | + | <description summary="client security context"> | |||
| 88 | + | The security context allows a client to register a new client and attach | |||
| 89 | + | security context metadata to the connections. | |||
| 90 | + | ||||
| 91 | + | When both are set, the combination of the application ID and the sandbox | |||
| 92 | + | engine must uniquely identify an application. The same application ID | |||
| 93 | + | will be used across instances (e.g. if the application is restarted, or | |||
| 94 | + | if the application is started multiple times). | |||
| 95 | + | ||||
| 96 | + | When both are set, the combination of the instance ID and the sandbox | |||
| 97 | + | engine must uniquely identify a running instance of an application. | |||
| 98 | + | </description> | |||
| 99 | + | ||||
| 100 | + | <enum name="error"> | |||
| 101 | + | <entry name="already_used" value="1" | |||
| 102 | + | summary="security context has already been committed"/> | |||
| 103 | + | <entry name="already_set" value="2" | |||
| 104 | + | summary="metadata has already been set"/> | |||
| 105 | + | <entry name="invalid_metadata" value="3" | |||
| 106 | + | summary="metadata is invalid"/> | |||
| 107 | + | </enum> | |||
| 108 | + | ||||
| 109 | + | <request name="destroy" type="destructor"> | |||
| 110 | + | <description summary="destroy the security context object"> | |||
| 111 | + | Destroy the security context object. | |||
| 112 | + | </description> | |||
| 113 | + | </request> | |||
| 114 | + | ||||
| 115 | + | <request name="set_sandbox_engine"> | |||
| 116 | + | <description summary="set the sandbox engine"> | |||
| 117 | + | Attach a unique sandbox engine name to the security context. The name | |||
| 118 | + | should follow the reverse-DNS style (e.g. "org.flatpak"). | |||
| 119 | + | ||||
| 120 | + | A list of well-known engines is maintained at: | |||
| 121 | + | https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/main/staging/security-context/engines.md | |||
| 122 | + | ||||
| 123 | + | It is a protocol error to call this request twice. The already_set | |||
| 124 | + | error is sent in this case. | |||
| 125 | + | </description> | |||
| 126 | + | <arg name="name" type="string" summary="the sandbox engine name"/> | |||
| 127 | + | </request> | |||
| 128 | + | ||||
| 129 | + | <request name="set_app_id"> | |||
| 130 | + | <description summary="set the application ID"> | |||
| 131 | + | Attach an application ID to the security context. | |||
| 132 | + | ||||
| 133 | + | The application ID is an opaque, sandbox-specific identifier for an | |||
| 134 | + | application. See the well-known engines document for more details: | |||
| 135 | + | https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/main/staging/security-context/engines.md | |||
| 136 | + | ||||
| 137 | + | The compositor may use the application ID to group clients belonging to | |||
| 138 | + | the same security context application. | |||
| 139 | + | ||||
| 140 | + | Whether this request is optional or not depends on the sandbox engine used. | |||
| 141 | + | ||||
| 142 | + | It is a protocol error to call this request twice. The already_set | |||
| 143 | + | error is sent in this case. | |||
| 144 | + | </description> | |||
| 145 | + | <arg name="app_id" type="string" summary="the application ID"/> | |||
| 146 | + | </request> | |||
| 147 | + | ||||
| 148 | + | <request name="set_instance_id"> | |||
| 149 | + | <description summary="set the instance ID"> | |||
| 150 | + | Attach an instance ID to the security context. | |||
| 151 | + | ||||
| 152 | + | The instance ID is an opaque, sandbox-specific identifier for a running | |||
| 153 | + | instance of an application. See the well-known engines document for | |||
| 154 | + | more details: | |||
| 155 | + | https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/main/staging/security-context/engines.md | |||
| 156 | + | ||||
| 157 | + | Whether this request is optional or not depends on the sandbox engine used. | |||
| 158 | + | ||||
| 159 | + | It is a protocol error to call this request twice. The already_set | |||
| 160 | + | error is sent in this case. | |||
| 161 | + | </description> | |||
| 162 | + | <arg name="instance_id" type="string" summary="the instance ID"/> | |||
| 163 | + | </request> | |||
| 164 | + | ||||
| 165 | + | <request name="commit"> | |||
| 166 | + | <description summary="register the security context"> | |||
| 167 | + | Atomically register the new client and attach the security context | |||
| 168 | + | metadata. | |||
| 169 | + | ||||
| 170 | + | If the provided metadata is inconsistent or does not match with out of | |||
| 171 | + | band metadata (see | |||
| 172 | + | https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/main/staging/security-context/engines.md), | |||
| 173 | + | the invalid_metadata error may be sent eventually. | |||
| 174 | + | ||||
| 175 | + | It's a protocol error to send any request other than "destroy" after | |||
| 176 | + | this request. In this case, the already_used error is sent. | |||
| 177 | + | </description> | |||
| 178 | + | </request> | |||
| 179 | + | </interface> | |||
| 180 | + | </protocol> | |||
A spec/xml/serverdecoration.xml +85 -0
| @@ -0,0 +1,85 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="server_decoration"> | |||
| 3 | + | <copyright><![CDATA[ | |||
| 4 | + | SPDX-FileCopyrightText: 2015 Martin Gräßlin | |||
| 5 | + | ||||
| 6 | + | SPDX-License-Identifier: LGPL-2.1-or-later | |||
| 7 | + | ]]></copyright> | |||
| 8 | + | <interface name="org_kde_kwin_server_decoration_manager" version="1"> | |||
| 9 | + | <description summary="Server side window decoration manager"> | |||
| 10 | + | This interface allows to coordinate whether the server should create | |||
| 11 | + | a server-side window decoration around a wl_surface representing a | |||
| 12 | + | shell surface (wl_shell_surface or similar). By announcing support | |||
| 13 | + | for this interface the server indicates that it supports server | |||
| 14 | + | side decorations. | |||
| 15 | + | ||||
| 16 | + | Use in conjunction with zxdg_decoration_manager_v1 is undefined. | |||
| 17 | + | </description> | |||
| 18 | + | <request name="create"> | |||
| 19 | + | <description summary="Create a server-side decoration object for a given surface"> | |||
| 20 | + | When a client creates a server-side decoration object it indicates | |||
| 21 | + | that it supports the protocol. The client is supposed to tell the | |||
| 22 | + | server whether it wants server-side decorations or will provide | |||
| 23 | + | client-side decorations. | |||
| 24 | + | ||||
| 25 | + | If the client does not create a server-side decoration object for | |||
| 26 | + | a surface the server interprets this as lack of support for this | |||
| 27 | + | protocol and considers it as client-side decorated. Nevertheless a | |||
| 28 | + | client-side decorated surface should use this protocol to indicate | |||
| 29 | + | to the server that it does not want a server-side deco. | |||
| 30 | + | </description> | |||
| 31 | + | <arg name="id" type="new_id" interface="org_kde_kwin_server_decoration"/> | |||
| 32 | + | <arg name="surface" type="object" interface="wl_surface"/> | |||
| 33 | + | </request> | |||
| 34 | + | <enum name="mode"> | |||
| 35 | + | <description summary="Possible values to use in request_mode and the event mode."/> | |||
| 36 | + | <entry name="None" value="0" summary="Undecorated: The surface is not decorated at all, neither server nor client-side. An example is a popup surface which should not be decorated."/> | |||
| 37 | + | <entry name="Client" value="1" summary="Client-side decoration: The decoration is part of the surface and the client."/> | |||
| 38 | + | <entry name="Server" value="2" summary="Server-side decoration: The server embeds the surface into a decoration frame."/> | |||
| 39 | + | </enum> | |||
| 40 | + | <event name="default_mode"> | |||
| 41 | + | <description summary="The default mode used on the server"> | |||
| 42 | + | This event is emitted directly after binding the interface. It contains | |||
| 43 | + | the default mode for the decoration. When a new server decoration object | |||
| 44 | + | is created this new object will be in the default mode until the first | |||
| 45 | + | request_mode is requested. | |||
| 46 | + | ||||
| 47 | + | The server may change the default mode at any time. | |||
| 48 | + | </description> | |||
| 49 | + | <arg name="mode" type="uint" summary="The default decoration mode applied to newly created server decorations."/> | |||
| 50 | + | </event> | |||
| 51 | + | </interface> | |||
| 52 | + | <interface name="org_kde_kwin_server_decoration" version="1"> | |||
| 53 | + | <request name="release" type="destructor"> | |||
| 54 | + | <description summary="release the server decoration object"/> | |||
| 55 | + | </request> | |||
| 56 | + | <enum name="mode"> | |||
| 57 | + | <description summary="Possible values to use in request_mode and the event mode."/> | |||
| 58 | + | <entry name="None" value="0" summary="Undecorated: The surface is not decorated at all, neither server nor client-side. An example is a popup surface which should not be decorated."/> | |||
| 59 | + | <entry name="Client" value="1" summary="Client-side decoration: The decoration is part of the surface and the client."/> | |||
| 60 | + | <entry name="Server" value="2" summary="Server-side decoration: The server embeds the surface into a decoration frame."/> | |||
| 61 | + | </enum> | |||
| 62 | + | <request name="request_mode"> | |||
| 63 | + | <description summary="The decoration mode the surface wants to use."/> | |||
| 64 | + | <arg name="mode" type="uint" summary="The mode this surface wants to use."/> | |||
| 65 | + | </request> | |||
| 66 | + | <event name="mode"> | |||
| 67 | + | <description summary="The new decoration mode applied by the server"> | |||
| 68 | + | This event is emitted directly after the decoration is created and | |||
| 69 | + | represents the base decoration policy by the server. E.g. a server | |||
| 70 | + | which wants all surfaces to be client-side decorated will send Client, | |||
| 71 | + | a server which wants server-side decoration will send Server. | |||
| 72 | + | ||||
| 73 | + | The client can request a different mode through the decoration request. | |||
| 74 | + | The server will acknowledge this by another event with the same mode. So | |||
| 75 | + | even if a server prefers server-side decoration it's possible to force a | |||
| 76 | + | client-side decoration. | |||
| 77 | + | ||||
| 78 | + | The server may emit this event at any time. In this case the client can | |||
| 79 | + | again request a different mode. It's the responsibility of the server to | |||
| 80 | + | prevent a feedback loop. | |||
| 81 | + | </description> | |||
| 82 | + | <arg name="mode" type="uint" summary="The decoration mode applied to the surface by the server."/> | |||
| 83 | + | </event> | |||
| 84 | + | </interface> | |||
| 85 | + | </protocol> | |||
A spec/xml/singlepixelbuffer.xml +76 -0
| @@ -0,0 +1,76 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="single_pixel_buffer_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2022 Simon Ser | |||
| 5 | + | ||||
| 6 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 7 | + | copy of this software and associated documentation files (the "Software"), | |||
| 8 | + | to deal in the Software without restriction, including without limitation | |||
| 9 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 10 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 11 | + | Software is furnished to do so, subject to the following conditions: | |||
| 12 | + | ||||
| 13 | + | The above copyright notice and this permission notice (including the next | |||
| 14 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 15 | + | Software. | |||
| 16 | + | ||||
| 17 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 18 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 19 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 20 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 21 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 22 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 23 | + | DEALINGS IN THE SOFTWARE. | |||
| 24 | + | </copyright> | |||
| 25 | + | ||||
| 26 | + | <description summary="single pixel buffer factory"> | |||
| 27 | + | This protocol extension allows clients to create single-pixel buffers. | |||
| 28 | + | ||||
| 29 | + | Compositors supporting this protocol extension should also support the | |||
| 30 | + | viewporter protocol extension. Clients may use viewporter to scale a | |||
| 31 | + | single-pixel buffer to a desired size. | |||
| 32 | + | ||||
| 33 | + | Warning! The protocol described in this file is currently in the testing | |||
| 34 | + | phase. Backward compatible changes may be added together with the | |||
| 35 | + | corresponding interface version bump. Backward incompatible changes can | |||
| 36 | + | only be done by creating a new major version of the extension. | |||
| 37 | + | </description> | |||
| 38 | + | ||||
| 39 | + | <interface name="wp_single_pixel_buffer_manager_v1" version="1"> | |||
| 40 | + | <description summary="global factory for single-pixel buffers"> | |||
| 41 | + | The wp_single_pixel_buffer_manager_v1 interface is a factory for | |||
| 42 | + | single-pixel buffers. | |||
| 43 | + | </description> | |||
| 44 | + | ||||
| 45 | + | <request name="destroy" type="destructor"> | |||
| 46 | + | <description summary="destroy the manager"> | |||
| 47 | + | Destroy the wp_single_pixel_buffer_manager_v1 object. | |||
| 48 | + | ||||
| 49 | + | The child objects created via this interface are unaffected. | |||
| 50 | + | </description> | |||
| 51 | + | </request> | |||
| 52 | + | ||||
| 53 | + | <request name="create_u32_rgba_buffer"> | |||
| 54 | + | <description summary="create a 1×1 buffer from 32-bit RGBA values"> | |||
| 55 | + | Create a single-pixel buffer from four 32-bit RGBA values. | |||
| 56 | + | ||||
| 57 | + | Unless specified in another protocol extension, the RGBA values use | |||
| 58 | + | pre-multiplied alpha. | |||
| 59 | + | ||||
| 60 | + | The width and height of the buffer are 1. | |||
| 61 | + | ||||
| 62 | + | The r, g, b and a arguments valid range is from UINT32_MIN (0) | |||
| 63 | + | to UINT32_MAX (0xffffffff). | |||
| 64 | + | ||||
| 65 | + | These arguments should be interpreted as a percentage, i.e. | |||
| 66 | + | - UINT32_MIN = 0% of the given color component | |||
| 67 | + | - UINT32_MAX = 100% of the given color component | |||
| 68 | + | </description> | |||
| 69 | + | <arg name="id" type="new_id" interface="wl_buffer"/> | |||
| 70 | + | <arg name="r" type="uint" summary="value of the buffer's red channel"/> | |||
| 71 | + | <arg name="g" type="uint" summary="value of the buffer's green channel"/> | |||
| 72 | + | <arg name="b" type="uint" summary="value of the buffer's blue channel"/> | |||
| 73 | + | <arg name="a" type="uint" summary="value of the buffer's alpha channel"/> | |||
| 74 | + | </request> | |||
| 75 | + | </interface> | |||
| 76 | + | </protocol> | |||
A spec/xml/tablet.xml +1297 -0
| @@ -0,0 +1,1297 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="tablet_v2"> | |||
| 3 | + | ||||
| 4 | + | <copyright> | |||
| 5 | + | Copyright 2014 © Stephen "Lyude" Chandler Paul | |||
| 6 | + | Copyright 2015-2024 © Red Hat, Inc. | |||
| 7 | + | ||||
| 8 | + | Permission is hereby granted, free of charge, to any person | |||
| 9 | + | obtaining a copy of this software and associated documentation files | |||
| 10 | + | (the "Software"), to deal in the Software without restriction, | |||
| 11 | + | including without limitation the rights to use, copy, modify, merge, | |||
| 12 | + | publish, distribute, sublicense, and/or sell copies of the Software, | |||
| 13 | + | and to permit persons to whom the Software is furnished to do so, | |||
| 14 | + | subject to the following conditions: | |||
| 15 | + | ||||
| 16 | + | The above copyright notice and this permission notice (including the | |||
| 17 | + | next paragraph) shall be included in all copies or substantial | |||
| 18 | + | portions of the Software. | |||
| 19 | + | ||||
| 20 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||
| 21 | + | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
| 22 | + | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |||
| 23 | + | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |||
| 24 | + | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |||
| 25 | + | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
| 26 | + | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| 27 | + | SOFTWARE. | |||
| 28 | + | </copyright> | |||
| 29 | + | ||||
| 30 | + | <description summary="Wayland protocol for graphics tablets"> | |||
| 31 | + | This description provides a high-level overview of the interplay between | |||
| 32 | + | the interfaces defined this protocol. For details, see the protocol | |||
| 33 | + | specification. | |||
| 34 | + | ||||
| 35 | + | More than one tablet may exist, and device-specifics matter. Tablets are | |||
| 36 | + | not represented by a single virtual device like wl_pointer. A client | |||
| 37 | + | binds to the tablet manager object which is just a proxy object. From | |||
| 38 | + | that, the client requests zwp_tablet_manager_v2.get_tablet_seat(wl_seat) | |||
| 39 | + | and that returns the actual interface that has all the tablets. With | |||
| 40 | + | this indirection, we can avoid merging zwp_tablet_v2 into the actual Wayland | |||
| 41 | + | protocol, a long-term benefit. | |||
| 42 | + | ||||
| 43 | + | The zwp_tablet_seat_v2 sends a "tablet added" event for each tablet | |||
| 44 | + | connected. That event is followed by descriptive events about the | |||
| 45 | + | hardware; currently that includes events for name, vid/pid and | |||
| 46 | + | a zwp_tablet_v2.path event that describes a local path. This path can be | |||
| 47 | + | used to uniquely identify a tablet or get more information through | |||
| 48 | + | libwacom. Emulated or nested tablets can skip any of those, e.g. a | |||
| 49 | + | virtual tablet may not have a vid/pid. The sequence of descriptive | |||
| 50 | + | events is terminated by a zwp_tablet_v2.done event to signal that a client | |||
| 51 | + | may now finalize any initialization for that tablet. | |||
| 52 | + | ||||
| 53 | + | Events from tablets require a tool in proximity. Tools are also managed | |||
| 54 | + | by the tablet seat; a "tool added" event is sent whenever a tool is new | |||
| 55 | + | to the compositor. That event is followed by a number of descriptive | |||
| 56 | + | events about the hardware; currently that includes capabilities, | |||
| 57 | + | hardware id and serial number, and tool type. Similar to the tablet | |||
| 58 | + | interface, a zwp_tablet_tool_v2.done event is sent to terminate that initial | |||
| 59 | + | sequence. | |||
| 60 | + | ||||
| 61 | + | Any event from a tool happens on the zwp_tablet_tool_v2 interface. When the | |||
| 62 | + | tool gets into proximity of the tablet, a proximity_in event is sent on | |||
| 63 | + | the zwp_tablet_tool_v2 interface, listing the tablet and the surface. That | |||
| 64 | + | event is followed by a motion event with the coordinates. After that, | |||
| 65 | + | it's the usual motion, axis, button, etc. events. The protocol's | |||
| 66 | + | serialisation means events are grouped by zwp_tablet_tool_v2.frame events. | |||
| 67 | + | ||||
| 68 | + | Two special events (that don't exist in X) are down and up. They signal | |||
| 69 | + | "tip touching the surface". For tablets without real proximity | |||
| 70 | + | detection, the sequence is: proximity_in, motion, down, frame. | |||
| 71 | + | ||||
| 72 | + | When the tool leaves proximity, a proximity_out event is sent. If any | |||
| 73 | + | button is still down, a button release event is sent before this | |||
| 74 | + | proximity event. These button events are sent in the same frame as the | |||
| 75 | + | proximity event to signal to the client that the buttons were held when | |||
| 76 | + | the tool left proximity. | |||
| 77 | + | ||||
| 78 | + | If the tool moves out of the surface but stays in proximity (i.e. | |||
| 79 | + | between windows), compositor-specific grab policies apply. This usually | |||
| 80 | + | means that the proximity-out is delayed until all buttons are released. | |||
| 81 | + | ||||
| 82 | + | Moving a tool physically from one tablet to the other has no real effect | |||
| 83 | + | on the protocol, since we already have the tool object from the "tool | |||
| 84 | + | added" event. All the information is already there and the proximity | |||
| 85 | + | events on both tablets are all a client needs to reconstruct what | |||
| 86 | + | happened. | |||
| 87 | + | ||||
| 88 | + | Some extra axes are normalized, i.e. the client knows the range as | |||
| 89 | + | specified in the protocol (e.g. [0, 65535]), the granularity however is | |||
| 90 | + | unknown. The current normalized axes are pressure, distance, and slider. | |||
| 91 | + | ||||
| 92 | + | Other extra axes are in physical units as specified in the protocol. | |||
| 93 | + | The current extra axes with physical units are tilt, rotation and | |||
| 94 | + | wheel rotation. | |||
| 95 | + | ||||
| 96 | + | Since tablets work independently of the pointer controlled by the mouse, | |||
| 97 | + | the focus handling is independent too and controlled by proximity. | |||
| 98 | + | The zwp_tablet_tool_v2.set_cursor request sets a tool-specific cursor. | |||
| 99 | + | This cursor surface may be the same as the mouse cursor, and it may be | |||
| 100 | + | the same across tools but it is possible to be more fine-grained. For | |||
| 101 | + | example, a client may set different cursors for the pen and eraser. | |||
| 102 | + | ||||
| 103 | + | Tools are generally independent of tablets and it is | |||
| 104 | + | compositor-specific policy when a tool can be removed. Common approaches | |||
| 105 | + | will likely include some form of removing a tool when all tablets the | |||
| 106 | + | tool was used on are removed. | |||
| 107 | + | </description> | |||
| 108 | + | ||||
| 109 | + | <interface name="zwp_tablet_manager_v2" version="2"> | |||
| 110 | + | <description summary="controller object for graphic tablet devices"> | |||
| 111 | + | An object that provides access to the graphics tablets available on this | |||
| 112 | + | system. All tablets are associated with a seat, to get access to the | |||
| 113 | + | actual tablets, use zwp_tablet_manager_v2.get_tablet_seat. | |||
| 114 | + | </description> | |||
| 115 | + | ||||
| 116 | + | <request name="get_tablet_seat"> | |||
| 117 | + | <description summary="get the tablet seat"> | |||
| 118 | + | Get the zwp_tablet_seat_v2 object for the given seat. This object | |||
| 119 | + | provides access to all graphics tablets in this seat. | |||
| 120 | + | </description> | |||
| 121 | + | <arg name="tablet_seat" type="new_id" interface="zwp_tablet_seat_v2"/> | |||
| 122 | + | <arg name="seat" type="object" interface="wl_seat" summary="The wl_seat object to retrieve the tablets for" /> | |||
| 123 | + | </request> | |||
| 124 | + | ||||
| 125 | + | <request name="destroy" type="destructor"> | |||
| 126 | + | <description summary="release the memory for the tablet manager object"> | |||
| 127 | + | Destroy the zwp_tablet_manager_v2 object. Objects created from this | |||
| 128 | + | object are unaffected and should be destroyed separately. | |||
| 129 | + | </description> | |||
| 130 | + | </request> | |||
| 131 | + | </interface> | |||
| 132 | + | ||||
| 133 | + | <interface name="zwp_tablet_seat_v2" version="2"> | |||
| 134 | + | <description summary="controller object for graphic tablet devices of a seat"> | |||
| 135 | + | An object that provides access to the graphics tablets available on this | |||
| 136 | + | seat. After binding to this interface, the compositor sends a set of | |||
| 137 | + | zwp_tablet_seat_v2.tablet_added and zwp_tablet_seat_v2.tool_added events. | |||
| 138 | + | </description> | |||
| 139 | + | ||||
| 140 | + | <request name="destroy" type="destructor"> | |||
| 141 | + | <description summary="release the memory for the tablet seat object"> | |||
| 142 | + | Destroy the zwp_tablet_seat_v2 object. Objects created from this | |||
| 143 | + | object are unaffected and should be destroyed separately. | |||
| 144 | + | </description> | |||
| 145 | + | </request> | |||
| 146 | + | ||||
| 147 | + | <event name="tablet_added"> | |||
| 148 | + | <description summary="new device notification"> | |||
| 149 | + | This event is sent whenever a new tablet becomes available on this | |||
| 150 | + | seat. This event only provides the object id of the tablet, any | |||
| 151 | + | static information about the tablet (device name, vid/pid, etc.) is | |||
| 152 | + | sent through the zwp_tablet_v2 interface. | |||
| 153 | + | </description> | |||
| 154 | + | <arg name="id" type="new_id" interface="zwp_tablet_v2" summary="the newly added graphics tablet"/> | |||
| 155 | + | </event> | |||
| 156 | + | ||||
| 157 | + | <event name="tool_added"> | |||
| 158 | + | <description summary="a new tool has been used with a tablet"> | |||
| 159 | + | This event is sent whenever a tool that has not previously been used | |||
| 160 | + | with a tablet comes into use. This event only provides the object id | |||
| 161 | + | of the tool; any static information about the tool (capabilities, | |||
| 162 | + | type, etc.) is sent through the zwp_tablet_tool_v2 interface. | |||
| 163 | + | </description> | |||
| 164 | + | <arg name="id" type="new_id" interface="zwp_tablet_tool_v2" summary="the newly added tablet tool"/> | |||
| 165 | + | </event> | |||
| 166 | + | ||||
| 167 | + | <event name="pad_added"> | |||
| 168 | + | <description summary="new pad notification"> | |||
| 169 | + | This event is sent whenever a new pad is known to the system. Typically, | |||
| 170 | + | pads are physically attached to tablets and a pad_added event is | |||
| 171 | + | sent immediately after the zwp_tablet_seat_v2.tablet_added. | |||
| 172 | + | However, some standalone pad devices logically attach to tablets at | |||
| 173 | + | runtime, and the client must wait for zwp_tablet_pad_v2.enter to know | |||
| 174 | + | the tablet a pad is attached to. | |||
| 175 | + | ||||
| 176 | + | This event only provides the object id of the pad. All further | |||
| 177 | + | features (buttons, strips, rings) are sent through the zwp_tablet_pad_v2 | |||
| 178 | + | interface. | |||
| 179 | + | </description> | |||
| 180 | + | <arg name="id" type="new_id" interface="zwp_tablet_pad_v2" summary="the newly added pad"/> | |||
| 181 | + | </event> | |||
| 182 | + | </interface> | |||
| 183 | + | ||||
| 184 | + | <interface name="zwp_tablet_tool_v2" version="2"> | |||
| 185 | + | <description summary="a physical tablet tool"> | |||
| 186 | + | An object that represents a physical tool that has been, or is | |||
| 187 | + | currently in use with a tablet in this seat. Each zwp_tablet_tool_v2 | |||
| 188 | + | object stays valid until the client destroys it; the compositor | |||
| 189 | + | reuses the zwp_tablet_tool_v2 object to indicate that the object's | |||
| 190 | + | respective physical tool has come into proximity of a tablet again. | |||
| 191 | + | ||||
| 192 | + | A zwp_tablet_tool_v2 object's relation to a physical tool depends on the | |||
| 193 | + | tablet's ability to report serial numbers. If the tablet supports | |||
| 194 | + | this capability, then the object represents a specific physical tool | |||
| 195 | + | and can be identified even when used on multiple tablets. | |||
| 196 | + | ||||
| 197 | + | A tablet tool has a number of static characteristics, e.g. tool type, | |||
| 198 | + | hardware_serial and capabilities. These capabilities are sent in an | |||
| 199 | + | event sequence after the zwp_tablet_seat_v2.tool_added event before any | |||
| 200 | + | actual events from this tool. This initial event sequence is | |||
| 201 | + | terminated by a zwp_tablet_tool_v2.done event. | |||
| 202 | + | ||||
| 203 | + | Tablet tool events are grouped by zwp_tablet_tool_v2.frame events. | |||
| 204 | + | Any events received before a zwp_tablet_tool_v2.frame event should be | |||
| 205 | + | considered part of the same hardware state change. | |||
| 206 | + | </description> | |||
| 207 | + | ||||
| 208 | + | <request name="set_cursor"> | |||
| 209 | + | <description summary="set the tablet tool's surface"> | |||
| 210 | + | Sets the surface of the cursor used for this tool on the given | |||
| 211 | + | tablet. This request only takes effect if the tool is in proximity | |||
| 212 | + | of one of the requesting client's surfaces or the surface parameter | |||
| 213 | + | is the current pointer surface. If there was a previous surface set | |||
| 214 | + | with this request it is replaced. If surface is NULL, the cursor | |||
| 215 | + | image is hidden. | |||
| 216 | + | ||||
| 217 | + | The parameters hotspot_x and hotspot_y define the position of the | |||
| 218 | + | pointer surface relative to the pointer location. Its top-left corner | |||
| 219 | + | is always at (x, y) - (hotspot_x, hotspot_y), where (x, y) are the | |||
| 220 | + | coordinates of the pointer location, in surface-local coordinates. | |||
| 221 | + | ||||
| 222 | + | On surface.attach requests to the pointer surface, hotspot_x and | |||
| 223 | + | hotspot_y are decremented by the x and y parameters passed to the | |||
| 224 | + | request. Attach must be confirmed by wl_surface.commit as usual. | |||
| 225 | + | ||||
| 226 | + | The hotspot can also be updated by passing the currently set pointer | |||
| 227 | + | surface to this request with new values for hotspot_x and hotspot_y. | |||
| 228 | + | ||||
| 229 | + | The current and pending input regions of the wl_surface are cleared, | |||
| 230 | + | and wl_surface.set_input_region is ignored until the wl_surface is no | |||
| 231 | + | longer used as the cursor. When the use as a cursor ends, the current | |||
| 232 | + | and pending input regions become undefined, and the wl_surface is | |||
| 233 | + | unmapped. | |||
| 234 | + | ||||
| 235 | + | This request gives the surface the role of a zwp_tablet_tool_v2 cursor. A | |||
| 236 | + | surface may only ever be used as the cursor surface for one | |||
| 237 | + | zwp_tablet_tool_v2. If the surface already has another role or has | |||
| 238 | + | previously been used as cursor surface for a different tool, a | |||
| 239 | + | protocol error is raised. | |||
| 240 | + | </description> | |||
| 241 | + | <arg name="serial" type="uint" summary="serial of the proximity_in event"/> | |||
| 242 | + | <arg name="surface" type="object" interface="wl_surface" allow-null="true"/> | |||
| 243 | + | <arg name="hotspot_x" type="int" summary="surface-local x coordinate"/> | |||
| 244 | + | <arg name="hotspot_y" type="int" summary="surface-local y coordinate"/> | |||
| 245 | + | </request> | |||
| 246 | + | ||||
| 247 | + | <request name="destroy" type="destructor"> | |||
| 248 | + | <description summary="destroy the tool object"> | |||
| 249 | + | This destroys the client's resource for this tool object. | |||
| 250 | + | </description> | |||
| 251 | + | </request> | |||
| 252 | + | ||||
| 253 | + | <enum name="type"> | |||
| 254 | + | <description summary="a physical tool type"> | |||
| 255 | + | Describes the physical type of a tool. The physical type of a tool | |||
| 256 | + | generally defines its base usage. | |||
| 257 | + | ||||
| 258 | + | The mouse tool represents a mouse-shaped tool that is not a relative | |||
| 259 | + | device but bound to the tablet's surface, providing absolute | |||
| 260 | + | coordinates. | |||
| 261 | + | ||||
| 262 | + | The lens tool is a mouse-shaped tool with an attached lens to | |||
| 263 | + | provide precision focus. | |||
| 264 | + | </description> | |||
| 265 | + | <entry name="pen" value="0x140" summary="Pen"/> | |||
| 266 | + | <entry name="eraser" value="0x141" summary="Eraser"/> | |||
| 267 | + | <entry name="brush" value="0x142" summary="Brush"/> | |||
| 268 | + | <entry name="pencil" value="0x143" summary="Pencil"/> | |||
| 269 | + | <entry name="airbrush" value="0x144" summary="Airbrush"/> | |||
| 270 | + | <entry name="finger" value="0x145" summary="Finger"/> | |||
| 271 | + | <entry name="mouse" value="0x146" summary="Mouse"/> | |||
| 272 | + | <entry name="lens" value="0x147" summary="Lens"/> | |||
| 273 | + | </enum> | |||
| 274 | + | ||||
| 275 | + | <event name="type"> | |||
| 276 | + | <description summary="tool type"> | |||
| 277 | + | The tool type is the high-level type of the tool and usually decides | |||
| 278 | + | the interaction expected from this tool. | |||
| 279 | + | ||||
| 280 | + | This event is sent in the initial burst of events before the | |||
| 281 | + | zwp_tablet_tool_v2.done event. | |||
| 282 | + | </description> | |||
| 283 | + | <arg name="tool_type" type="uint" enum="type" summary="the physical tool type"/> | |||
| 284 | + | </event> | |||
| 285 | + | ||||
| 286 | + | <event name="hardware_serial"> | |||
| 287 | + | <description summary="unique hardware serial number of the tool"> | |||
| 288 | + | If the physical tool can be identified by a unique 64-bit serial | |||
| 289 | + | number, this event notifies the client of this serial number. | |||
| 290 | + | ||||
| 291 | + | If multiple tablets are available in the same seat and the tool is | |||
| 292 | + | uniquely identifiable by the serial number, that tool may move | |||
| 293 | + | between tablets. | |||
| 294 | + | ||||
| 295 | + | Otherwise, if the tool has no serial number and this event is | |||
| 296 | + | missing, the tool is tied to the tablet it first comes into | |||
| 297 | + | proximity with. Even if the physical tool is used on multiple | |||
| 298 | + | tablets, separate zwp_tablet_tool_v2 objects will be created, one per | |||
| 299 | + | tablet. | |||
| 300 | + | ||||
| 301 | + | This event is sent in the initial burst of events before the | |||
| 302 | + | zwp_tablet_tool_v2.done event. | |||
| 303 | + | </description> | |||
| 304 | + | <arg name="hardware_serial_hi" type="uint" summary="the unique serial number of the tool, most significant bits"/> | |||
| 305 | + | <arg name="hardware_serial_lo" type="uint" summary="the unique serial number of the tool, least significant bits"/> | |||
| 306 | + | </event> | |||
| 307 | + | ||||
| 308 | + | <event name="hardware_id_wacom"> | |||
| 309 | + | <description summary="hardware id notification in Wacom's format"> | |||
| 310 | + | This event notifies the client of a hardware id available on this tool. | |||
| 311 | + | ||||
| 312 | + | The hardware id is a device-specific 64-bit id that provides extra | |||
| 313 | + | information about the tool in use, beyond the wl_tool.type | |||
| 314 | + | enumeration. The format of the id is specific to tablets made by | |||
| 315 | + | Wacom Inc. For example, the hardware id of a Wacom Grip | |||
| 316 | + | Pen (a stylus) is 0x802. | |||
| 317 | + | ||||
| 318 | + | This event is sent in the initial burst of events before the | |||
| 319 | + | zwp_tablet_tool_v2.done event. | |||
| 320 | + | </description> | |||
| 321 | + | <arg name="hardware_id_hi" type="uint" summary="the hardware id, most significant bits"/> | |||
| 322 | + | <arg name="hardware_id_lo" type="uint" summary="the hardware id, least significant bits"/> | |||
| 323 | + | </event> | |||
| 324 | + | ||||
| 325 | + | <enum name="capability"> | |||
| 326 | + | <description summary="capability flags for a tool"> | |||
| 327 | + | Describes extra capabilities on a tablet. | |||
| 328 | + | ||||
| 329 | + | Any tool must provide x and y values, extra axes are | |||
| 330 | + | device-specific. | |||
| 331 | + | </description> | |||
| 332 | + | <entry name="tilt" value="1" summary="Tilt axes"/> | |||
| 333 | + | <entry name="pressure" value="2" summary="Pressure axis"/> | |||
| 334 | + | <entry name="distance" value="3" summary="Distance axis"/> | |||
| 335 | + | <entry name="rotation" value="4" summary="Z-rotation axis"/> | |||
| 336 | + | <entry name="slider" value="5" summary="Slider axis"/> | |||
| 337 | + | <entry name="wheel" value="6" summary="Wheel axis"/> | |||
| 338 | + | </enum> | |||
| 339 | + | ||||
| 340 | + | <event name="capability"> | |||
| 341 | + | <description summary="tool capability notification"> | |||
| 342 | + | This event notifies the client of any capabilities of this tool, | |||
| 343 | + | beyond the main set of x/y axes and tip up/down detection. | |||
| 344 | + | ||||
| 345 | + | One event is sent for each extra capability available on this tool. | |||
| 346 | + | ||||
| 347 | + | This event is sent in the initial burst of events before the | |||
| 348 | + | zwp_tablet_tool_v2.done event. | |||
| 349 | + | </description> | |||
| 350 | + | <arg name="capability" type="uint" enum="capability" summary="the capability"/> | |||
| 351 | + | </event> | |||
| 352 | + | ||||
| 353 | + | <event name="done"> | |||
| 354 | + | <description summary="tool description events sequence complete"> | |||
| 355 | + | This event signals the end of the initial burst of descriptive | |||
| 356 | + | events. A client may consider the static description of the tool to | |||
| 357 | + | be complete and finalize initialization of the tool. | |||
| 358 | + | </description> | |||
| 359 | + | </event> | |||
| 360 | + | ||||
| 361 | + | <event name="removed"> | |||
| 362 | + | <description summary="tool removed"> | |||
| 363 | + | This event is sent when the tool is removed from the system and will | |||
| 364 | + | send no further events. Should the physical tool come back into | |||
| 365 | + | proximity later, a new zwp_tablet_tool_v2 object will be created. | |||
| 366 | + | ||||
| 367 | + | It is compositor-dependent when a tool is removed. A compositor may | |||
| 368 | + | remove a tool on proximity out, tablet removal or any other reason. | |||
| 369 | + | A compositor may also keep a tool alive until shutdown. | |||
| 370 | + | ||||
| 371 | + | If the tool is currently in proximity, a proximity_out event will be | |||
| 372 | + | sent before the removed event. See zwp_tablet_tool_v2.proximity_out for | |||
| 373 | + | the handling of any buttons logically down. | |||
| 374 | + | ||||
| 375 | + | When this event is received, the client must zwp_tablet_tool_v2.destroy | |||
| 376 | + | the object. | |||
| 377 | + | </description> | |||
| 378 | + | </event> | |||
| 379 | + | ||||
| 380 | + | <event name="proximity_in"> | |||
| 381 | + | <description summary="proximity in event"> | |||
| 382 | + | Notification that this tool is focused on a certain surface. | |||
| 383 | + | ||||
| 384 | + | This event can be received when the tool has moved from one surface to | |||
| 385 | + | another, or when the tool has come back into proximity above the | |||
| 386 | + | surface. | |||
| 387 | + | ||||
| 388 | + | If any button is logically down when the tool comes into proximity, | |||
| 389 | + | the respective button event is sent after the proximity_in event but | |||
| 390 | + | within the same frame as the proximity_in event. | |||
| 391 | + | </description> | |||
| 392 | + | <arg name="serial" type="uint"/> | |||
| 393 | + | <arg name="tablet" type="object" interface="zwp_tablet_v2" summary="The tablet the tool is in proximity of"/> | |||
| 394 | + | <arg name="surface" type="object" interface="wl_surface" summary="The current surface the tablet tool is over"/> | |||
| 395 | + | </event> | |||
| 396 | + | ||||
| 397 | + | <event name="proximity_out"> | |||
| 398 | + | <description summary="proximity out event"> | |||
| 399 | + | Notification that this tool has either left proximity, or is no | |||
| 400 | + | longer focused on a certain surface. | |||
| 401 | + | ||||
| 402 | + | When the tablet tool leaves proximity of the tablet, button release | |||
| 403 | + | events are sent for each button that was held down at the time of | |||
| 404 | + | leaving proximity. These events are sent before the proximity_out | |||
| 405 | + | event but within the same zwp_tablet_v2.frame. | |||
| 406 | + | ||||
| 407 | + | If the tool stays within proximity of the tablet, but the focus | |||
| 408 | + | changes from one surface to another, a button release event may not | |||
| 409 | + | be sent until the button is actually released or the tool leaves the | |||
| 410 | + | proximity of the tablet. | |||
| 411 | + | </description> | |||
| 412 | + | </event> | |||
| 413 | + | ||||
| 414 | + | <event name="down"> | |||
| 415 | + | <description summary="tablet tool is making contact"> | |||
| 416 | + | Sent whenever the tablet tool comes in contact with the surface of the | |||
| 417 | + | tablet. | |||
| 418 | + | ||||
| 419 | + | If the tool is already in contact with the tablet when entering the | |||
| 420 | + | input region, the client owning said region will receive a | |||
| 421 | + | zwp_tablet_v2.proximity_in event, followed by a zwp_tablet_v2.down | |||
| 422 | + | event and a zwp_tablet_v2.frame event. | |||
| 423 | + | ||||
| 424 | + | Note that this event describes logical contact, not physical | |||
| 425 | + | contact. On some devices, a compositor may not consider a tool in | |||
| 426 | + | logical contact until a minimum physical pressure threshold is | |||
| 427 | + | exceeded. | |||
| 428 | + | </description> | |||
| 429 | + | <arg name="serial" type="uint"/> | |||
| 430 | + | </event> | |||
| 431 | + | ||||
| 432 | + | <event name="up"> | |||
| 433 | + | <description summary="tablet tool is no longer making contact"> | |||
| 434 | + | Sent whenever the tablet tool stops making contact with the surface of | |||
| 435 | + | the tablet, or when the tablet tool moves out of the input region | |||
| 436 | + | and the compositor grab (if any) is dismissed. | |||
| 437 | + | ||||
| 438 | + | If the tablet tool moves out of the input region while in contact | |||
| 439 | + | with the surface of the tablet and the compositor does not have an | |||
| 440 | + | ongoing grab on the surface, the client owning said region will | |||
| 441 | + | receive a zwp_tablet_v2.up event, followed by a zwp_tablet_v2.proximity_out | |||
| 442 | + | event and a zwp_tablet_v2.frame event. If the compositor has an ongoing | |||
| 443 | + | grab on this device, this event sequence is sent whenever the grab | |||
| 444 | + | is dismissed in the future. | |||
| 445 | + | ||||
| 446 | + | Note that this event describes logical contact, not physical | |||
| 447 | + | contact. On some devices, a compositor may not consider a tool out | |||
| 448 | + | of logical contact until physical pressure falls below a specific | |||
| 449 | + | threshold. | |||
| 450 | + | </description> | |||
| 451 | + | </event> | |||
| 452 | + | ||||
| 453 | + | <event name="motion"> | |||
| 454 | + | <description summary="motion event"> | |||
| 455 | + | Sent whenever a tablet tool moves. | |||
| 456 | + | </description> | |||
| 457 | + | <arg name="x" type="fixed" summary="surface-local x coordinate"/> | |||
| 458 | + | <arg name="y" type="fixed" summary="surface-local y coordinate"/> | |||
| 459 | + | </event> | |||
| 460 | + | ||||
| 461 | + | <event name="pressure"> | |||
| 462 | + | <description summary="pressure change event"> | |||
| 463 | + | Sent whenever the pressure axis on a tool changes. The value of this | |||
| 464 | + | event is normalized to a value between 0 and 65535. | |||
| 465 | + | ||||
| 466 | + | Note that pressure may be nonzero even when a tool is not in logical | |||
| 467 | + | contact. See the down and up events for more details. | |||
| 468 | + | </description> | |||
| 469 | + | <arg name="pressure" type="uint" summary="The current pressure value"/> | |||
| 470 | + | </event> | |||
| 471 | + | ||||
| 472 | + | <event name="distance"> | |||
| 473 | + | <description summary="distance change event"> | |||
| 474 | + | Sent whenever the distance axis on a tool changes. The value of this | |||
| 475 | + | event is normalized to a value between 0 and 65535. | |||
| 476 | + | ||||
| 477 | + | Note that distance may be nonzero even when a tool is not in logical | |||
| 478 | + | contact. See the down and up events for more details. | |||
| 479 | + | </description> | |||
| 480 | + | <arg name="distance" type="uint" summary="The current distance value"/> | |||
| 481 | + | </event> | |||
| 482 | + | ||||
| 483 | + | <event name="tilt"> | |||
| 484 | + | <description summary="tilt change event"> | |||
| 485 | + | Sent whenever one or both of the tilt axes on a tool change. Each tilt | |||
| 486 | + | value is in degrees, relative to the z-axis of the tablet. | |||
| 487 | + | The angle is positive when the top of a tool tilts along the | |||
| 488 | + | positive x or y axis. | |||
| 489 | + | </description> | |||
| 490 | + | <arg name="tilt_x" type="fixed" summary="The current value of the X tilt axis"/> | |||
| 491 | + | <arg name="tilt_y" type="fixed" summary="The current value of the Y tilt axis"/> | |||
| 492 | + | </event> | |||
| 493 | + | ||||
| 494 | + | <event name="rotation"> | |||
| 495 | + | <description summary="z-rotation change event"> | |||
| 496 | + | Sent whenever the z-rotation axis on the tool changes. The | |||
| 497 | + | rotation value is in degrees clockwise from the tool's | |||
| 498 | + | logical neutral position. | |||
| 499 | + | </description> | |||
| 500 | + | <arg name="degrees" type="fixed" summary="The current rotation of the Z axis"/> | |||
| 501 | + | </event> | |||
| 502 | + | ||||
| 503 | + | <event name="slider"> | |||
| 504 | + | <description summary="Slider position change event"> | |||
| 505 | + | Sent whenever the slider position on the tool changes. The | |||
| 506 | + | value is normalized between -65535 and 65535, with 0 as the logical | |||
| 507 | + | neutral position of the slider. | |||
| 508 | + | ||||
| 509 | + | The slider is available on e.g. the Wacom Airbrush tool. | |||
| 510 | + | </description> | |||
| 511 | + | <arg name="position" type="int" summary="The current position of slider"/> | |||
| 512 | + | </event> | |||
| 513 | + | ||||
| 514 | + | <event name="wheel"> | |||
| 515 | + | <description summary="Wheel delta event"> | |||
| 516 | + | Sent whenever the wheel on the tool emits an event. This event | |||
| 517 | + | contains two values for the same axis change. The degrees value is | |||
| 518 | + | in the same orientation as the wl_pointer.vertical_scroll axis. The | |||
| 519 | + | clicks value is in discrete logical clicks of the mouse wheel. This | |||
| 520 | + | value may be zero if the movement of the wheel was less | |||
| 521 | + | than one logical click. | |||
| 522 | + | ||||
| 523 | + | Clients should choose either value and avoid mixing degrees and | |||
| 524 | + | clicks. The compositor may accumulate values smaller than a logical | |||
| 525 | + | click and emulate click events when a certain threshold is met. | |||
| 526 | + | Thus, zwp_tablet_tool_v2.wheel events with non-zero clicks values may | |||
| 527 | + | have different degrees values. | |||
| 528 | + | </description> | |||
| 529 | + | <arg name="degrees" type="fixed" summary="The wheel delta in degrees"/> | |||
| 530 | + | <arg name="clicks" type="int" summary="The wheel delta in discrete clicks"/> | |||
| 531 | + | </event> | |||
| 532 | + | ||||
| 533 | + | <enum name="button_state"> | |||
| 534 | + | <description summary="physical button state"> | |||
| 535 | + | Describes the physical state of a button that produced the button event. | |||
| 536 | + | </description> | |||
| 537 | + | <entry name="released" value="0" summary="button is not pressed"/> | |||
| 538 | + | <entry name="pressed" value="1" summary="button is pressed"/> | |||
| 539 | + | </enum> | |||
| 540 | + | ||||
| 541 | + | <event name="button"> | |||
| 542 | + | <description summary="button event"> | |||
| 543 | + | Sent whenever a button on the tool is pressed or released. | |||
| 544 | + | ||||
| 545 | + | If a button is held down when the tool moves in or out of proximity, | |||
| 546 | + | button events are generated by the compositor. See | |||
| 547 | + | zwp_tablet_tool_v2.proximity_in and zwp_tablet_tool_v2.proximity_out for | |||
| 548 | + | details. | |||
| 549 | + | </description> | |||
| 550 | + | <arg name="serial" type="uint"/> | |||
| 551 | + | <arg name="button" type="uint" summary="The button whose state has changed"/> | |||
| 552 | + | <arg name="state" type="uint" enum="button_state" summary="Whether the button was pressed or released"/> | |||
| 553 | + | </event> | |||
| 554 | + | ||||
| 555 | + | <event name="frame"> | |||
| 556 | + | <description summary="frame event"> | |||
| 557 | + | Marks the end of a series of axis and/or button updates from the | |||
| 558 | + | tablet. The Wayland protocol requires axis updates to be sent | |||
| 559 | + | sequentially, however all events within a frame should be considered | |||
| 560 | + | one hardware event. | |||
| 561 | + | </description> | |||
| 562 | + | <arg name="time" type="uint" summary="The time of the event with millisecond granularity"/> | |||
| 563 | + | </event> | |||
| 564 | + | ||||
| 565 | + | <enum name="error"> | |||
| 566 | + | <entry name="role" value="0" summary="given wl_surface has another role"/> | |||
| 567 | + | </enum> | |||
| 568 | + | </interface> | |||
| 569 | + | ||||
| 570 | + | <interface name="zwp_tablet_v2" version="2"> | |||
| 571 | + | <description summary="graphics tablet device"> | |||
| 572 | + | The zwp_tablet_v2 interface represents one graphics tablet device. The | |||
| 573 | + | tablet interface itself does not generate events; all events are | |||
| 574 | + | generated by zwp_tablet_tool_v2 objects when in proximity above a tablet. | |||
| 575 | + | ||||
| 576 | + | A tablet has a number of static characteristics, e.g. device name and | |||
| 577 | + | pid/vid. These capabilities are sent in an event sequence after the | |||
| 578 | + | zwp_tablet_seat_v2.tablet_added event. This initial event sequence is | |||
| 579 | + | terminated by a zwp_tablet_v2.done event. | |||
| 580 | + | </description> | |||
| 581 | + | ||||
| 582 | + | <request name="destroy" type="destructor"> | |||
| 583 | + | <description summary="destroy the tablet object"> | |||
| 584 | + | This destroys the client's resource for this tablet object. | |||
| 585 | + | </description> | |||
| 586 | + | </request> | |||
| 587 | + | ||||
| 588 | + | <event name="name"> | |||
| 589 | + | <description summary="tablet device name"> | |||
| 590 | + | A descriptive name for the tablet device. | |||
| 591 | + | ||||
| 592 | + | If the device has no descriptive name, this event is not sent. | |||
| 593 | + | ||||
| 594 | + | This event is sent in the initial burst of events before the | |||
| 595 | + | zwp_tablet_v2.done event. | |||
| 596 | + | </description> | |||
| 597 | + | <arg name="name" type="string" summary="the device name"/> | |||
| 598 | + | </event> | |||
| 599 | + | ||||
| 600 | + | <event name="id"> | |||
| 601 | + | <description summary="tablet device vendor/product id"> | |||
| 602 | + | The vendor and product IDs for the tablet device. | |||
| 603 | + | ||||
| 604 | + | The interpretation of the id depends on the zwp_tablet_v2.bustype. | |||
| 605 | + | Prior to version v2 of this protocol, the id was implied to be a USB | |||
| 606 | + | vendor and product ID. If no zwp_tablet_v2.bustype is sent, the ID | |||
| 607 | + | is to be interpreted as USB vendor and product ID. | |||
| 608 | + | ||||
| 609 | + | If the device has no vendor/product ID, this event is not sent. | |||
| 610 | + | This can happen for virtual devices or non-USB devices, for instance. | |||
| 611 | + | ||||
| 612 | + | This event is sent in the initial burst of events before the | |||
| 613 | + | zwp_tablet_v2.done event. | |||
| 614 | + | </description> | |||
| 615 | + | <arg name="vid" type="uint" summary="vendor id"/> | |||
| 616 | + | <arg name="pid" type="uint" summary="product id"/> | |||
| 617 | + | </event> | |||
| 618 | + | ||||
| 619 | + | <event name="path"> | |||
| 620 | + | <description summary="path to the device"> | |||
| 621 | + | A system-specific device path that indicates which device is behind | |||
| 622 | + | this zwp_tablet_v2. This information may be used to gather additional | |||
| 623 | + | information about the device, e.g. through libwacom. | |||
| 624 | + | ||||
| 625 | + | A device may have more than one device path. If so, multiple | |||
| 626 | + | zwp_tablet_v2.path events are sent. A device may be emulated and not | |||
| 627 | + | have a device path, and in that case this event will not be sent. | |||
| 628 | + | ||||
| 629 | + | The format of the path is unspecified, it may be a device node, a | |||
| 630 | + | sysfs path, or some other identifier. It is up to the client to | |||
| 631 | + | identify the string provided. | |||
| 632 | + | ||||
| 633 | + | This event is sent in the initial burst of events before the | |||
| 634 | + | zwp_tablet_v2.done event. | |||
| 635 | + | </description> | |||
| 636 | + | <arg name="path" type="string" summary="path to local device"/> | |||
| 637 | + | </event> | |||
| 638 | + | ||||
| 639 | + | <event name="done"> | |||
| 640 | + | <description summary="tablet description events sequence complete"> | |||
| 641 | + | This event is sent immediately to signal the end of the initial | |||
| 642 | + | burst of descriptive events. A client may consider the static | |||
| 643 | + | description of the tablet to be complete and finalize initialization | |||
| 644 | + | of the tablet. | |||
| 645 | + | </description> | |||
| 646 | + | </event> | |||
| 647 | + | ||||
| 648 | + | <event name="removed"> | |||
| 649 | + | <description summary="tablet removed event"> | |||
| 650 | + | Sent when the tablet has been removed from the system. When a tablet | |||
| 651 | + | is removed, some tools may be removed. | |||
| 652 | + | ||||
| 653 | + | When this event is received, the client must zwp_tablet_v2.destroy | |||
| 654 | + | the object. | |||
| 655 | + | </description> | |||
| 656 | + | </event> | |||
| 657 | + | ||||
| 658 | + | <!-- Version 2 additions --> | |||
| 659 | + | ||||
| 660 | + | <enum name="bustype" since="2"> | |||
| 661 | + | <description summary="bus type "> | |||
| 662 | + | Describes the bus types this tablet is connected to. | |||
| 663 | + | </description> | |||
| 664 | + | <entry name="usb" value="3" summary="USB"/> | |||
| 665 | + | <entry name="bluetooth" value="5" summary="Bluetooth"/> | |||
| 666 | + | <entry name="virtual" value="6" summary="Virtual"/> | |||
| 667 | + | <entry name="serial" value="17" summary="Serial"/> | |||
| 668 | + | <entry name="i2c" value="24" summary="I2C"/> | |||
| 669 | + | </enum> | |||
| 670 | + | ||||
| 671 | + | <event name="bustype" since="2"> | |||
| 672 | + | <description summary="tablet device bus type"> | |||
| 673 | + | The bustype argument is one of the BUS_ defines in the Linux kernel's | |||
| 674 | + | linux/input.h | |||
| 675 | + | ||||
| 676 | + | If the device has no known bustype or the bustype cannot be | |||
| 677 | + | queried, this event is not sent. | |||
| 678 | + | ||||
| 679 | + | This event is sent in the initial burst of events before the | |||
| 680 | + | zwp_tablet_v2.done event. | |||
| 681 | + | </description> | |||
| 682 | + | <arg name="bustype" type="uint" enum="bustype" summary="bus type"/> | |||
| 683 | + | </event> | |||
| 684 | + | </interface> | |||
| 685 | + | ||||
| 686 | + | <interface name="zwp_tablet_pad_ring_v2" version="2"> | |||
| 687 | + | <description summary="pad ring"> | |||
| 688 | + | A circular interaction area, such as the touch ring on the Wacom Intuos | |||
| 689 | + | Pro series tablets. | |||
| 690 | + | ||||
| 691 | + | Events on a ring are logically grouped by the zwp_tablet_pad_ring_v2.frame | |||
| 692 | + | event. | |||
| 693 | + | </description> | |||
| 694 | + | ||||
| 695 | + | <request name="set_feedback"> | |||
| 696 | + | <description summary="set compositor feedback"> | |||
| 697 | + | Request that the compositor use the provided feedback string | |||
| 698 | + | associated with this ring. This request should be issued immediately | |||
| 699 | + | after a zwp_tablet_pad_group_v2.mode_switch event from the corresponding | |||
| 700 | + | group is received, or whenever the ring is mapped to a different | |||
| 701 | + | action. See zwp_tablet_pad_group_v2.mode_switch for more details. | |||
| 702 | + | ||||
| 703 | + | Clients are encouraged to provide context-aware descriptions for | |||
| 704 | + | the actions associated with the ring; compositors may use this | |||
| 705 | + | information to offer visual feedback about the button layout | |||
| 706 | + | (eg. on-screen displays). | |||
| 707 | + | ||||
| 708 | + | The provided string 'description' is a UTF-8 encoded string to be | |||
| 709 | + | associated with this ring, and is considered user-visible; general | |||
| 710 | + | internationalization rules apply. | |||
| 711 | + | ||||
| 712 | + | The serial argument will be that of the last | |||
| 713 | + | zwp_tablet_pad_group_v2.mode_switch event received for the group of this | |||
| 714 | + | ring. Requests providing other serials than the most recent one will be | |||
| 715 | + | ignored. | |||
| 716 | + | </description> | |||
| 717 | + | <arg name="description" type="string" summary="ring description"/> | |||
| 718 | + | <arg name="serial" type="uint" summary="serial of the mode switch event"/> | |||
| 719 | + | </request> | |||
| 720 | + | ||||
| 721 | + | <request name="destroy" type="destructor"> | |||
| 722 | + | <description summary="destroy the ring object"> | |||
| 723 | + | This destroys the client's resource for this ring object. | |||
| 724 | + | </description> | |||
| 725 | + | </request> | |||
| 726 | + | ||||
| 727 | + | <enum name="source"> | |||
| 728 | + | <description summary="ring axis source"> | |||
| 729 | + | Describes the source types for ring events. This indicates to the | |||
| 730 | + | client how a ring event was physically generated; a client may | |||
| 731 | + | adjust the user interface accordingly. For example, events | |||
| 732 | + | from a "finger" source may trigger kinetic scrolling. | |||
| 733 | + | </description> | |||
| 734 | + | <entry name="finger" value="1" summary="finger"/> | |||
| 735 | + | </enum> | |||
| 736 | + | ||||
| 737 | + | <event name="source"> | |||
| 738 | + | <description summary="ring event source"> | |||
| 739 | + | Source information for ring events. | |||
| 740 | + | ||||
| 741 | + | This event does not occur on its own. It is sent before a | |||
| 742 | + | zwp_tablet_pad_ring_v2.frame event and carries the source information | |||
| 743 | + | for all events within that frame. | |||
| 744 | + | ||||
| 745 | + | The source specifies how this event was generated. If the source is | |||
| 746 | + | zwp_tablet_pad_ring_v2.source.finger, a zwp_tablet_pad_ring_v2.stop event | |||
| 747 | + | will be sent when the user lifts the finger off the device. | |||
| 748 | + | ||||
| 749 | + | This event is optional. If the source is unknown for an interaction, | |||
| 750 | + | no event is sent. | |||
| 751 | + | </description> | |||
| 752 | + | <arg name="source" type="uint" enum="source" summary="the event source"/> | |||
| 753 | + | </event> | |||
| 754 | + | ||||
| 755 | + | <event name="angle"> | |||
| 756 | + | <description summary="angle changed"> | |||
| 757 | + | Sent whenever the angle on a ring changes. | |||
| 758 | + | ||||
| 759 | + | The angle is provided in degrees clockwise from the logical | |||
| 760 | + | north of the ring in the pad's current rotation. | |||
| 761 | + | </description> | |||
| 762 | + | <arg name="degrees" type="fixed" summary="the current angle in degrees"/> | |||
| 763 | + | </event> | |||
| 764 | + | ||||
| 765 | + | <event name="stop"> | |||
| 766 | + | <description summary="interaction stopped"> | |||
| 767 | + | Stop notification for ring events. | |||
| 768 | + | ||||
| 769 | + | For some zwp_tablet_pad_ring_v2.source types, a zwp_tablet_pad_ring_v2.stop | |||
| 770 | + | event is sent to notify a client that the interaction with the ring | |||
| 771 | + | has terminated. This enables the client to implement kinetic scrolling. | |||
| 772 | + | See the zwp_tablet_pad_ring_v2.source documentation for information on | |||
| 773 | + | when this event may be generated. | |||
| 774 | + | ||||
| 775 | + | Any zwp_tablet_pad_ring_v2.angle events with the same source after this | |||
| 776 | + | event should be considered as the start of a new interaction. | |||
| 777 | + | </description> | |||
| 778 | + | </event> | |||
| 779 | + | ||||
| 780 | + | <event name="frame"> | |||
| 781 | + | <description summary="end of a ring event sequence"> | |||
| 782 | + | Indicates the end of a set of ring events that logically belong | |||
| 783 | + | together. A client is expected to accumulate the data in all events | |||
| 784 | + | within the frame before proceeding. | |||
| 785 | + | ||||
| 786 | + | All zwp_tablet_pad_ring_v2 events before a zwp_tablet_pad_ring_v2.frame event belong | |||
| 787 | + | logically together. For example, on termination of a finger interaction | |||
| 788 | + | on a ring the compositor will send a zwp_tablet_pad_ring_v2.source event, | |||
| 789 | + | a zwp_tablet_pad_ring_v2.stop event and a zwp_tablet_pad_ring_v2.frame event. | |||
| 790 | + | ||||
| 791 | + | A zwp_tablet_pad_ring_v2.frame event is sent for every logical event | |||
| 792 | + | group, even if the group only contains a single zwp_tablet_pad_ring_v2 | |||
| 793 | + | event. Specifically, a client may get a sequence: angle, frame, | |||
| 794 | + | angle, frame, etc. | |||
| 795 | + | </description> | |||
| 796 | + | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |||
| 797 | + | </event> | |||
| 798 | + | </interface> | |||
| 799 | + | ||||
| 800 | + | <interface name="zwp_tablet_pad_strip_v2" version="2"> | |||
| 801 | + | <description summary="pad strip"> | |||
| 802 | + | A linear interaction area, such as the strips found in Wacom Cintiq | |||
| 803 | + | models. | |||
| 804 | + | ||||
| 805 | + | Events on a strip are logically grouped by the zwp_tablet_pad_strip_v2.frame | |||
| 806 | + | event. | |||
| 807 | + | </description> | |||
| 808 | + | ||||
| 809 | + | <request name="set_feedback"> | |||
| 810 | + | <description summary="set compositor feedback"> | |||
| 811 | + | Requests the compositor to use the provided feedback string | |||
| 812 | + | associated with this strip. This request should be issued immediately | |||
| 813 | + | after a zwp_tablet_pad_group_v2.mode_switch event from the corresponding | |||
| 814 | + | group is received, or whenever the strip is mapped to a different | |||
| 815 | + | action. See zwp_tablet_pad_group_v2.mode_switch for more details. | |||
| 816 | + | ||||
| 817 | + | Clients are encouraged to provide context-aware descriptions for | |||
| 818 | + | the actions associated with the strip, and compositors may use this | |||
| 819 | + | information to offer visual feedback about the button layout | |||
| 820 | + | (eg. on-screen displays). | |||
| 821 | + | ||||
| 822 | + | The provided string 'description' is a UTF-8 encoded string to be | |||
| 823 | + | associated with this ring, and is considered user-visible; general | |||
| 824 | + | internationalization rules apply. | |||
| 825 | + | ||||
| 826 | + | The serial argument will be that of the last | |||
| 827 | + | zwp_tablet_pad_group_v2.mode_switch event received for the group of this | |||
| 828 | + | strip. Requests providing other serials than the most recent one will be | |||
| 829 | + | ignored. | |||
| 830 | + | </description> | |||
| 831 | + | <arg name="description" type="string" summary="strip description"/> | |||
| 832 | + | <arg name="serial" type="uint" summary="serial of the mode switch event"/> | |||
| 833 | + | </request> | |||
| 834 | + | ||||
| 835 | + | <request name="destroy" type="destructor"> | |||
| 836 | + | <description summary="destroy the strip object"> | |||
| 837 | + | This destroys the client's resource for this strip object. | |||
| 838 | + | </description> | |||
| 839 | + | </request> | |||
| 840 | + | ||||
| 841 | + | <enum name="source"> | |||
| 842 | + | <description summary="strip axis source"> | |||
| 843 | + | Describes the source types for strip events. This indicates to the | |||
| 844 | + | client how a strip event was physically generated; a client may | |||
| 845 | + | adjust the user interface accordingly. For example, events | |||
| 846 | + | from a "finger" source may trigger kinetic scrolling. | |||
| 847 | + | </description> | |||
| 848 | + | <entry name="finger" value="1" summary="finger"/> | |||
| 849 | + | </enum> | |||
| 850 | + | ||||
| 851 | + | <event name="source"> | |||
| 852 | + | <description summary="strip event source"> | |||
| 853 | + | Source information for strip events. | |||
| 854 | + | ||||
| 855 | + | This event does not occur on its own. It is sent before a | |||
| 856 | + | zwp_tablet_pad_strip_v2.frame event and carries the source information | |||
| 857 | + | for all events within that frame. | |||
| 858 | + | ||||
| 859 | + | The source specifies how this event was generated. If the source is | |||
| 860 | + | zwp_tablet_pad_strip_v2.source.finger, a zwp_tablet_pad_strip_v2.stop event | |||
| 861 | + | will be sent when the user lifts their finger off the device. | |||
| 862 | + | ||||
| 863 | + | This event is optional. If the source is unknown for an interaction, | |||
| 864 | + | no event is sent. | |||
| 865 | + | </description> | |||
| 866 | + | <arg name="source" type="uint" enum="source" summary="the event source"/> | |||
| 867 | + | </event> | |||
| 868 | + | ||||
| 869 | + | <event name="position"> | |||
| 870 | + | <description summary="position changed"> | |||
| 871 | + | Sent whenever the position on a strip changes. | |||
| 872 | + | ||||
| 873 | + | The position is normalized to a range of [0, 65535], the 0-value | |||
| 874 | + | represents the top-most and/or left-most position of the strip in | |||
| 875 | + | the pad's current rotation. | |||
| 876 | + | </description> | |||
| 877 | + | <arg name="position" type="uint" summary="the current position"/> | |||
| 878 | + | </event> | |||
| 879 | + | ||||
| 880 | + | <event name="stop"> | |||
| 881 | + | <description summary="interaction stopped"> | |||
| 882 | + | Stop notification for strip events. | |||
| 883 | + | ||||
| 884 | + | For some zwp_tablet_pad_strip_v2.source types, a zwp_tablet_pad_strip_v2.stop | |||
| 885 | + | event is sent to notify a client that the interaction with the strip | |||
| 886 | + | has terminated. This enables the client to implement kinetic | |||
| 887 | + | scrolling. See the zwp_tablet_pad_strip_v2.source documentation for | |||
| 888 | + | information on when this event may be generated. | |||
| 889 | + | ||||
| 890 | + | Any zwp_tablet_pad_strip_v2.position events with the same source after this | |||
| 891 | + | event should be considered as the start of a new interaction. | |||
| 892 | + | </description> | |||
| 893 | + | </event> | |||
| 894 | + | ||||
| 895 | + | <event name="frame"> | |||
| 896 | + | <description summary="end of a strip event sequence"> | |||
| 897 | + | Indicates the end of a set of events that represent one logical | |||
| 898 | + | hardware strip event. A client is expected to accumulate the data | |||
| 899 | + | in all events within the frame before proceeding. | |||
| 900 | + | ||||
| 901 | + | All zwp_tablet_pad_strip_v2 events before a zwp_tablet_pad_strip_v2.frame event belong | |||
| 902 | + | logically together. For example, on termination of a finger interaction | |||
| 903 | + | on a strip the compositor will send a zwp_tablet_pad_strip_v2.source event, | |||
| 904 | + | a zwp_tablet_pad_strip_v2.stop event and a zwp_tablet_pad_strip_v2.frame | |||
| 905 | + | event. | |||
| 906 | + | ||||
| 907 | + | A zwp_tablet_pad_strip_v2.frame event is sent for every logical event | |||
| 908 | + | group, even if the group only contains a single zwp_tablet_pad_strip_v2 | |||
| 909 | + | event. Specifically, a client may get a sequence: position, frame, | |||
| 910 | + | position, frame, etc. | |||
| 911 | + | </description> | |||
| 912 | + | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |||
| 913 | + | </event> | |||
| 914 | + | </interface> | |||
| 915 | + | ||||
| 916 | + | <interface name="zwp_tablet_pad_group_v2" version="2"> | |||
| 917 | + | <description summary="a set of buttons, rings and strips"> | |||
| 918 | + | A pad group describes a distinct (sub)set of buttons, rings and strips | |||
| 919 | + | present in the tablet. The criteria of this grouping is usually positional, | |||
| 920 | + | eg. if a tablet has buttons on the left and right side, 2 groups will be | |||
| 921 | + | presented. The physical arrangement of groups is undisclosed and may | |||
| 922 | + | change on the fly. | |||
| 923 | + | ||||
| 924 | + | Pad groups will announce their features during pad initialization. Between | |||
| 925 | + | the corresponding zwp_tablet_pad_v2.group event and zwp_tablet_pad_group_v2.done, the | |||
| 926 | + | pad group will announce the buttons, rings and strips contained in it, | |||
| 927 | + | plus the number of supported modes. | |||
| 928 | + | ||||
| 929 | + | Modes are a mechanism to allow multiple groups of actions for every element | |||
| 930 | + | in the pad group. The number of groups and available modes in each is | |||
| 931 | + | persistent across device plugs. The current mode is user-switchable, it | |||
| 932 | + | will be announced through the zwp_tablet_pad_group_v2.mode_switch event both | |||
| 933 | + | whenever it is switched, and after zwp_tablet_pad_v2.enter. | |||
| 934 | + | ||||
| 935 | + | The current mode logically applies to all elements in the pad group, | |||
| 936 | + | although it is at clients' discretion whether to actually perform different | |||
| 937 | + | actions, and/or issue the respective .set_feedback requests to notify the | |||
| 938 | + | compositor. See the zwp_tablet_pad_group_v2.mode_switch event for more details. | |||
| 939 | + | </description> | |||
| 940 | + | ||||
| 941 | + | <request name="destroy" type="destructor"> | |||
| 942 | + | <description summary="destroy the pad object"> | |||
| 943 | + | Destroy the zwp_tablet_pad_group_v2 object. Objects created from this object | |||
| 944 | + | are unaffected and should be destroyed separately. | |||
| 945 | + | </description> | |||
| 946 | + | </request> | |||
| 947 | + | ||||
| 948 | + | <event name="buttons"> | |||
| 949 | + | <description summary="buttons announced"> | |||
| 950 | + | Sent on zwp_tablet_pad_group_v2 initialization to announce the available | |||
| 951 | + | buttons in the group. Button indices start at 0, a button may only be | |||
| 952 | + | in one group at a time. | |||
| 953 | + | ||||
| 954 | + | This event is first sent in the initial burst of events before the | |||
| 955 | + | zwp_tablet_pad_group_v2.done event. | |||
| 956 | + | ||||
| 957 | + | Some buttons are reserved by the compositor. These buttons may not be | |||
| 958 | + | assigned to any zwp_tablet_pad_group_v2. Compositors may broadcast this | |||
| 959 | + | event in the case of changes to the mapping of these reserved buttons. | |||
| 960 | + | If the compositor happens to reserve all buttons in a group, this event | |||
| 961 | + | will be sent with an empty array. | |||
| 962 | + | </description> | |||
| 963 | + | <arg name="buttons" type="array" summary="buttons in this group"/> | |||
| 964 | + | </event> | |||
| 965 | + | ||||
| 966 | + | <event name="ring"> | |||
| 967 | + | <description summary="ring announced"> | |||
| 968 | + | Sent on zwp_tablet_pad_group_v2 initialization to announce available rings. | |||
| 969 | + | One event is sent for each ring available on this pad group. | |||
| 970 | + | ||||
| 971 | + | This event is sent in the initial burst of events before the | |||
| 972 | + | zwp_tablet_pad_group_v2.done event. | |||
| 973 | + | </description> | |||
| 974 | + | <arg name="ring" type="new_id" interface="zwp_tablet_pad_ring_v2"/> | |||
| 975 | + | </event> | |||
| 976 | + | ||||
| 977 | + | <event name="strip"> | |||
| 978 | + | <description summary="strip announced"> | |||
| 979 | + | Sent on zwp_tablet_pad_v2 initialization to announce available strips. | |||
| 980 | + | One event is sent for each strip available on this pad group. | |||
| 981 | + | ||||
| 982 | + | This event is sent in the initial burst of events before the | |||
| 983 | + | zwp_tablet_pad_group_v2.done event. | |||
| 984 | + | </description> | |||
| 985 | + | <arg name="strip" type="new_id" interface="zwp_tablet_pad_strip_v2"/> | |||
| 986 | + | </event> | |||
| 987 | + | ||||
| 988 | + | <event name="modes"> | |||
| 989 | + | <description summary="mode-switch ability announced"> | |||
| 990 | + | Sent on zwp_tablet_pad_group_v2 initialization to announce that the pad | |||
| 991 | + | group may switch between modes. A client may use a mode to store a | |||
| 992 | + | specific configuration for buttons, rings and strips and use the | |||
| 993 | + | zwp_tablet_pad_group_v2.mode_switch event to toggle between these | |||
| 994 | + | configurations. Mode indices start at 0. | |||
| 995 | + | ||||
| 996 | + | Switching modes is compositor-dependent. See the | |||
| 997 | + | zwp_tablet_pad_group_v2.mode_switch event for more details. | |||
| 998 | + | ||||
| 999 | + | This event is sent in the initial burst of events before the | |||
| 1000 | + | zwp_tablet_pad_group_v2.done event. This event is only sent when | |||
| 1001 | + | more than one mode is available. | |||
| 1002 | + | </description> | |||
| 1003 | + | <arg name="modes" type="uint" summary="the number of modes"/> | |||
| 1004 | + | </event> | |||
| 1005 | + | ||||
| 1006 | + | <event name="done"> | |||
| 1007 | + | <description summary="tablet group description events sequence complete"> | |||
| 1008 | + | This event is sent immediately to signal the end of the initial | |||
| 1009 | + | burst of descriptive events. A client may consider the static | |||
| 1010 | + | description of the tablet to be complete and finalize initialization | |||
| 1011 | + | of the tablet group. | |||
| 1012 | + | </description> | |||
| 1013 | + | </event> | |||
| 1014 | + | ||||
| 1015 | + | <event name="mode_switch"> | |||
| 1016 | + | <description summary="mode switch event"> | |||
| 1017 | + | Notification that the mode was switched. | |||
| 1018 | + | ||||
| 1019 | + | A mode applies to all buttons, rings, strips and dials in a group | |||
| 1020 | + | simultaneously, but a client is not required to assign different actions | |||
| 1021 | + | for each mode. For example, a client may have mode-specific button | |||
| 1022 | + | mappings but map the ring to vertical scrolling in all modes. Mode | |||
| 1023 | + | indices start at 0. | |||
| 1024 | + | ||||
| 1025 | + | Switching modes is compositor-dependent. The compositor may provide | |||
| 1026 | + | visual cues to the user about the mode, e.g. by toggling LEDs on | |||
| 1027 | + | the tablet device. Mode-switching may be software-controlled or | |||
| 1028 | + | controlled by one or more physical buttons. For example, on a Wacom | |||
| 1029 | + | Intuos Pro, the button inside the ring may be assigned to switch | |||
| 1030 | + | between modes. | |||
| 1031 | + | ||||
| 1032 | + | The compositor will also send this event after zwp_tablet_pad_v2.enter on | |||
| 1033 | + | each group in order to notify of the current mode. Groups that only | |||
| 1034 | + | feature one mode will use mode=0 when emitting this event. | |||
| 1035 | + | ||||
| 1036 | + | If a button action in the new mode differs from the action in the | |||
| 1037 | + | previous mode, the client should immediately issue a | |||
| 1038 | + | zwp_tablet_pad_v2.set_feedback request for each changed button. | |||
| 1039 | + | ||||
| 1040 | + | If a ring, strip or dial action in the new mode differs from the action | |||
| 1041 | + | in the previous mode, the client should immediately issue a | |||
| 1042 | + | zwp_tablet_ring_v2.set_feedback, zwp_tablet_strip_v2.set_feedback or | |||
| 1043 | + | zwp_tablet_dial_v2.set_feedback request for each changed ring, strip or dial. | |||
| 1044 | + | </description> | |||
| 1045 | + | <arg name="time" type="uint" summary="the time of the event with millisecond granularity"/> | |||
| 1046 | + | <arg name="serial" type="uint"/> | |||
| 1047 | + | <arg name="mode" type="uint" summary="the new mode of the pad"/> | |||
| 1048 | + | </event> | |||
| 1049 | + | ||||
| 1050 | + | <!-- Version 2 additions --> | |||
| 1051 | + | ||||
| 1052 | + | <event name="dial" since="2"> | |||
| 1053 | + | <description summary="dial announced"> | |||
| 1054 | + | Sent on zwp_tablet_pad_v2 initialization to announce available dials. | |||
| 1055 | + | One event is sent for each dial available on this pad group. | |||
| 1056 | + | ||||
| 1057 | + | This event is sent in the initial burst of events before the | |||
| 1058 | + | zwp_tablet_pad_group_v2.done event. | |||
| 1059 | + | </description> | |||
| 1060 | + | <arg name="dial" type="new_id" interface="zwp_tablet_pad_dial_v2"/> | |||
| 1061 | + | </event> | |||
| 1062 | + | </interface> | |||
| 1063 | + | ||||
| 1064 | + | <interface name="zwp_tablet_pad_v2" version="2"> | |||
| 1065 | + | <description summary="a set of buttons, rings, strips and dials"> | |||
| 1066 | + | A pad device is a set of buttons, rings, strips and dials | |||
| 1067 | + | usually physically present on the tablet device itself. Some | |||
| 1068 | + | exceptions exist where the pad device is physically detached, e.g. the | |||
| 1069 | + | Wacom ExpressKey Remote. | |||
| 1070 | + | ||||
| 1071 | + | Pad devices have no axes that control the cursor and are generally | |||
| 1072 | + | auxiliary devices to the tool devices used on the tablet surface. | |||
| 1073 | + | ||||
| 1074 | + | A pad device has a number of static characteristics, e.g. the number | |||
| 1075 | + | of rings. These capabilities are sent in an event sequence after the | |||
| 1076 | + | zwp_tablet_seat_v2.pad_added event before any actual events from this pad. | |||
| 1077 | + | This initial event sequence is terminated by a zwp_tablet_pad_v2.done | |||
| 1078 | + | event. | |||
| 1079 | + | ||||
| 1080 | + | All pad features (buttons, rings, strips and dials) are logically divided into | |||
| 1081 | + | groups and all pads have at least one group. The available groups are | |||
| 1082 | + | notified through the zwp_tablet_pad_v2.group event; the compositor will | |||
| 1083 | + | emit one event per group before emitting zwp_tablet_pad_v2.done. | |||
| 1084 | + | ||||
| 1085 | + | Groups may have multiple modes. Modes allow clients to map multiple | |||
| 1086 | + | actions to a single pad feature. Only one mode can be active per group, | |||
| 1087 | + | although different groups may have different active modes. | |||
| 1088 | + | </description> | |||
| 1089 | + | ||||
| 1090 | + | <request name="set_feedback"> | |||
| 1091 | + | <description summary="set compositor feedback"> | |||
| 1092 | + | Requests the compositor to use the provided feedback string | |||
| 1093 | + | associated with this button. This request should be issued immediately | |||
| 1094 | + | after a zwp_tablet_pad_group_v2.mode_switch event from the corresponding | |||
| 1095 | + | group is received, or whenever a button is mapped to a different | |||
| 1096 | + | action. See zwp_tablet_pad_group_v2.mode_switch for more details. | |||
| 1097 | + | ||||
| 1098 | + | Clients are encouraged to provide context-aware descriptions for | |||
| 1099 | + | the actions associated with each button, and compositors may use | |||
| 1100 | + | this information to offer visual feedback on the button layout | |||
| 1101 | + | (e.g. on-screen displays). | |||
| 1102 | + | ||||
| 1103 | + | Button indices start at 0. Setting the feedback string on a button | |||
| 1104 | + | that is reserved by the compositor (i.e. not belonging to any | |||
| 1105 | + | zwp_tablet_pad_group_v2) does not generate an error but the compositor | |||
| 1106 | + | is free to ignore the request. | |||
| 1107 | + | ||||
| 1108 | + | The provided string 'description' is a UTF-8 encoded string to be | |||
| 1109 | + | associated with this ring, and is considered user-visible; general | |||
| 1110 | + | internationalization rules apply. | |||
| 1111 | + | ||||
| 1112 | + | The serial argument will be that of the last | |||
| 1113 | + | zwp_tablet_pad_group_v2.mode_switch event received for the group of this | |||
| 1114 | + | button. Requests providing other serials than the most recent one will | |||
| 1115 | + | be ignored. | |||
| 1116 | + | </description> | |||
| 1117 | + | <arg name="button" type="uint" summary="button index"/> | |||
| 1118 | + | <arg name="description" type="string" summary="button description"/> | |||
| 1119 | + | <arg name="serial" type="uint" summary="serial of the mode switch event"/> | |||
| 1120 | + | </request> | |||
| 1121 | + | ||||
| 1122 | + | <request name="destroy" type="destructor"> | |||
| 1123 | + | <description summary="destroy the pad object"> | |||
| 1124 | + | Destroy the zwp_tablet_pad_v2 object. Objects created from this object | |||
| 1125 | + | are unaffected and should be destroyed separately. | |||
| 1126 | + | </description> | |||
| 1127 | + | </request> | |||
| 1128 | + | ||||
| 1129 | + | <event name="group"> | |||
| 1130 | + | <description summary="group announced"> | |||
| 1131 | + | Sent on zwp_tablet_pad_v2 initialization to announce available groups. | |||
| 1132 | + | One event is sent for each pad group available. | |||
| 1133 | + | ||||
| 1134 | + | This event is sent in the initial burst of events before the | |||
| 1135 | + | zwp_tablet_pad_v2.done event. At least one group will be announced. | |||
| 1136 | + | </description> | |||
| 1137 | + | <arg name="pad_group" type="new_id" interface="zwp_tablet_pad_group_v2"/> | |||
| 1138 | + | </event> | |||
| 1139 | + | ||||
| 1140 | + | <event name="path"> | |||
| 1141 | + | <description summary="path to the device"> | |||
| 1142 | + | A system-specific device path that indicates which device is behind | |||
| 1143 | + | this zwp_tablet_pad_v2. This information may be used to gather additional | |||
| 1144 | + | information about the device, e.g. through libwacom. | |||
| 1145 | + | ||||
| 1146 | + | The format of the path is unspecified, it may be a device node, a | |||
| 1147 | + | sysfs path, or some other identifier. It is up to the client to | |||
| 1148 | + | identify the string provided. | |||
| 1149 | + | ||||
| 1150 | + | This event is sent in the initial burst of events before the | |||
| 1151 | + | zwp_tablet_pad_v2.done event. | |||
| 1152 | + | </description> | |||
| 1153 | + | <arg name="path" type="string" summary="path to local device"/> | |||
| 1154 | + | </event> | |||
| 1155 | + | ||||
| 1156 | + | <event name="buttons"> | |||
| 1157 | + | <description summary="buttons announced"> | |||
| 1158 | + | Sent on zwp_tablet_pad_v2 initialization to announce the available | |||
| 1159 | + | buttons. | |||
| 1160 | + | ||||
| 1161 | + | This event is sent in the initial burst of events before the | |||
| 1162 | + | zwp_tablet_pad_v2.done event. This event is only sent when at least one | |||
| 1163 | + | button is available. | |||
| 1164 | + | </description> | |||
| 1165 | + | <arg name="buttons" type="uint" summary="the number of buttons"/> | |||
| 1166 | + | </event> | |||
| 1167 | + | ||||
| 1168 | + | <event name="done"> | |||
| 1169 | + | <description summary="pad description event sequence complete"> | |||
| 1170 | + | This event signals the end of the initial burst of descriptive | |||
| 1171 | + | events. A client may consider the static description of the pad to | |||
| 1172 | + | be complete and finalize initialization of the pad. | |||
| 1173 | + | </description> | |||
| 1174 | + | </event> | |||
| 1175 | + | ||||
| 1176 | + | <enum name="button_state"> | |||
| 1177 | + | <description summary="physical button state"> | |||
| 1178 | + | Describes the physical state of a button that caused the button | |||
| 1179 | + | event. | |||
| 1180 | + | </description> | |||
| 1181 | + | <entry name="released" value="0" summary="the button is not pressed"/> | |||
| 1182 | + | <entry name="pressed" value="1" summary="the button is pressed"/> | |||
| 1183 | + | </enum> | |||
| 1184 | + | ||||
| 1185 | + | <event name="button"> | |||
| 1186 | + | <description summary="physical button state"> | |||
| 1187 | + | Sent whenever the physical state of a button changes. | |||
| 1188 | + | </description> | |||
| 1189 | + | <arg name="time" type="uint" summary="the time of the event with millisecond granularity"/> | |||
| 1190 | + | <arg name="button" type="uint" summary="the index of the button that changed state"/> | |||
| 1191 | + | <arg name="state" type="uint" enum="button_state"/> | |||
| 1192 | + | </event> | |||
| 1193 | + | ||||
| 1194 | + | <event name="enter"> | |||
| 1195 | + | <description summary="enter event"> | |||
| 1196 | + | Notification that this pad is focused on the specified surface. | |||
| 1197 | + | </description> | |||
| 1198 | + | <arg name="serial" type="uint" summary="serial number of the enter event"/> | |||
| 1199 | + | <arg name="tablet" type="object" interface="zwp_tablet_v2" summary="the tablet the pad is attached to"/> | |||
| 1200 | + | <arg name="surface" type="object" interface="wl_surface" summary="surface the pad is focused on"/> | |||
| 1201 | + | </event> | |||
| 1202 | + | ||||
| 1203 | + | <event name="leave"> | |||
| 1204 | + | <description summary="leave event"> | |||
| 1205 | + | Notification that this pad is no longer focused on the specified | |||
| 1206 | + | surface. | |||
| 1207 | + | </description> | |||
| 1208 | + | <arg name="serial" type="uint" summary="serial number of the leave event"/> | |||
| 1209 | + | <arg name="surface" type="object" interface="wl_surface" summary="surface the pad is no longer focused on"/> | |||
| 1210 | + | </event> | |||
| 1211 | + | ||||
| 1212 | + | <event name="removed"> | |||
| 1213 | + | <description summary="pad removed event"> | |||
| 1214 | + | Sent when the pad has been removed from the system. When a tablet | |||
| 1215 | + | is removed its pad(s) will be removed too. | |||
| 1216 | + | ||||
| 1217 | + | When this event is received, the client must destroy all rings, strips | |||
| 1218 | + | and groups that were offered by this pad, and issue zwp_tablet_pad_v2.destroy | |||
| 1219 | + | the pad itself. | |||
| 1220 | + | </description> | |||
| 1221 | + | </event> | |||
| 1222 | + | </interface> | |||
| 1223 | + | ||||
| 1224 | + | <interface name="zwp_tablet_pad_dial_v2" version="2"> | |||
| 1225 | + | <description summary="pad dial"> | |||
| 1226 | + | A rotary control, e.g. a dial or a wheel. | |||
| 1227 | + | ||||
| 1228 | + | Events on a dial are logically grouped by the zwp_tablet_pad_dial_v2.frame | |||
| 1229 | + | event. | |||
| 1230 | + | </description> | |||
| 1231 | + | ||||
| 1232 | + | <request name="set_feedback"> | |||
| 1233 | + | <description summary="set compositor feedback"> | |||
| 1234 | + | Requests the compositor to use the provided feedback string | |||
| 1235 | + | associated with this dial. This request should be issued immediately | |||
| 1236 | + | after a zwp_tablet_pad_group_v2.mode_switch event from the corresponding | |||
| 1237 | + | group is received, or whenever the dial is mapped to a different | |||
| 1238 | + | action. See zwp_tablet_pad_group_v2.mode_switch for more details. | |||
| 1239 | + | ||||
| 1240 | + | Clients are encouraged to provide context-aware descriptions for | |||
| 1241 | + | the actions associated with the dial, and compositors may use this | |||
| 1242 | + | information to offer visual feedback about the button layout | |||
| 1243 | + | (eg. on-screen displays). | |||
| 1244 | + | ||||
| 1245 | + | The provided string 'description' is a UTF-8 encoded string to be | |||
| 1246 | + | associated with this ring, and is considered user-visible; general | |||
| 1247 | + | internationalization rules apply. | |||
| 1248 | + | ||||
| 1249 | + | The serial argument will be that of the last | |||
| 1250 | + | zwp_tablet_pad_group_v2.mode_switch event received for the group of this | |||
| 1251 | + | dial. Requests providing other serials than the most recent one will be | |||
| 1252 | + | ignored. | |||
| 1253 | + | </description> | |||
| 1254 | + | <arg name="description" type="string" summary="dial description"/> | |||
| 1255 | + | <arg name="serial" type="uint" summary="serial of the mode switch event"/> | |||
| 1256 | + | </request> | |||
| 1257 | + | ||||
| 1258 | + | <request name="destroy" type="destructor"> | |||
| 1259 | + | <description summary="destroy the dial object"> | |||
| 1260 | + | This destroys the client's resource for this dial object. | |||
| 1261 | + | </description> | |||
| 1262 | + | </request> | |||
| 1263 | + | ||||
| 1264 | + | <event name="delta"> | |||
| 1265 | + | <description summary="delta movement"> | |||
| 1266 | + | Sent whenever the position on a dial changes. | |||
| 1267 | + | ||||
| 1268 | + | This event carries the wheel delta as multiples or fractions | |||
| 1269 | + | of 120 with each multiple of 120 representing one logical wheel detent. | |||
| 1270 | + | For example, an axis_value120 of 30 is one quarter of | |||
| 1271 | + | a logical wheel step in the positive direction, a value120 of | |||
| 1272 | + | -240 are two logical wheel steps in the negative direction within the | |||
| 1273 | + | same hardware event. See the wl_pointer.axis_value120 for more details. | |||
| 1274 | + | ||||
| 1275 | + | The value120 must not be zero. | |||
| 1276 | + | </description> | |||
| 1277 | + | <arg name="value120" type="int" summary="rotation distance as fraction of 120"/> | |||
| 1278 | + | </event> | |||
| 1279 | + | ||||
| 1280 | + | <event name="frame"> | |||
| 1281 | + | <description summary="end of a dial event sequence"> | |||
| 1282 | + | Indicates the end of a set of events that represent one logical | |||
| 1283 | + | hardware dial event. A client is expected to accumulate the data | |||
| 1284 | + | in all events within the frame before proceeding. | |||
| 1285 | + | ||||
| 1286 | + | All zwp_tablet_pad_dial_v2 events before a zwp_tablet_pad_dial_v2.frame event belong | |||
| 1287 | + | logically together. | |||
| 1288 | + | ||||
| 1289 | + | A zwp_tablet_pad_dial_v2.frame event is sent for every logical event | |||
| 1290 | + | group, even if the group only contains a single zwp_tablet_pad_dial_v2 | |||
| 1291 | + | event. Specifically, a client may get a sequence: delta, frame, | |||
| 1292 | + | delta, frame, etc. | |||
| 1293 | + | </description> | |||
| 1294 | + | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |||
| 1295 | + | </event> | |||
| 1296 | + | </interface> | |||
| 1297 | + | </protocol> | |||
A spec/xml/tearingcontrol.xml +123 -0
| @@ -0,0 +1,123 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="tearing_control_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2021 Xaver Hugl | |||
| 5 | + | ||||
| 6 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 7 | + | copy of this software and associated documentation files (the "Software"), | |||
| 8 | + | to deal in the Software without restriction, including without limitation | |||
| 9 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 10 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 11 | + | Software is furnished to do so, subject to the following conditions: | |||
| 12 | + | ||||
| 13 | + | The above copyright notice and this permission notice (including the next | |||
| 14 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 15 | + | Software. | |||
| 16 | + | ||||
| 17 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 18 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 19 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 20 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 21 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 22 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 23 | + | DEALINGS IN THE SOFTWARE. | |||
| 24 | + | </copyright> | |||
| 25 | + | ||||
| 26 | + | <interface name="wp_tearing_control_manager_v1" version="1"> | |||
| 27 | + | <description summary="protocol for tearing control"> | |||
| 28 | + | For some use cases like games or drawing tablets it can make sense to | |||
| 29 | + | reduce latency by accepting tearing with the use of asynchronous page | |||
| 30 | + | flips. This global is a factory interface, allowing clients to inform | |||
| 31 | + | which type of presentation the content of their surfaces is suitable for. | |||
| 32 | + | ||||
| 33 | + | Graphics APIs like EGL or Vulkan, that manage the buffer queue and commits | |||
| 34 | + | of a wl_surface themselves, are likely to be using this extension | |||
| 35 | + | internally. If a client is using such an API for a wl_surface, it should | |||
| 36 | + | not directly use this extension on that surface, to avoid raising a | |||
| 37 | + | tearing_control_exists protocol error. | |||
| 38 | + | ||||
| 39 | + | Warning! The protocol described in this file is currently in the testing | |||
| 40 | + | phase. Backward compatible changes may be added together with the | |||
| 41 | + | corresponding interface version bump. Backward incompatible changes can | |||
| 42 | + | only be done by creating a new major version of the extension. | |||
| 43 | + | </description> | |||
| 44 | + | ||||
| 45 | + | <request name="destroy" type="destructor"> | |||
| 46 | + | <description summary="destroy tearing control factory object"> | |||
| 47 | + | Destroy this tearing control factory object. Other objects, including | |||
| 48 | + | wp_tearing_control_v1 objects created by this factory, are not affected | |||
| 49 | + | by this request. | |||
| 50 | + | </description> | |||
| 51 | + | </request> | |||
| 52 | + | ||||
| 53 | + | <enum name="error"> | |||
| 54 | + | <entry name="tearing_control_exists" value="0" | |||
| 55 | + | summary="the surface already has a tearing object associated"/> | |||
| 56 | + | </enum> | |||
| 57 | + | ||||
| 58 | + | <request name="get_tearing_control"> | |||
| 59 | + | <description summary="extend surface interface for tearing control"> | |||
| 60 | + | Instantiate an interface extension for the given wl_surface to request | |||
| 61 | + | asynchronous page flips for presentation. | |||
| 62 | + | ||||
| 63 | + | If the given wl_surface already has a wp_tearing_control_v1 object | |||
| 64 | + | associated, the tearing_control_exists protocol error is raised. | |||
| 65 | + | </description> | |||
| 66 | + | <arg name="id" type="new_id" interface="wp_tearing_control_v1"/> | |||
| 67 | + | <arg name="surface" type="object" interface="wl_surface"/> | |||
| 68 | + | </request> | |||
| 69 | + | </interface> | |||
| 70 | + | ||||
| 71 | + | <interface name="wp_tearing_control_v1" version="1"> | |||
| 72 | + | <description summary="per-surface tearing control interface"> | |||
| 73 | + | An additional interface to a wl_surface object, which allows the client | |||
| 74 | + | to hint to the compositor if the content on the surface is suitable for | |||
| 75 | + | presentation with tearing. | |||
| 76 | + | The default presentation hint is vsync. See presentation_hint for more | |||
| 77 | + | details. | |||
| 78 | + | ||||
| 79 | + | If the associated wl_surface is destroyed, this object becomes inert and | |||
| 80 | + | should be destroyed. | |||
| 81 | + | </description> | |||
| 82 | + | ||||
| 83 | + | <enum name="presentation_hint"> | |||
| 84 | + | <description summary="presentation hint values"> | |||
| 85 | + | This enum provides information for if submitted frames from the client | |||
| 86 | + | may be presented with tearing. | |||
| 87 | + | </description> | |||
| 88 | + | <entry name="vsync" value="0"> | |||
| 89 | + | <description summary="tearing-free presentation"> | |||
| 90 | + | The content of this surface is meant to be synchronized to the | |||
| 91 | + | vertical blanking period. This should not result in visible tearing | |||
| 92 | + | and may result in a delay before a surface commit is presented. | |||
| 93 | + | </description> | |||
| 94 | + | </entry> | |||
| 95 | + | <entry name="async" value="1"> | |||
| 96 | + | <description summary="asynchronous presentation"> | |||
| 97 | + | The content of this surface is meant to be presented with minimal | |||
| 98 | + | latency and tearing is acceptable. | |||
| 99 | + | </description> | |||
| 100 | + | </entry> | |||
| 101 | + | </enum> | |||
| 102 | + | ||||
| 103 | + | <request name="set_presentation_hint"> | |||
| 104 | + | <description summary="set presentation hint"> | |||
| 105 | + | Set the presentation hint for the associated wl_surface. This state is | |||
| 106 | + | double-buffered, see wl_surface.commit. | |||
| 107 | + | ||||
| 108 | + | The compositor is free to dynamically respect or ignore this hint based | |||
| 109 | + | on various conditions like hardware capabilities, surface state and | |||
| 110 | + | user preferences. | |||
| 111 | + | </description> | |||
| 112 | + | <arg name="hint" type="uint" enum="presentation_hint"/> | |||
| 113 | + | </request> | |||
| 114 | + | ||||
| 115 | + | <request name="destroy" type="destructor"> | |||
| 116 | + | <description summary="destroy tearing control object"> | |||
| 117 | + | Destroy this surface tearing object and revert the presentation hint to | |||
| 118 | + | vsync. The change will be applied on the next wl_surface.commit. | |||
| 119 | + | </description> | |||
| 120 | + | </request> | |||
| 121 | + | </interface> | |||
| 122 | + | ||||
| 123 | + | </protocol> | |||
A spec/xml/textinput.xml +604 -0
| @@ -0,0 +1,604 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | ||||
| 3 | + | <protocol name="text_input_unstable_v3"> | |||
| 4 | + | <copyright> | |||
| 5 | + | Copyright © 2012, 2013 Intel Corporation | |||
| 6 | + | Copyright © 2015, 2016 Jan Arne Petersen | |||
| 7 | + | Copyright © 2017, 2018 Red Hat, Inc. | |||
| 8 | + | Copyright © 2018 Purism SPC | |||
| 9 | + | ||||
| 10 | + | Permission to use, copy, modify, distribute, and sell this | |||
| 11 | + | software and its documentation for any purpose is hereby granted | |||
| 12 | + | without fee, provided that the above copyright notice appear in | |||
| 13 | + | all copies and that both that copyright notice and this permission | |||
| 14 | + | notice appear in supporting documentation, and that the name of | |||
| 15 | + | the copyright holders not be used in advertising or publicity | |||
| 16 | + | pertaining to distribution of the software without specific, | |||
| 17 | + | written prior permission. The copyright holders make no | |||
| 18 | + | representations about the suitability of this software for any | |||
| 19 | + | purpose. It is provided "as is" without express or implied | |||
| 20 | + | warranty. | |||
| 21 | + | ||||
| 22 | + | THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | |||
| 23 | + | SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||
| 24 | + | FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | |||
| 25 | + | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||
| 26 | + | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | |||
| 27 | + | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |||
| 28 | + | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |||
| 29 | + | THIS SOFTWARE. | |||
| 30 | + | </copyright> | |||
| 31 | + | ||||
| 32 | + | <description summary="Protocol for composing text"> | |||
| 33 | + | This protocol allows compositors to act as input methods and to send text | |||
| 34 | + | to applications. A text input object is used to manage state of what are | |||
| 35 | + | typically text entry fields in the application. | |||
| 36 | + | ||||
| 37 | + | This document adheres to the RFC 2119 when using words like "must", | |||
| 38 | + | "should", "may", etc. | |||
| 39 | + | ||||
| 40 | + | Warning! The protocol described in this file is experimental and | |||
| 41 | + | backward incompatible changes may be made. Backward compatible changes | |||
| 42 | + | may be added together with the corresponding interface version bump. | |||
| 43 | + | Backward incompatible changes are done by bumping the version number in | |||
| 44 | + | the protocol and interface names and resetting the interface version. | |||
| 45 | + | Once the protocol is to be declared stable, the 'z' prefix and the | |||
| 46 | + | version number in the protocol and interface names are removed and the | |||
| 47 | + | interface version number is reset. | |||
| 48 | + | </description> | |||
| 49 | + | ||||
| 50 | + | <interface name="zwp_text_input_v3" version="2"> | |||
| 51 | + | <description summary="text input"> | |||
| 52 | + | The zwp_text_input_v3 interface represents text input and input methods | |||
| 53 | + | associated with a seat. It provides enter/leave events to follow the | |||
| 54 | + | text input focus for a seat. | |||
| 55 | + | ||||
| 56 | + | Requests are used to enable/disable the text-input object and set | |||
| 57 | + | state information like surrounding and selected text or the content type. | |||
| 58 | + | The information about the entered text is sent to the text-input object | |||
| 59 | + | via the preedit_string and commit_string events. | |||
| 60 | + | ||||
| 61 | + | Text is valid UTF-8 encoded, indices and lengths are in bytes. Indices | |||
| 62 | + | must not point to middle bytes inside a code point: they must either | |||
| 63 | + | point to the first byte of a code point or to the end of the buffer. | |||
| 64 | + | Lengths must be measured between two valid indices. | |||
| 65 | + | ||||
| 66 | + | Focus moving throughout surfaces will result in the emission of | |||
| 67 | + | zwp_text_input_v3.enter and zwp_text_input_v3.leave events. The focused | |||
| 68 | + | surface must commit zwp_text_input_v3.enable and | |||
| 69 | + | zwp_text_input_v3.disable requests as the keyboard focus moves across | |||
| 70 | + | editable and non-editable elements of the UI. Those two requests are not | |||
| 71 | + | expected to be paired with each other, the compositor must be able to | |||
| 72 | + | handle consecutive series of the same request. | |||
| 73 | + | ||||
| 74 | + | State is sent by the state requests (set_surrounding_text, | |||
| 75 | + | set_content_type and set_cursor_rectangle) and a commit request. After an | |||
| 76 | + | enter event or disable request all state information is invalidated and | |||
| 77 | + | needs to be resent by the client. | |||
| 78 | + | </description> | |||
| 79 | + | ||||
| 80 | + | <request name="destroy" type="destructor"> | |||
| 81 | + | <description summary="Destroy the wp_text_input"> | |||
| 82 | + | Destroy the wp_text_input object. Also disables all surfaces enabled | |||
| 83 | + | through this wp_text_input object. | |||
| 84 | + | </description> | |||
| 85 | + | </request> | |||
| 86 | + | ||||
| 87 | + | <request name="enable"> | |||
| 88 | + | <description summary="Request text input to be enabled"> | |||
| 89 | + | Requests text input on the surface previously obtained from the enter | |||
| 90 | + | event. | |||
| 91 | + | ||||
| 92 | + | This request must be issued every time the focused text input changes | |||
| 93 | + | to a new one, including within the current surface. Use | |||
| 94 | + | zwp_text_input_v3.disable when there is no longer any input focus on | |||
| 95 | + | the current surface. | |||
| 96 | + | ||||
| 97 | + | Clients must not enable more than one text input on the single seat | |||
| 98 | + | and should disable the current text input before enabling the new one. | |||
| 99 | + | Requests to enable a text input when another text input is enabled | |||
| 100 | + | on the same seat must be ignored by compositor. | |||
| 101 | + | ||||
| 102 | + | This request resets all state associated with previous enable, disable, | |||
| 103 | + | set_surrounding_text, set_text_change_cause, set_content_type, and | |||
| 104 | + | set_cursor_rectangle requests, as well as the state associated with | |||
| 105 | + | preedit_string, commit_string, and delete_surrounding_text events. | |||
| 106 | + | ||||
| 107 | + | The set_surrounding_text, set_content_type and set_cursor_rectangle | |||
| 108 | + | requests must follow if the text input supports the necessary | |||
| 109 | + | functionality. | |||
| 110 | + | ||||
| 111 | + | State set with this request is double-buffered. It will get applied on | |||
| 112 | + | the next zwp_text_input_v3.commit request, and stay valid until the | |||
| 113 | + | next committed enable or disable request. | |||
| 114 | + | ||||
| 115 | + | The changes must be applied by the compositor after issuing a | |||
| 116 | + | zwp_text_input_v3.commit request. | |||
| 117 | + | </description> | |||
| 118 | + | </request> | |||
| 119 | + | ||||
| 120 | + | <request name="disable"> | |||
| 121 | + | <description summary="Disable text input on a surface"> | |||
| 122 | + | Explicitly disable text input on the current surface (typically when | |||
| 123 | + | there is no focus on any text entry inside the surface). | |||
| 124 | + | ||||
| 125 | + | State set with this request is double-buffered. It will get applied on | |||
| 126 | + | the next zwp_text_input_v3.commit request. | |||
| 127 | + | </description> | |||
| 128 | + | </request> | |||
| 129 | + | ||||
| 130 | + | <request name="set_surrounding_text"> | |||
| 131 | + | <description summary="sets the surrounding text"> | |||
| 132 | + | Sets the surrounding plain text around the input, excluding the preedit | |||
| 133 | + | text. | |||
| 134 | + | ||||
| 135 | + | The client should notify the compositor of any changes in any of the | |||
| 136 | + | values carried with this request, including changes caused by handling | |||
| 137 | + | incoming text-input events as well as changes caused by other | |||
| 138 | + | mechanisms like keyboard typing. | |||
| 139 | + | ||||
| 140 | + | If the client is unaware of the text around the cursor, it should not | |||
| 141 | + | issue this request, to signify lack of support to the compositor. | |||
| 142 | + | ||||
| 143 | + | Text is UTF-8 encoded, and should include the cursor position, the | |||
| 144 | + | complete selection and additional characters before and after them. | |||
| 145 | + | There is a maximum length of wayland messages, so text can not be | |||
| 146 | + | longer than 4000 bytes. | |||
| 147 | + | ||||
| 148 | + | Cursor is the byte offset of the cursor within text buffer. | |||
| 149 | + | ||||
| 150 | + | Anchor is the byte offset of the selection anchor within text buffer. | |||
| 151 | + | If there is no selected text, anchor is the same as cursor. | |||
| 152 | + | ||||
| 153 | + | If any preedit text is present, it is replaced with a cursor for the | |||
| 154 | + | purpose of this event. | |||
| 155 | + | ||||
| 156 | + | Values set with this request are double-buffered. They will get applied | |||
| 157 | + | on the next zwp_text_input_v3.commit request, and stay valid until the | |||
| 158 | + | next committed enable or disable request. | |||
| 159 | + | ||||
| 160 | + | The initial state for affected fields is empty, meaning that the text | |||
| 161 | + | input does not support sending surrounding text. If the empty values | |||
| 162 | + | get applied, subsequent attempts to change them may have no effect. | |||
| 163 | + | </description> | |||
| 164 | + | <arg name="text" type="string"/> | |||
| 165 | + | <arg name="cursor" type="int"/> | |||
| 166 | + | <arg name="anchor" type="int"/> | |||
| 167 | + | </request> | |||
| 168 | + | ||||
| 169 | + | <enum name="change_cause"> | |||
| 170 | + | <description summary="text change reason"> | |||
| 171 | + | Reason for the change of surrounding text or cursor posision. | |||
| 172 | + | </description> | |||
| 173 | + | <entry name="input_method" value="0" summary="input method caused the change"/> | |||
| 174 | + | <entry name="other" value="1" summary="something else than the input method caused the change"/> | |||
| 175 | + | </enum> | |||
| 176 | + | ||||
| 177 | + | <request name="set_text_change_cause"> | |||
| 178 | + | <description summary="indicates the cause of surrounding text change"> | |||
| 179 | + | Tells the compositor why the text surrounding the cursor changed. | |||
| 180 | + | ||||
| 181 | + | Whenever the client detects an external change in text, cursor, or | |||
| 182 | + | anchor posision, it must issue this request to the compositor. This | |||
| 183 | + | request is intended to give the input method a chance to update the | |||
| 184 | + | preedit text in an appropriate way, e.g. by removing it when the user | |||
| 185 | + | starts typing with a keyboard. | |||
| 186 | + | ||||
| 187 | + | cause describes the source of the change. | |||
| 188 | + | ||||
| 189 | + | The value set with this request is double-buffered. It must be applied | |||
| 190 | + | and reset to initial at the next zwp_text_input_v3.commit request. | |||
| 191 | + | ||||
| 192 | + | The initial value of cause is input_method. | |||
| 193 | + | </description> | |||
| 194 | + | <arg name="cause" type="uint" enum="change_cause"/> | |||
| 195 | + | </request> | |||
| 196 | + | ||||
| 197 | + | <enum name="content_hint" bitfield="true"> | |||
| 198 | + | <description summary="content hint"> | |||
| 199 | + | Content hint is a bitmask to allow to modify the behavior of the text | |||
| 200 | + | input. | |||
| 201 | + | </description> | |||
| 202 | + | <entry name="none" value="0x0" summary="no special behavior"/> | |||
| 203 | + | <entry name="completion" value="0x1" summary="suggest word completions"/> | |||
| 204 | + | <entry name="spellcheck" value="0x2" summary="suggest word corrections"/> | |||
| 205 | + | <entry name="auto_capitalization" value="0x4" summary="switch to uppercase letters at the start of a sentence"/> | |||
| 206 | + | <entry name="lowercase" value="0x8" summary="prefer lowercase letters"/> | |||
| 207 | + | <entry name="uppercase" value="0x10" summary="prefer uppercase letters"/> | |||
| 208 | + | <entry name="titlecase" value="0x20" summary="prefer casing for titles and headings (can be language dependent)"/> | |||
| 209 | + | <entry name="hidden_text" value="0x40" summary="characters should be hidden"/> | |||
| 210 | + | <entry name="sensitive_data" value="0x80" summary="typed text should not be stored"/> | |||
| 211 | + | <entry name="latin" value="0x100" summary="just Latin characters should be entered"/> | |||
| 212 | + | <entry name="multiline" value="0x200" summary="the text input is multiline"/> | |||
| 213 | + | <entry | |||
| 214 | + | name="on_screen_input_provided" value="0x400" since="2" | |||
| 215 | + | summary="an on-screen way to fill in the input is already provided by the client"/> | |||
| 216 | + | <entry | |||
| 217 | + | name="no_emoji" value="0x800" since="2" | |||
| 218 | + | summary="prefer not offering emoji support"/> | |||
| 219 | + | <entry | |||
| 220 | + | name="preedit_shown" value="0x1000" since="2" | |||
| 221 | + | summary="the text input will display preedit text in place"/> | |||
| 222 | + | </enum> | |||
| 223 | + | ||||
| 224 | + | <enum name="content_purpose"> | |||
| 225 | + | <description summary="content purpose"> | |||
| 226 | + | The content purpose allows to specify the primary purpose of a text | |||
| 227 | + | input. | |||
| 228 | + | ||||
| 229 | + | This allows an input method to show special purpose input panels with | |||
| 230 | + | extra characters or to disallow some characters. | |||
| 231 | + | </description> | |||
| 232 | + | <entry name="normal" value="0" summary="default input, allowing all characters"/> | |||
| 233 | + | <entry name="alpha" value="1" summary="allow only alphabetic characters"/> | |||
| 234 | + | <entry name="digits" value="2" summary="allow only digits"/> | |||
| 235 | + | <entry name="number" value="3" summary="input a number (including decimal separator and sign)"/> | |||
| 236 | + | <entry name="phone" value="4" summary="input a phone number"/> | |||
| 237 | + | <entry name="url" value="5" summary="input an URL"/> | |||
| 238 | + | <entry name="email" value="6" summary="input an email address"/> | |||
| 239 | + | <entry name="name" value="7" summary="input a name of a person"/> | |||
| 240 | + | <entry name="password" value="8" summary="input a password (combine with sensitive_data hint)"/> | |||
| 241 | + | <entry name="pin" value="9" summary="input is a numeric password (combine with sensitive_data hint)"/> | |||
| 242 | + | <entry name="date" value="10" summary="input a date"/> | |||
| 243 | + | <entry name="time" value="11" summary="input a time"/> | |||
| 244 | + | <entry name="datetime" value="12" summary="input a date and time"/> | |||
| 245 | + | <entry name="terminal" value="13" summary="input for a terminal"/> | |||
| 246 | + | </enum> | |||
| 247 | + | ||||
| 248 | + | <request name="set_content_type"> | |||
| 249 | + | <description summary="set content purpose and hint"> | |||
| 250 | + | Sets the content purpose and content hint. While the purpose is the | |||
| 251 | + | basic purpose of an input field, the hint flags allow to modify some of | |||
| 252 | + | the behavior. | |||
| 253 | + | ||||
| 254 | + | Values set with this request are double-buffered. They will get applied | |||
| 255 | + | on the next zwp_text_input_v3.commit request. | |||
| 256 | + | Subsequent attempts to update them may have no effect. The values | |||
| 257 | + | remain valid until the next committed enable or disable request. | |||
| 258 | + | ||||
| 259 | + | The initial value for hint is none, and the initial value for purpose | |||
| 260 | + | is normal. | |||
| 261 | + | </description> | |||
| 262 | + | <arg name="hint" type="uint" enum="content_hint"/> | |||
| 263 | + | <arg name="purpose" type="uint" enum="content_purpose"/> | |||
| 264 | + | </request> | |||
| 265 | + | ||||
| 266 | + | <request name="set_cursor_rectangle"> | |||
| 267 | + | <description summary="set cursor position"> | |||
| 268 | + | Marks an area around the cursor as a x, y, width, height rectangle in | |||
| 269 | + | surface local coordinates. | |||
| 270 | + | ||||
| 271 | + | Allows the compositor to put a window with word suggestions near the | |||
| 272 | + | cursor, without obstructing the text being input. | |||
| 273 | + | ||||
| 274 | + | If the client is unaware of the position of edited text, it should not | |||
| 275 | + | issue this request, to signify lack of support to the compositor. | |||
| 276 | + | ||||
| 277 | + | Values set with this request are double-buffered. They will get applied | |||
| 278 | + | on the next zwp_text_input_v3.commit request, and stay valid until the | |||
| 279 | + | next committed enable or disable request. | |||
| 280 | + | ||||
| 281 | + | The initial values describing a cursor rectangle are empty. That means | |||
| 282 | + | the text input does not support describing the cursor area. If the | |||
| 283 | + | empty values get applied, subsequent attempts to change them may have | |||
| 284 | + | no effect. | |||
| 285 | + | ||||
| 286 | + | As of version 2, the zwp_text_input_v3.commit request does not apply | |||
| 287 | + | values sent with this request. Instead, it stores them in a separate | |||
| 288 | + | "committed" area. The committed values, if still valid, get applied on | |||
| 289 | + | the next wl_surface.commit request on the surface with text-input focus. | |||
| 290 | + | Both committed and applied values get invalidated on: | |||
| 291 | + | ||||
| 292 | + | - the next committed enable or disable request, or | |||
| 293 | + | - a change of the focused surface of the text-input (leave or enter events). | |||
| 294 | + | ||||
| 295 | + | This double stage application allows the compositor to position | |||
| 296 | + | the input method popup in the same frame as the contents | |||
| 297 | + | of the text on the surface are updated. | |||
| 298 | + | </description> | |||
| 299 | + | <arg name="x" type="int"/> | |||
| 300 | + | <arg name="y" type="int"/> | |||
| 301 | + | <arg name="width" type="int"/> | |||
| 302 | + | <arg name="height" type="int"/> | |||
| 303 | + | </request> | |||
| 304 | + | ||||
| 305 | + | <request name="commit"> | |||
| 306 | + | <description summary="commit state"> | |||
| 307 | + | Atomically applies state changes recently sent to the compositor. | |||
| 308 | + | ||||
| 309 | + | The commit request establishes and updates the state of the client, and | |||
| 310 | + | must be issued after any changes to apply them. | |||
| 311 | + | ||||
| 312 | + | Text input state (enabled status, content purpose, content hint, | |||
| 313 | + | surrounding text and change cause, cursor rectangle) is conceptually | |||
| 314 | + | double-buffered within the context of a text input, i.e. between a | |||
| 315 | + | committed enable request and the following committed enable or disable | |||
| 316 | + | request. | |||
| 317 | + | ||||
| 318 | + | Protocol requests modify the pending state, as opposed to the current | |||
| 319 | + | state in use by the input method. A commit request atomically applies | |||
| 320 | + | all pending state, replacing the current state. After commit, the new | |||
| 321 | + | pending state is as documented for each related request. | |||
| 322 | + | ||||
| 323 | + | Requests are applied in the order of arrival. | |||
| 324 | + | ||||
| 325 | + | Neither current nor pending state are modified unless noted otherwise. | |||
| 326 | + | ||||
| 327 | + | The compositor must count the number of commit requests coming from | |||
| 328 | + | each zwp_text_input_v3 object and use the count as the serial in done | |||
| 329 | + | events. | |||
| 330 | + | </description> | |||
| 331 | + | </request> | |||
| 332 | + | ||||
| 333 | + | <event name="enter"> | |||
| 334 | + | <description summary="enter event"> | |||
| 335 | + | Notification that this seat's text-input focus is on a certain surface. | |||
| 336 | + | ||||
| 337 | + | If client has created multiple text input objects, compositor must send | |||
| 338 | + | this event to all of them. | |||
| 339 | + | ||||
| 340 | + | When the seat has the keyboard capability the text-input focus follows | |||
| 341 | + | the keyboard focus. This event sets the current surface for the | |||
| 342 | + | text-input object. | |||
| 343 | + | </description> | |||
| 344 | + | <arg name="surface" type="object" interface="wl_surface"/> | |||
| 345 | + | </event> | |||
| 346 | + | ||||
| 347 | + | <event name="leave"> | |||
| 348 | + | <description summary="leave event"> | |||
| 349 | + | Notification that this seat's text-input focus is no longer on a | |||
| 350 | + | certain surface. The client should reset any preedit string previously | |||
| 351 | + | set. | |||
| 352 | + | ||||
| 353 | + | The leave notification clears the current surface. It is sent before | |||
| 354 | + | the enter notification for the new focus. After leave event, compositor | |||
| 355 | + | must ignore requests from any text input instances until next enter | |||
| 356 | + | event. | |||
| 357 | + | ||||
| 358 | + | When the seat has the keyboard capability the text-input focus follows | |||
| 359 | + | the keyboard focus. | |||
| 360 | + | </description> | |||
| 361 | + | <arg name="surface" type="object" interface="wl_surface"/> | |||
| 362 | + | </event> | |||
| 363 | + | ||||
| 364 | + | <event name="preedit_string"> | |||
| 365 | + | <description summary="pre-edit"> | |||
| 366 | + | Notify when a new composing text (pre-edit) should be set at the | |||
| 367 | + | current cursor position. Any previously set composing text must be | |||
| 368 | + | removed. Any previously existing selected text must be removed. | |||
| 369 | + | ||||
| 370 | + | The argument text contains the pre-edit string buffer. | |||
| 371 | + | ||||
| 372 | + | The parameters cursor_begin and cursor_end are counted in bytes | |||
| 373 | + | relative to the beginning of the submitted text buffer. Cursor should | |||
| 374 | + | be hidden when both are equal to -1. | |||
| 375 | + | ||||
| 376 | + | They could be represented by the client as a line if both values are | |||
| 377 | + | the same, or as a text highlight otherwise. | |||
| 378 | + | ||||
| 379 | + | Values set with this event are double-buffered. They must be applied | |||
| 380 | + | and reset to initial on the next zwp_text_input_v3.done event. | |||
| 381 | + | ||||
| 382 | + | The initial value of text is an empty string, and cursor_begin, | |||
| 383 | + | cursor_end and cursor_hidden are all 0. | |||
| 384 | + | </description> | |||
| 385 | + | <arg name="text" type="string" allow-null="true"/> | |||
| 386 | + | <arg name="cursor_begin" type="int"/> | |||
| 387 | + | <arg name="cursor_end" type="int"/> | |||
| 388 | + | </event> | |||
| 389 | + | ||||
| 390 | + | <event name="commit_string"> | |||
| 391 | + | <description summary="text commit"> | |||
| 392 | + | Notify when text should be inserted into the editor widget. The text to | |||
| 393 | + | commit could be either just a single character after a key press or the | |||
| 394 | + | result of some composing (pre-edit). | |||
| 395 | + | ||||
| 396 | + | Values set with this event are double-buffered. They must be applied | |||
| 397 | + | and reset to initial on the next zwp_text_input_v3.done event. | |||
| 398 | + | ||||
| 399 | + | The initial value of text is an empty string. | |||
| 400 | + | </description> | |||
| 401 | + | <arg name="text" type="string" allow-null="true"/> | |||
| 402 | + | </event> | |||
| 403 | + | ||||
| 404 | + | <event name="delete_surrounding_text"> | |||
| 405 | + | <description summary="delete surrounding text"> | |||
| 406 | + | Notify when the text around the current cursor position should be | |||
| 407 | + | deleted. | |||
| 408 | + | ||||
| 409 | + | Before_length and after_length are the number of bytes before and after | |||
| 410 | + | the current cursor index (excluding the selection) to delete. | |||
| 411 | + | ||||
| 412 | + | If a preedit text is present, in effect before_length is counted from | |||
| 413 | + | the beginning of it, and after_length from its end (see done event | |||
| 414 | + | sequence). | |||
| 415 | + | ||||
| 416 | + | Values set with this event are double-buffered. They must be applied | |||
| 417 | + | and reset to initial on the next zwp_text_input_v3.done event. | |||
| 418 | + | ||||
| 419 | + | The initial values of both before_length and after_length are 0. | |||
| 420 | + | </description> | |||
| 421 | + | <arg name="before_length" type="uint" summary="length of text before current cursor position"/> | |||
| 422 | + | <arg name="after_length" type="uint" summary="length of text after current cursor position"/> | |||
| 423 | + | </event> | |||
| 424 | + | ||||
| 425 | + | <event name="done"> | |||
| 426 | + | <description summary="apply changes"> | |||
| 427 | + | Instruct the application to apply changes to state requested by the | |||
| 428 | + | preedit_string, commit_string delete_surrounding_text, and action | |||
| 429 | + | events. | |||
| 430 | + | ||||
| 431 | + | The state relating to these events is double-buffered, and each one | |||
| 432 | + | modifies the pending state. This event replaces the current state with | |||
| 433 | + | the pending state. | |||
| 434 | + | ||||
| 435 | + | The application must proceed by evaluating the changes in the following | |||
| 436 | + | order: | |||
| 437 | + | ||||
| 438 | + | 1. Replace existing preedit string with the cursor. | |||
| 439 | + | 2. Delete requested surrounding text. | |||
| 440 | + | 3. Insert commit string with the cursor at its end. | |||
| 441 | + | 4. Calculate surrounding text to send. | |||
| 442 | + | 5. Insert new preedit text in cursor position. | |||
| 443 | + | 6. Place cursor inside preedit text. | |||
| 444 | + | 7. Perform the requested action. | |||
| 445 | + | ||||
| 446 | + | The serial number reflects the last state of the zwp_text_input_v3 | |||
| 447 | + | object known to the compositor. The value of the serial argument must | |||
| 448 | + | be equal to the number of commit requests already issued on that object. | |||
| 449 | + | ||||
| 450 | + | When the client receives a done event with a serial different than the | |||
| 451 | + | number of past commit requests, it must proceed with evaluating and | |||
| 452 | + | applying the changes as normal, except it should not change the current | |||
| 453 | + | state of the zwp_text_input_v3 object. All pending state requests | |||
| 454 | + | (set_surrounding_text, set_content_type and set_cursor_rectangle) on | |||
| 455 | + | the zwp_text_input_v3 object should be sent and committed after | |||
| 456 | + | receiving a zwp_text_input_v3.done event with a matching serial. | |||
| 457 | + | </description> | |||
| 458 | + | <arg name="serial" type="uint"/> | |||
| 459 | + | </event> | |||
| 460 | + | ||||
| 461 | + | <!-- Version 2 additions --> | |||
| 462 | + | <enum name="error" since="2"> | |||
| 463 | + | <entry name="invalid_action" value="0" summary="an invalid or duplicate action was specified"/> | |||
| 464 | + | </enum> | |||
| 465 | + | ||||
| 466 | + | <enum name="action" since="2"> | |||
| 467 | + | <description summary="action"> | |||
| 468 | + | A possible action to perform on a text input. | |||
| 469 | + | ||||
| 470 | + | The submit action is intended for input entries that expect some sort of | |||
| 471 | + | activation after user interaction, e.g. the URL entry in a browser. | |||
| 472 | + | </description> | |||
| 473 | + | <entry name="none" value="0" summary="no action"/> | |||
| 474 | + | <entry name="submit" value="1" summary="the action is submitted"/> | |||
| 475 | + | </enum> | |||
| 476 | + | ||||
| 477 | + | <event name="action" since="2"> | |||
| 478 | + | <description summary="action performed"> | |||
| 479 | + | An action was performed on this text input. | |||
| 480 | + | ||||
| 481 | + | Values set with this event are double-buffered. They must be applied | |||
| 482 | + | and reset to initial on the next zwp_text_input_v3.done event. | |||
| 483 | + | ||||
| 484 | + | The initial value of action is none. | |||
| 485 | + | </description> | |||
| 486 | + | <arg name="action" type="uint" enum="action" summary="action performed"/> | |||
| 487 | + | <arg name="serial" type="uint" summary="serial number of the action event"/> | |||
| 488 | + | </event> | |||
| 489 | + | ||||
| 490 | + | <event name="language" since="2"> | |||
| 491 | + | <description summary="notify of language selection"> | |||
| 492 | + | Notify the application of language used by the input method. | |||
| 493 | + | ||||
| 494 | + | This event will be sent on creation if known and for all subsequent changes. | |||
| 495 | + | ||||
| 496 | + | The language should be specified as an IETF BCP 47 tag. | |||
| 497 | + | Setting an empty string will reset any known language back to the default unknown state. | |||
| 498 | + | </description> | |||
| 499 | + | <arg name="language" type="string" summary="new language set by IME"/> | |||
| 500 | + | </event> | |||
| 501 | + | ||||
| 502 | + | <request name="set_available_actions" since="2"> | |||
| 503 | + | <description summary="set the available actions"> | |||
| 504 | + | Set the actions available for this text input. | |||
| 505 | + | ||||
| 506 | + | Values set with this request are double-buffered. They will get applied | |||
| 507 | + | on the next zwp_text_input_v3.commit request. | |||
| 508 | + | ||||
| 509 | + | If the available_actions array contains the none action, or contains the | |||
| 510 | + | same action multiple times, the compositor must raise the invalid_action | |||
| 511 | + | protocol error. | |||
| 512 | + | ||||
| 513 | + | Initially, no actions are available. | |||
| 514 | + | </description> | |||
| 515 | + | <arg name="available_actions" type="array" summary="available actions"/> | |||
| 516 | + | </request> | |||
| 517 | + | ||||
| 518 | + | <request name="show_input_panel" since="2"> | |||
| 519 | + | <description summary="show input panel"> | |||
| 520 | + | Requests an input panel to be shown (e.g. a on-screen keyboard). | |||
| 521 | + | ||||
| 522 | + | This request only hints the desired interaction pattern from the | |||
| 523 | + | client side, and its effect may be ignored by compositors given | |||
| 524 | + | other environmental factors. Repeated calls will be ignored. | |||
| 525 | + | </description> | |||
| 526 | + | </request> | |||
| 527 | + | ||||
| 528 | + | <request name="hide_input_panel" since="2"> | |||
| 529 | + | <description summary="hide input panel"> | |||
| 530 | + | Requests an input panel to be hidden. | |||
| 531 | + | ||||
| 532 | + | This request only hints the desired interaction pattern from the | |||
| 533 | + | client side, and its effect may be ignored by compositors given | |||
| 534 | + | other environmental factors. Repeated calls will be ignored. | |||
| 535 | + | </description> | |||
| 536 | + | </request> | |||
| 537 | + | ||||
| 538 | + | <enum name="preedit_hint"> | |||
| 539 | + | <description summary="preedit style hint"> | |||
| 540 | + | Style hints for the preedit string. | |||
| 541 | + | </description> | |||
| 542 | + | <entry name="whole" value="1" summary="simple pre-edit text style, typically underlined"/> | |||
| 543 | + | <entry name="selection" value="2" | |||
| 544 | + | summary="hint for a selected piece of text, e.g. per-character navigation and composition"/> | |||
| 545 | + | <entry name="prediction" value="3" summary="predicted text, not typed by the user"/> | |||
| 546 | + | <entry name="prefix" value="4" | |||
| 547 | + | summary="prefixed text not being currently edited, e.g. prior to a 'selection' section"/> | |||
| 548 | + | <entry name="suffix" value="5" | |||
| 549 | + | summary="suffixed text not being currently edited, e.g. after a 'selection' section"/> | |||
| 550 | + | <entry name="spelling_error" value="6" summary="spelling error"/> | |||
| 551 | + | <entry name="compose_error" value="7" | |||
| 552 | + | summary="wrong composition, e.g. user input that can not be transliterated"/> | |||
| 553 | + | </enum> | |||
| 554 | + | ||||
| 555 | + | <event name="preedit_hint" since="2"> | |||
| 556 | + | <description summary="pre-edit"> | |||
| 557 | + | Notify of contextual hints for the pre-edit string. This | |||
| 558 | + | event is always sent together with a zwp_text_input_v3.preedit_string | |||
| 559 | + | event. | |||
| 560 | + | ||||
| 561 | + | The parameters start and end are counted in bytes relative to the | |||
| 562 | + | beginning of the text buffer submitted through | |||
| 563 | + | zwp_text_input_v3.preedit_string, and represent the substring in the | |||
| 564 | + | pre-edit text affected by the hint. | |||
| 565 | + | ||||
| 566 | + | Multiple events may be submitted if the preedit string has different | |||
| 567 | + | sections. The extent of hints may overlap. The parts of the preedit | |||
| 568 | + | string that are not covered by any zwp_text_input_v3.preedit_hint event, | |||
| 569 | + | the text will be considered unhinted. This is also the case if no | |||
| 570 | + | preedit_hint event is sent. | |||
| 571 | + | ||||
| 572 | + | Clients should provide recognizable visuals to these hints. if they are | |||
| 573 | + | unable to comply with this requisition, it may be preferable for them | |||
| 574 | + | keep the preedit_shown content hint disabled. | |||
| 575 | + | ||||
| 576 | + | Values set with this event are double-buffered. They must be applied | |||
| 577 | + | and reset on the next zwp_text_input_v3.done event. | |||
| 578 | + | </description> | |||
| 579 | + | <arg name="start" type="uint" summary="starting point of the affected substring"/> | |||
| 580 | + | <arg name="end" type="uint" summary="end point of the affected substring"/> | |||
| 581 | + | <arg name="hint" type="uint" enum="preedit_hint" summary="hint to apply"/> | |||
| 582 | + | </event> | |||
| 583 | + | </interface> | |||
| 584 | + | ||||
| 585 | + | <interface name="zwp_text_input_manager_v3" version="2"> | |||
| 586 | + | <description summary="text input manager"> | |||
| 587 | + | A factory for text-input objects. This object is a global singleton. | |||
| 588 | + | </description> | |||
| 589 | + | ||||
| 590 | + | <request name="destroy" type="destructor"> | |||
| 591 | + | <description summary="Destroy the wp_text_input_manager"> | |||
| 592 | + | Destroy the wp_text_input_manager object. | |||
| 593 | + | </description> | |||
| 594 | + | </request> | |||
| 595 | + | ||||
| 596 | + | <request name="get_text_input"> | |||
| 597 | + | <description summary="create a new text input object"> | |||
| 598 | + | Creates a new text-input object for a given seat. | |||
| 599 | + | </description> | |||
| 600 | + | <arg name="id" type="new_id" interface="zwp_text_input_v3"/> | |||
| 601 | + | <arg name="seat" type="object" interface="wl_seat"/> | |||
| 602 | + | </request> | |||
| 603 | + | </interface> | |||
| 604 | + | </protocol> | |||
A spec/xml/viewporter.xml +177 -0
| @@ -0,0 +1,177 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="viewporter"> | |||
| 3 | + | ||||
| 4 | + | <copyright> | |||
| 5 | + | Copyright © 2013-2016 Collabora, Ltd. | |||
| 6 | + | ||||
| 7 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 8 | + | copy of this software and associated documentation files (the "Software"), | |||
| 9 | + | to deal in the Software without restriction, including without limitation | |||
| 10 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 11 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 12 | + | Software is furnished to do so, subject to the following conditions: | |||
| 13 | + | ||||
| 14 | + | The above copyright notice and this permission notice (including the next | |||
| 15 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 16 | + | Software. | |||
| 17 | + | ||||
| 18 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 19 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 20 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 21 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 22 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 23 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 24 | + | DEALINGS IN THE SOFTWARE. | |||
| 25 | + | </copyright> | |||
| 26 | + | ||||
| 27 | + | <interface name="wp_viewporter" version="1"> | |||
| 28 | + | <description summary="surface cropping and scaling"> | |||
| 29 | + | The global interface exposing surface cropping and scaling | |||
| 30 | + | capabilities is used to instantiate an interface extension for a | |||
| 31 | + | wl_surface object. This extended interface will then allow | |||
| 32 | + | cropping and scaling the surface contents, effectively | |||
| 33 | + | disconnecting the direct relationship between the buffer and the | |||
| 34 | + | surface size. | |||
| 35 | + | </description> | |||
| 36 | + | ||||
| 37 | + | <request name="destroy" type="destructor"> | |||
| 38 | + | <description summary="unbind from the cropping and scaling interface"> | |||
| 39 | + | Informs the server that the client will not be using this | |||
| 40 | + | protocol object anymore. This does not affect any other objects, | |||
| 41 | + | wp_viewport objects included. | |||
| 42 | + | </description> | |||
| 43 | + | </request> | |||
| 44 | + | ||||
| 45 | + | <enum name="error"> | |||
| 46 | + | <entry name="viewport_exists" value="0" | |||
| 47 | + | summary="the surface already has a viewport object associated"/> | |||
| 48 | + | </enum> | |||
| 49 | + | ||||
| 50 | + | <request name="get_viewport"> | |||
| 51 | + | <description summary="extend surface interface for crop and scale"> | |||
| 52 | + | Instantiate an interface extension for the given wl_surface to | |||
| 53 | + | crop and scale its content. If the given wl_surface already has | |||
| 54 | + | a wp_viewport object associated, the viewport_exists | |||
| 55 | + | protocol error is raised. | |||
| 56 | + | </description> | |||
| 57 | + | <arg name="id" type="new_id" interface="wp_viewport" | |||
| 58 | + | summary="the new viewport interface id"/> | |||
| 59 | + | <arg name="surface" type="object" interface="wl_surface" | |||
| 60 | + | summary="the surface"/> | |||
| 61 | + | </request> | |||
| 62 | + | </interface> | |||
| 63 | + | ||||
| 64 | + | <interface name="wp_viewport" version="1"> | |||
| 65 | + | <description summary="crop and scale interface to a wl_surface"> | |||
| 66 | + | An additional interface to a wl_surface object, which allows the | |||
| 67 | + | client to specify the cropping and scaling of the surface | |||
| 68 | + | contents. | |||
| 69 | + | ||||
| 70 | + | This interface works with two concepts: the source rectangle (src_x, | |||
| 71 | + | src_y, src_width, src_height), and the destination size (dst_width, | |||
| 72 | + | dst_height). The contents of the source rectangle are scaled to the | |||
| 73 | + | destination size, and content outside the source rectangle is ignored. | |||
| 74 | + | This state is double-buffered, see wl_surface.commit. | |||
| 75 | + | ||||
| 76 | + | The two parts of crop and scale state are independent: the source | |||
| 77 | + | rectangle, and the destination size. Initially both are unset, that | |||
| 78 | + | is, no scaling is applied. The whole of the current wl_buffer is | |||
| 79 | + | used as the source, and the surface size is as defined in | |||
| 80 | + | wl_surface.attach. | |||
| 81 | + | ||||
| 82 | + | If the destination size is set, it causes the surface size to become | |||
| 83 | + | dst_width, dst_height. The source (rectangle) is scaled to exactly | |||
| 84 | + | this size. This overrides whatever the attached wl_buffer size is, | |||
| 85 | + | unless the wl_buffer is NULL. If the wl_buffer is NULL, the surface | |||
| 86 | + | has no content and therefore no size. Otherwise, the size is always | |||
| 87 | + | at least 1x1 in surface local coordinates. | |||
| 88 | + | ||||
| 89 | + | If the source rectangle is set, it defines what area of the wl_buffer is | |||
| 90 | + | taken as the source. If the source rectangle is set and the destination | |||
| 91 | + | size is not set, then src_width and src_height must be integers, and the | |||
| 92 | + | surface size becomes the source rectangle size. This results in cropping | |||
| 93 | + | without scaling. If src_width or src_height are not integers and | |||
| 94 | + | destination size is not set, the bad_size protocol error is raised when | |||
| 95 | + | the surface state is applied. | |||
| 96 | + | ||||
| 97 | + | The coordinate transformations from buffer pixel coordinates up to | |||
| 98 | + | the surface-local coordinates happen in the following order: | |||
| 99 | + | 1. buffer_transform (wl_surface.set_buffer_transform) | |||
| 100 | + | 2. buffer_scale (wl_surface.set_buffer_scale) | |||
| 101 | + | 3. crop and scale (wp_viewport.set*) | |||
| 102 | + | This means, that the source rectangle coordinates of crop and scale | |||
| 103 | + | are given in the coordinates after the buffer transform and scale, | |||
| 104 | + | i.e. in the coordinates that would be the surface-local coordinates | |||
| 105 | + | if the crop and scale was not applied. | |||
| 106 | + | ||||
| 107 | + | If src_x or src_y are negative, the bad_value protocol error is raised. | |||
| 108 | + | Otherwise, if the source rectangle is partially or completely outside of | |||
| 109 | + | the non-NULL wl_buffer, then the out_of_buffer protocol error is raised | |||
| 110 | + | when the surface state is applied. A NULL wl_buffer does not raise the | |||
| 111 | + | out_of_buffer error. | |||
| 112 | + | ||||
| 113 | + | If the wl_surface associated with the wp_viewport is destroyed, | |||
| 114 | + | all wp_viewport requests except 'destroy' raise the protocol error | |||
| 115 | + | no_surface. | |||
| 116 | + | ||||
| 117 | + | If the wp_viewport object is destroyed, the crop and scale | |||
| 118 | + | state is removed from the wl_surface. The change will be applied | |||
| 119 | + | on the next wl_surface.commit. | |||
| 120 | + | </description> | |||
| 121 | + | ||||
| 122 | + | <request name="destroy" type="destructor"> | |||
| 123 | + | <description summary="remove scaling and cropping from the surface"> | |||
| 124 | + | The associated wl_surface's crop and scale state is removed. | |||
| 125 | + | The change is applied on the next wl_surface.commit. | |||
| 126 | + | </description> | |||
| 127 | + | </request> | |||
| 128 | + | ||||
| 129 | + | <enum name="error"> | |||
| 130 | + | <entry name="bad_value" value="0" | |||
| 131 | + | summary="negative or zero values in width or height"/> | |||
| 132 | + | <entry name="bad_size" value="1" | |||
| 133 | + | summary="destination size is not integer"/> | |||
| 134 | + | <entry name="out_of_buffer" value="2" | |||
| 135 | + | summary="source rectangle extends outside of the content area"/> | |||
| 136 | + | <entry name="no_surface" value="3" | |||
| 137 | + | summary="the wl_surface was destroyed"/> | |||
| 138 | + | </enum> | |||
| 139 | + | ||||
| 140 | + | <request name="set_source"> | |||
| 141 | + | <description summary="set the source rectangle for cropping"> | |||
| 142 | + | Set the source rectangle of the associated wl_surface. See | |||
| 143 | + | wp_viewport for the description, and relation to the wl_buffer | |||
| 144 | + | size. | |||
| 145 | + | ||||
| 146 | + | If all of x, y, width and height are -1.0, the source rectangle is | |||
| 147 | + | unset instead. Any other set of values where width or height are zero | |||
| 148 | + | or negative, or x or y are negative, raise the bad_value protocol | |||
| 149 | + | error. | |||
| 150 | + | ||||
| 151 | + | The crop and scale state is double-buffered, see wl_surface.commit. | |||
| 152 | + | </description> | |||
| 153 | + | <arg name="x" type="fixed" summary="source rectangle x"/> | |||
| 154 | + | <arg name="y" type="fixed" summary="source rectangle y"/> | |||
| 155 | + | <arg name="width" type="fixed" summary="source rectangle width"/> | |||
| 156 | + | <arg name="height" type="fixed" summary="source rectangle height"/> | |||
| 157 | + | </request> | |||
| 158 | + | ||||
| 159 | + | <request name="set_destination"> | |||
| 160 | + | <description summary="set the surface size for scaling"> | |||
| 161 | + | Set the destination size of the associated wl_surface. See | |||
| 162 | + | wp_viewport for the description, and relation to the wl_buffer | |||
| 163 | + | size. | |||
| 164 | + | ||||
| 165 | + | If width is -1 and height is -1, the destination size is unset | |||
| 166 | + | instead. Any other pair of values for width and height that | |||
| 167 | + | contains zero or negative values raises the bad_value protocol | |||
| 168 | + | error. | |||
| 169 | + | ||||
| 170 | + | The crop and scale state is double-buffered, see wl_surface.commit. | |||
| 171 | + | </description> | |||
| 172 | + | <arg name="width" type="int" summary="surface width"/> | |||
| 173 | + | <arg name="height" type="int" summary="surface height"/> | |||
| 174 | + | </request> | |||
| 175 | + | </interface> | |||
| 176 | + | ||||
| 177 | + | </protocol> | |||
A spec/xml/virtualkeyboard.xml +113 -0
| @@ -0,0 +1,113 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="virtual_keyboard_unstable_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2008-2011 Kristian Høgsberg | |||
| 5 | + | Copyright © 2010-2013 Intel Corporation | |||
| 6 | + | Copyright © 2012-2013 Collabora, Ltd. | |||
| 7 | + | Copyright © 2018 Purism SPC | |||
| 8 | + | ||||
| 9 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 10 | + | copy of this software and associated documentation files (the "Software"), | |||
| 11 | + | to deal in the Software without restriction, including without limitation | |||
| 12 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 13 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 14 | + | Software is furnished to do so, subject to the following conditions: | |||
| 15 | + | ||||
| 16 | + | The above copyright notice and this permission notice (including the next | |||
| 17 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 18 | + | Software. | |||
| 19 | + | ||||
| 20 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 21 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 22 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 23 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 24 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 25 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 26 | + | DEALINGS IN THE SOFTWARE. | |||
| 27 | + | </copyright> | |||
| 28 | + | ||||
| 29 | + | <interface name="zwp_virtual_keyboard_v1" version="1"> | |||
| 30 | + | <description summary="virtual keyboard"> | |||
| 31 | + | The virtual keyboard provides an application with requests which emulate | |||
| 32 | + | the behaviour of a physical keyboard. | |||
| 33 | + | ||||
| 34 | + | This interface can be used by clients on its own to provide raw input | |||
| 35 | + | events, or it can accompany the input method protocol. | |||
| 36 | + | </description> | |||
| 37 | + | ||||
| 38 | + | <request name="keymap"> | |||
| 39 | + | <description summary="keyboard mapping"> | |||
| 40 | + | Provide a file descriptor to the compositor which can be | |||
| 41 | + | memory-mapped to provide a keyboard mapping description. | |||
| 42 | + | ||||
| 43 | + | Format carries a value from the keymap_format enumeration. | |||
| 44 | + | </description> | |||
| 45 | + | <arg name="format" type="uint" summary="keymap format"/> | |||
| 46 | + | <arg name="fd" type="fd" summary="keymap file descriptor"/> | |||
| 47 | + | <arg name="size" type="uint" summary="keymap size, in bytes"/> | |||
| 48 | + | </request> | |||
| 49 | + | ||||
| 50 | + | <enum name="error"> | |||
| 51 | + | <entry name="no_keymap" value="0" summary="No keymap was set"/> | |||
| 52 | + | </enum> | |||
| 53 | + | ||||
| 54 | + | <request name="key"> | |||
| 55 | + | <description summary="key event"> | |||
| 56 | + | A key was pressed or released. | |||
| 57 | + | The time argument is a timestamp with millisecond granularity, with an | |||
| 58 | + | undefined base. All requests regarding a single object must share the | |||
| 59 | + | same clock. | |||
| 60 | + | ||||
| 61 | + | Keymap must be set before issuing this request. | |||
| 62 | + | ||||
| 63 | + | State carries a value from the key_state enumeration. | |||
| 64 | + | </description> | |||
| 65 | + | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |||
| 66 | + | <arg name="key" type="uint" summary="key that produced the event"/> | |||
| 67 | + | <arg name="state" type="uint" summary="physical state of the key"/> | |||
| 68 | + | </request> | |||
| 69 | + | ||||
| 70 | + | <request name="modifiers"> | |||
| 71 | + | <description summary="modifier and group state"> | |||
| 72 | + | Notifies the compositor that the modifier and/or group state has | |||
| 73 | + | changed, and it should update state. | |||
| 74 | + | ||||
| 75 | + | The client should use wl_keyboard.modifiers event to synchronize its | |||
| 76 | + | internal state with seat state. | |||
| 77 | + | ||||
| 78 | + | Keymap must be set before issuing this request. | |||
| 79 | + | </description> | |||
| 80 | + | <arg name="mods_depressed" type="uint" summary="depressed modifiers"/> | |||
| 81 | + | <arg name="mods_latched" type="uint" summary="latched modifiers"/> | |||
| 82 | + | <arg name="mods_locked" type="uint" summary="locked modifiers"/> | |||
| 83 | + | <arg name="group" type="uint" summary="keyboard layout"/> | |||
| 84 | + | </request> | |||
| 85 | + | ||||
| 86 | + | <request name="destroy" type="destructor" since="1"> | |||
| 87 | + | <description summary="destroy the virtual keyboard keyboard object"/> | |||
| 88 | + | </request> | |||
| 89 | + | </interface> | |||
| 90 | + | ||||
| 91 | + | <interface name="zwp_virtual_keyboard_manager_v1" version="1"> | |||
| 92 | + | <description summary="virtual keyboard manager"> | |||
| 93 | + | A virtual keyboard manager allows an application to provide keyboard | |||
| 94 | + | input events as if they came from a physical keyboard. | |||
| 95 | + | </description> | |||
| 96 | + | ||||
| 97 | + | <enum name="error"> | |||
| 98 | + | <entry name="unauthorized" value="0" summary="client not authorized to use the interface"/> | |||
| 99 | + | </enum> | |||
| 100 | + | ||||
| 101 | + | <request name="create_virtual_keyboard"> | |||
| 102 | + | <description summary="Create a new virtual keyboard"> | |||
| 103 | + | Creates a new virtual keyboard associated to a seat. | |||
| 104 | + | ||||
| 105 | + | If the compositor enables a keyboard to perform arbitrary actions, it | |||
| 106 | + | should present an error when an untrusted client requests a new | |||
| 107 | + | keyboard. | |||
| 108 | + | </description> | |||
| 109 | + | <arg name="seat" type="object" interface="wl_seat"/> | |||
| 110 | + | <arg name="id" type="new_id" interface="zwp_virtual_keyboard_v1"/> | |||
| 111 | + | </request> | |||
| 112 | + | </interface> | |||
| 113 | + | </protocol> | |||
A spec/xml/wlrdatacontrol.xml +281 -0
| @@ -0,0 +1,281 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="wlr_data_control_unstable_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2018 Simon Ser | |||
| 5 | + | Copyright © 2019 Ivan Molodetskikh | |||
| 6 | + | ||||
| 7 | + | Permission to use, copy, modify, distribute, and sell this | |||
| 8 | + | software and its documentation for any purpose is hereby granted | |||
| 9 | + | without fee, provided that the above copyright notice appear in | |||
| 10 | + | all copies and that both that copyright notice and this permission | |||
| 11 | + | notice appear in supporting documentation, and that the name of | |||
| 12 | + | the copyright holders not be used in advertising or publicity | |||
| 13 | + | pertaining to distribution of the software without specific, | |||
| 14 | + | written prior permission. The copyright holders make no | |||
| 15 | + | representations about the suitability of this software for any | |||
| 16 | + | purpose. It is provided "as is" without express or implied | |||
| 17 | + | warranty. | |||
| 18 | + | ||||
| 19 | + | THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | |||
| 20 | + | SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||
| 21 | + | FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | |||
| 22 | + | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||
| 23 | + | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | |||
| 24 | + | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |||
| 25 | + | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |||
| 26 | + | THIS SOFTWARE. | |||
| 27 | + | </copyright> | |||
| 28 | + | ||||
| 29 | + | <description summary="control data devices"> | |||
| 30 | + | This protocol allows a privileged client to control data devices. In | |||
| 31 | + | particular, the client will be able to manage the current selection and take | |||
| 32 | + | the role of a clipboard manager. | |||
| 33 | + | ||||
| 34 | + | Warning! The protocol described in this file is experimental and | |||
| 35 | + | backward incompatible changes may be made. Backward compatible changes | |||
| 36 | + | may be added together with the corresponding interface version bump. | |||
| 37 | + | Backward incompatible changes are done by bumping the version number in | |||
| 38 | + | the protocol and interface names and resetting the interface version. | |||
| 39 | + | Once the protocol is to be declared stable, the 'z' prefix and the | |||
| 40 | + | version number in the protocol and interface names are removed and the | |||
| 41 | + | interface version number is reset. | |||
| 42 | + | ||||
| 43 | + | Note! This protocol is deprecated and not intended for production use. | |||
| 44 | + | For clipboard management, use the ext-data-control-v1 protocol. | |||
| 45 | + | </description> | |||
| 46 | + | ||||
| 47 | + | <interface name="zwlr_data_control_manager_v1" version="2"> | |||
| 48 | + | <description summary="manager to control data devices"> | |||
| 49 | + | This interface is a manager that allows creating per-seat data device | |||
| 50 | + | controls. | |||
| 51 | + | </description> | |||
| 52 | + | ||||
| 53 | + | <request name="create_data_source"> | |||
| 54 | + | <description summary="create a new data source"> | |||
| 55 | + | Create a new data source. | |||
| 56 | + | </description> | |||
| 57 | + | <arg name="id" type="new_id" interface="zwlr_data_control_source_v1" | |||
| 58 | + | summary="data source to create"/> | |||
| 59 | + | </request> | |||
| 60 | + | ||||
| 61 | + | <request name="get_data_device"> | |||
| 62 | + | <description summary="get a data device for a seat"> | |||
| 63 | + | Create a data device that can be used to manage a seat's selection. | |||
| 64 | + | </description> | |||
| 65 | + | <arg name="id" type="new_id" interface="zwlr_data_control_device_v1"/> | |||
| 66 | + | <arg name="seat" type="object" interface="wl_seat"/> | |||
| 67 | + | </request> | |||
| 68 | + | ||||
| 69 | + | <request name="destroy" type="destructor"> | |||
| 70 | + | <description summary="destroy the manager"> | |||
| 71 | + | All objects created by the manager will still remain valid, until their | |||
| 72 | + | appropriate destroy request has been called. | |||
| 73 | + | </description> | |||
| 74 | + | </request> | |||
| 75 | + | </interface> | |||
| 76 | + | ||||
| 77 | + | <interface name="zwlr_data_control_device_v1" version="2"> | |||
| 78 | + | <description summary="manage a data device for a seat"> | |||
| 79 | + | This interface allows a client to manage a seat's selection. | |||
| 80 | + | ||||
| 81 | + | When the seat is destroyed, this object becomes inert. | |||
| 82 | + | </description> | |||
| 83 | + | ||||
| 84 | + | <request name="set_selection"> | |||
| 85 | + | <description summary="copy data to the selection"> | |||
| 86 | + | This request asks the compositor to set the selection to the data from | |||
| 87 | + | the source on behalf of the client. | |||
| 88 | + | ||||
| 89 | + | The given source may not be used in any further set_selection or | |||
| 90 | + | set_primary_selection requests. Attempting to use a previously used | |||
| 91 | + | source is a protocol error. | |||
| 92 | + | ||||
| 93 | + | To unset the selection, set the source to NULL. | |||
| 94 | + | </description> | |||
| 95 | + | <arg name="source" type="object" interface="zwlr_data_control_source_v1" | |||
| 96 | + | allow-null="true"/> | |||
| 97 | + | </request> | |||
| 98 | + | ||||
| 99 | + | <request name="destroy" type="destructor"> | |||
| 100 | + | <description summary="destroy this data device"> | |||
| 101 | + | Destroys the data device object. | |||
| 102 | + | </description> | |||
| 103 | + | </request> | |||
| 104 | + | ||||
| 105 | + | <event name="data_offer"> | |||
| 106 | + | <description summary="introduce a new wlr_data_control_offer"> | |||
| 107 | + | The data_offer event introduces a new wlr_data_control_offer object, | |||
| 108 | + | which will subsequently be used in either the | |||
| 109 | + | wlr_data_control_device.selection event (for the regular clipboard | |||
| 110 | + | selections) or the wlr_data_control_device.primary_selection event (for | |||
| 111 | + | the primary clipboard selections). Immediately following the | |||
| 112 | + | wlr_data_control_device.data_offer event, the new data_offer object | |||
| 113 | + | will send out wlr_data_control_offer.offer events to describe the MIME | |||
| 114 | + | types it offers. | |||
| 115 | + | </description> | |||
| 116 | + | <arg name="id" type="new_id" interface="zwlr_data_control_offer_v1"/> | |||
| 117 | + | </event> | |||
| 118 | + | ||||
| 119 | + | <event name="selection"> | |||
| 120 | + | <description summary="advertise new selection"> | |||
| 121 | + | The selection event is sent out to notify the client of a new | |||
| 122 | + | wlr_data_control_offer for the selection for this device. The | |||
| 123 | + | wlr_data_control_device.data_offer and the wlr_data_control_offer.offer | |||
| 124 | + | events are sent out immediately before this event to introduce the data | |||
| 125 | + | offer object. The selection event is sent to a client when a new | |||
| 126 | + | selection is set. The wlr_data_control_offer is valid until a new | |||
| 127 | + | wlr_data_control_offer or NULL is received. The client must destroy the | |||
| 128 | + | previous selection wlr_data_control_offer, if any, upon receiving this | |||
| 129 | + | event. | |||
| 130 | + | ||||
| 131 | + | The first selection event is sent upon binding the | |||
| 132 | + | wlr_data_control_device object. | |||
| 133 | + | </description> | |||
| 134 | + | <arg name="id" type="object" interface="zwlr_data_control_offer_v1" | |||
| 135 | + | allow-null="true"/> | |||
| 136 | + | </event> | |||
| 137 | + | ||||
| 138 | + | <event name="finished"> | |||
| 139 | + | <description summary="this data control is no longer valid"> | |||
| 140 | + | This data control object is no longer valid and should be destroyed by | |||
| 141 | + | the client. | |||
| 142 | + | </description> | |||
| 143 | + | </event> | |||
| 144 | + | ||||
| 145 | + | <!-- Version 2 additions --> | |||
| 146 | + | ||||
| 147 | + | <event name="primary_selection" since="2"> | |||
| 148 | + | <description summary="advertise new primary selection"> | |||
| 149 | + | The primary_selection event is sent out to notify the client of a new | |||
| 150 | + | wlr_data_control_offer for the primary selection for this device. The | |||
| 151 | + | wlr_data_control_device.data_offer and the wlr_data_control_offer.offer | |||
| 152 | + | events are sent out immediately before this event to introduce the data | |||
| 153 | + | offer object. The primary_selection event is sent to a client when a | |||
| 154 | + | new primary selection is set. The wlr_data_control_offer is valid until | |||
| 155 | + | a new wlr_data_control_offer or NULL is received. The client must | |||
| 156 | + | destroy the previous primary selection wlr_data_control_offer, if any, | |||
| 157 | + | upon receiving this event. | |||
| 158 | + | ||||
| 159 | + | If the compositor supports primary selection, the first | |||
| 160 | + | primary_selection event is sent upon binding the | |||
| 161 | + | wlr_data_control_device object. | |||
| 162 | + | </description> | |||
| 163 | + | <arg name="id" type="object" interface="zwlr_data_control_offer_v1" | |||
| 164 | + | allow-null="true"/> | |||
| 165 | + | </event> | |||
| 166 | + | ||||
| 167 | + | <request name="set_primary_selection" since="2"> | |||
| 168 | + | <description summary="copy data to the primary selection"> | |||
| 169 | + | This request asks the compositor to set the primary selection to the | |||
| 170 | + | data from the source on behalf of the client. | |||
| 171 | + | ||||
| 172 | + | The given source may not be used in any further set_selection or | |||
| 173 | + | set_primary_selection requests. Attempting to use a previously used | |||
| 174 | + | source is a protocol error. | |||
| 175 | + | ||||
| 176 | + | To unset the primary selection, set the source to NULL. | |||
| 177 | + | ||||
| 178 | + | The compositor will ignore this request if it does not support primary | |||
| 179 | + | selection. | |||
| 180 | + | </description> | |||
| 181 | + | <arg name="source" type="object" interface="zwlr_data_control_source_v1" | |||
| 182 | + | allow-null="true"/> | |||
| 183 | + | </request> | |||
| 184 | + | ||||
| 185 | + | <enum name="error" since="2"> | |||
| 186 | + | <entry name="used_source" value="1" | |||
| 187 | + | summary="source given to set_selection or set_primary_selection was already used before"/> | |||
| 188 | + | </enum> | |||
| 189 | + | </interface> | |||
| 190 | + | ||||
| 191 | + | <interface name="zwlr_data_control_source_v1" version="1"> | |||
| 192 | + | <description summary="offer to transfer data"> | |||
| 193 | + | The wlr_data_control_source object is the source side of a | |||
| 194 | + | wlr_data_control_offer. It is created by the source client in a data | |||
| 195 | + | transfer and provides a way to describe the offered data and a way to | |||
| 196 | + | respond to requests to transfer the data. | |||
| 197 | + | </description> | |||
| 198 | + | ||||
| 199 | + | <enum name="error"> | |||
| 200 | + | <entry name="invalid_offer" value="1" | |||
| 201 | + | summary="offer sent after wlr_data_control_device.set_selection"/> | |||
| 202 | + | </enum> | |||
| 203 | + | ||||
| 204 | + | <request name="offer"> | |||
| 205 | + | <description summary="add an offered MIME type"> | |||
| 206 | + | This request adds a MIME type to the set of MIME types advertised to | |||
| 207 | + | targets. Can be called several times to offer multiple types. | |||
| 208 | + | ||||
| 209 | + | Calling this after wlr_data_control_device.set_selection is a protocol | |||
| 210 | + | error. | |||
| 211 | + | </description> | |||
| 212 | + | <arg name="mime_type" type="string" | |||
| 213 | + | summary="MIME type offered by the data source"/> | |||
| 214 | + | </request> | |||
| 215 | + | ||||
| 216 | + | <request name="destroy" type="destructor"> | |||
| 217 | + | <description summary="destroy this source"> | |||
| 218 | + | Destroys the data source object. | |||
| 219 | + | </description> | |||
| 220 | + | </request> | |||
| 221 | + | ||||
| 222 | + | <event name="send"> | |||
| 223 | + | <description summary="send the data"> | |||
| 224 | + | Request for data from the client. Send the data as the specified MIME | |||
| 225 | + | type over the passed file descriptor, then close it. | |||
| 226 | + | </description> | |||
| 227 | + | <arg name="mime_type" type="string" summary="MIME type for the data"/> | |||
| 228 | + | <arg name="fd" type="fd" summary="file descriptor for the data"/> | |||
| 229 | + | </event> | |||
| 230 | + | ||||
| 231 | + | <event name="cancelled"> | |||
| 232 | + | <description summary="selection was cancelled"> | |||
| 233 | + | This data source is no longer valid. The data source has been replaced | |||
| 234 | + | by another data source. | |||
| 235 | + | ||||
| 236 | + | The client should clean up and destroy this data source. | |||
| 237 | + | </description> | |||
| 238 | + | </event> | |||
| 239 | + | </interface> | |||
| 240 | + | ||||
| 241 | + | <interface name="zwlr_data_control_offer_v1" version="1"> | |||
| 242 | + | <description summary="offer to transfer data"> | |||
| 243 | + | A wlr_data_control_offer represents a piece of data offered for transfer | |||
| 244 | + | by another client (the source client). The offer describes the different | |||
| 245 | + | MIME types that the data can be converted to and provides the mechanism | |||
| 246 | + | for transferring the data directly from the source client. | |||
| 247 | + | </description> | |||
| 248 | + | ||||
| 249 | + | <request name="receive"> | |||
| 250 | + | <description summary="request that the data is transferred"> | |||
| 251 | + | To transfer the offered data, the client issues this request and | |||
| 252 | + | indicates the MIME type it wants to receive. The transfer happens | |||
| 253 | + | through the passed file descriptor (typically created with the pipe | |||
| 254 | + | system call). The source client writes the data in the MIME type | |||
| 255 | + | representation requested and then closes the file descriptor. | |||
| 256 | + | ||||
| 257 | + | The receiving client reads from the read end of the pipe until EOF and | |||
| 258 | + | then closes its end, at which point the transfer is complete. | |||
| 259 | + | ||||
| 260 | + | This request may happen multiple times for different MIME types. | |||
| 261 | + | </description> | |||
| 262 | + | <arg name="mime_type" type="string" | |||
| 263 | + | summary="MIME type desired by receiver"/> | |||
| 264 | + | <arg name="fd" type="fd" summary="file descriptor for data transfer"/> | |||
| 265 | + | </request> | |||
| 266 | + | ||||
| 267 | + | <request name="destroy" type="destructor"> | |||
| 268 | + | <description summary="destroy this offer"> | |||
| 269 | + | Destroys the data offer object. | |||
| 270 | + | </description> | |||
| 271 | + | </request> | |||
| 272 | + | ||||
| 273 | + | <event name="offer"> | |||
| 274 | + | <description summary="advertise offered MIME type"> | |||
| 275 | + | Sent immediately after creating the wlr_data_control_offer object. | |||
| 276 | + | One event per offered MIME type. | |||
| 277 | + | </description> | |||
| 278 | + | <arg name="mime_type" type="string" summary="offered MIME type"/> | |||
| 279 | + | </event> | |||
| 280 | + | </interface> | |||
| 281 | + | </protocol> | |||
A spec/xml/wlrexportdmabuf.xml +203 -0
| @@ -0,0 +1,203 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="wlr_export_dmabuf_unstable_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2018 Rostislav Pehlivanov | |||
| 5 | + | ||||
| 6 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 7 | + | copy of this software and associated documentation files (the "Software"), | |||
| 8 | + | to deal in the Software without restriction, including without limitation | |||
| 9 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 10 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 11 | + | Software is furnished to do so, subject to the following conditions: | |||
| 12 | + | ||||
| 13 | + | The above copyright notice and this permission notice (including the next | |||
| 14 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 15 | + | Software. | |||
| 16 | + | ||||
| 17 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 18 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 19 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 20 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 21 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 22 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 23 | + | DEALINGS IN THE SOFTWARE. | |||
| 24 | + | </copyright> | |||
| 25 | + | ||||
| 26 | + | <description summary="a protocol for low overhead screen content capturing"> | |||
| 27 | + | An interface to capture surfaces in an efficient way by exporting DMA-BUFs. | |||
| 28 | + | ||||
| 29 | + | Warning! The protocol described in this file is experimental and | |||
| 30 | + | backward incompatible changes may be made. Backward compatible changes | |||
| 31 | + | may be added together with the corresponding interface version bump. | |||
| 32 | + | Backward incompatible changes are done by bumping the version number in | |||
| 33 | + | the protocol and interface names and resetting the interface version. | |||
| 34 | + | Once the protocol is to be declared stable, the 'z' prefix and the | |||
| 35 | + | version number in the protocol and interface names are removed and the | |||
| 36 | + | interface version number is reset. | |||
| 37 | + | </description> | |||
| 38 | + | ||||
| 39 | + | <interface name="zwlr_export_dmabuf_manager_v1" version="1"> | |||
| 40 | + | <description summary="manager to inform clients and begin capturing"> | |||
| 41 | + | This object is a manager with which to start capturing from sources. | |||
| 42 | + | </description> | |||
| 43 | + | ||||
| 44 | + | <request name="capture_output"> | |||
| 45 | + | <description summary="capture a frame from an output"> | |||
| 46 | + | Capture the next frame of an entire output. | |||
| 47 | + | </description> | |||
| 48 | + | <arg name="frame" type="new_id" interface="zwlr_export_dmabuf_frame_v1"/> | |||
| 49 | + | <arg name="overlay_cursor" type="int" | |||
| 50 | + | summary="include custom client hardware cursor on top of the frame"/> | |||
| 51 | + | <arg name="output" type="object" interface="wl_output"/> | |||
| 52 | + | </request> | |||
| 53 | + | ||||
| 54 | + | <request name="destroy" type="destructor"> | |||
| 55 | + | <description summary="destroy the manager"> | |||
| 56 | + | All objects created by the manager will still remain valid, until their | |||
| 57 | + | appropriate destroy request has been called. | |||
| 58 | + | </description> | |||
| 59 | + | </request> | |||
| 60 | + | </interface> | |||
| 61 | + | ||||
| 62 | + | <interface name="zwlr_export_dmabuf_frame_v1" version="1"> | |||
| 63 | + | <description summary="a DMA-BUF frame"> | |||
| 64 | + | This object represents a single DMA-BUF frame. | |||
| 65 | + | ||||
| 66 | + | If the capture is successful, the compositor will first send a "frame" | |||
| 67 | + | event, followed by one or several "object". When the frame is available | |||
| 68 | + | for readout, the "ready" event is sent. | |||
| 69 | + | ||||
| 70 | + | If the capture failed, the "cancel" event is sent. This can happen anytime | |||
| 71 | + | before the "ready" event. | |||
| 72 | + | ||||
| 73 | + | Once either a "ready" or a "cancel" event is received, the client should | |||
| 74 | + | destroy the frame. Once an "object" event is received, the client is | |||
| 75 | + | responsible for closing the associated file descriptor. | |||
| 76 | + | ||||
| 77 | + | All frames are read-only and may not be written into or altered. | |||
| 78 | + | </description> | |||
| 79 | + | ||||
| 80 | + | <enum name="flags"> | |||
| 81 | + | <description summary="frame flags"> | |||
| 82 | + | Special flags that should be respected by the client. | |||
| 83 | + | </description> | |||
| 84 | + | <entry name="transient" value="0x1" | |||
| 85 | + | summary="clients should copy frame before processing"/> | |||
| 86 | + | </enum> | |||
| 87 | + | ||||
| 88 | + | <event name="frame"> | |||
| 89 | + | <description summary="a frame description"> | |||
| 90 | + | Main event supplying the client with information about the frame. If the | |||
| 91 | + | capture didn't fail, this event is always emitted first before any other | |||
| 92 | + | events. | |||
| 93 | + | ||||
| 94 | + | This event is followed by a number of "object" as specified by the | |||
| 95 | + | "num_objects" argument. | |||
| 96 | + | </description> | |||
| 97 | + | <arg name="width" type="uint" | |||
| 98 | + | summary="frame width in pixels"/> | |||
| 99 | + | <arg name="height" type="uint" | |||
| 100 | + | summary="frame height in pixels"/> | |||
| 101 | + | <arg name="offset_x" type="uint" | |||
| 102 | + | summary="crop offset for the x axis"/> | |||
| 103 | + | <arg name="offset_y" type="uint" | |||
| 104 | + | summary="crop offset for the y axis"/> | |||
| 105 | + | <arg name="buffer_flags" type="uint" | |||
| 106 | + | summary="flags which indicate properties (invert, interlacing), | |||
| 107 | + | has the same values as zwp_linux_buffer_params_v1:flags"/> | |||
| 108 | + | <arg name="flags" type="uint" enum="flags" | |||
| 109 | + | summary="indicates special frame features"/> | |||
| 110 | + | <arg name="format" type="uint" | |||
| 111 | + | summary="format of the frame (DRM_FORMAT_*)"/> | |||
| 112 | + | <arg name="mod_high" type="uint" | |||
| 113 | + | summary="drm format modifier, high"/> | |||
| 114 | + | <arg name="mod_low" type="uint" | |||
| 115 | + | summary="drm format modifier, low"/> | |||
| 116 | + | <arg name="num_objects" type="uint" | |||
| 117 | + | summary="indicates how many objects (FDs) the frame has (max 4)"/> | |||
| 118 | + | </event> | |||
| 119 | + | ||||
| 120 | + | <event name="object"> | |||
| 121 | + | <description summary="an object description"> | |||
| 122 | + | Event which serves to supply the client with the file descriptors | |||
| 123 | + | containing the data for each object. | |||
| 124 | + | ||||
| 125 | + | After receiving this event, the client must always close the file | |||
| 126 | + | descriptor as soon as they're done with it and even if the frame fails. | |||
| 127 | + | </description> | |||
| 128 | + | <arg name="index" type="uint" | |||
| 129 | + | summary="index of the current object"/> | |||
| 130 | + | <arg name="fd" type="fd" | |||
| 131 | + | summary="fd of the current object"/> | |||
| 132 | + | <arg name="size" type="uint" | |||
| 133 | + | summary="size in bytes for the current object"/> | |||
| 134 | + | <arg name="offset" type="uint" | |||
| 135 | + | summary="starting point for the data in the object's fd"/> | |||
| 136 | + | <arg name="stride" type="uint" | |||
| 137 | + | summary="line size in bytes"/> | |||
| 138 | + | <arg name="plane_index" type="uint" | |||
| 139 | + | summary="index of the plane the data in the object applies to"/> | |||
| 140 | + | </event> | |||
| 141 | + | ||||
| 142 | + | <event name="ready"> | |||
| 143 | + | <description summary="indicates frame is available for reading"> | |||
| 144 | + | This event is sent as soon as the frame is presented, indicating it is | |||
| 145 | + | available for reading. This event includes the time at which | |||
| 146 | + | presentation happened at. | |||
| 147 | + | ||||
| 148 | + | The timestamp is expressed as tv_sec_hi, tv_sec_lo, tv_nsec triples, | |||
| 149 | + | each component being an unsigned 32-bit value. Whole seconds are in | |||
| 150 | + | tv_sec which is a 64-bit value combined from tv_sec_hi and tv_sec_lo, | |||
| 151 | + | and the additional fractional part in tv_nsec as nanoseconds. Hence, | |||
| 152 | + | for valid timestamps tv_nsec must be in [0, 999999999]. The seconds part | |||
| 153 | + | may have an arbitrary offset at start. | |||
| 154 | + | ||||
| 155 | + | After receiving this event, the client should destroy this object. | |||
| 156 | + | </description> | |||
| 157 | + | <arg name="tv_sec_hi" type="uint" | |||
| 158 | + | summary="high 32 bits of the seconds part of the timestamp"/> | |||
| 159 | + | <arg name="tv_sec_lo" type="uint" | |||
| 160 | + | summary="low 32 bits of the seconds part of the timestamp"/> | |||
| 161 | + | <arg name="tv_nsec" type="uint" | |||
| 162 | + | summary="nanoseconds part of the timestamp"/> | |||
| 163 | + | </event> | |||
| 164 | + | ||||
| 165 | + | <enum name="cancel_reason"> | |||
| 166 | + | <description summary="cancel reason"> | |||
| 167 | + | Indicates reason for cancelling the frame. | |||
| 168 | + | </description> | |||
| 169 | + | <entry name="temporary" value="0" | |||
| 170 | + | summary="temporary error, source will produce more frames"/> | |||
| 171 | + | <entry name="permanent" value="1" | |||
| 172 | + | summary="fatal error, source will not produce frames"/> | |||
| 173 | + | <entry name="resizing" value="2" | |||
| 174 | + | summary="temporary error, source will produce more frames"/> | |||
| 175 | + | </enum> | |||
| 176 | + | ||||
| 177 | + | <event name="cancel"> | |||
| 178 | + | <description summary="indicates the frame is no longer valid"> | |||
| 179 | + | If the capture failed or if the frame is no longer valid after the | |||
| 180 | + | "frame" event has been emitted, this event will be used to inform the | |||
| 181 | + | client to scrap the frame. | |||
| 182 | + | ||||
| 183 | + | If the failure is temporary, the client may capture again the same | |||
| 184 | + | source. If the failure is permanent, any further attempts to capture the | |||
| 185 | + | same source will fail again. | |||
| 186 | + | ||||
| 187 | + | After receiving this event, the client should destroy this object. | |||
| 188 | + | </description> | |||
| 189 | + | <arg name="reason" type="uint" enum="cancel_reason" | |||
| 190 | + | summary="indicates a reason for cancelling this frame capture"/> | |||
| 191 | + | </event> | |||
| 192 | + | ||||
| 193 | + | <request name="destroy" type="destructor"> | |||
| 194 | + | <description summary="delete this object, used or not"> | |||
| 195 | + | Unreferences the frame. This request must be called as soon as it's no | |||
| 196 | + | longer used. | |||
| 197 | + | ||||
| 198 | + | It can be called at any time by the client. The client will still have | |||
| 199 | + | to close any FDs it has been given. | |||
| 200 | + | </description> | |||
| 201 | + | </request> | |||
| 202 | + | </interface> | |||
| 203 | + | </protocol> | |||
A spec/xml/wlrforeigntoplevelmanagement.xml +270 -0
| @@ -0,0 +1,270 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="wlr_foreign_toplevel_management_unstable_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2018 Ilia Bozhinov | |||
| 5 | + | ||||
| 6 | + | Permission to use, copy, modify, distribute, and sell this | |||
| 7 | + | software and its documentation for any purpose is hereby granted | |||
| 8 | + | without fee, provided that the above copyright notice appear in | |||
| 9 | + | all copies and that both that copyright notice and this permission | |||
| 10 | + | notice appear in supporting documentation, and that the name of | |||
| 11 | + | the copyright holders not be used in advertising or publicity | |||
| 12 | + | pertaining to distribution of the software without specific, | |||
| 13 | + | written prior permission. The copyright holders make no | |||
| 14 | + | representations about the suitability of this software for any | |||
| 15 | + | purpose. It is provided "as is" without express or implied | |||
| 16 | + | warranty. | |||
| 17 | + | ||||
| 18 | + | THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | |||
| 19 | + | SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||
| 20 | + | FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | |||
| 21 | + | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||
| 22 | + | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | |||
| 23 | + | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |||
| 24 | + | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |||
| 25 | + | THIS SOFTWARE. | |||
| 26 | + | </copyright> | |||
| 27 | + | ||||
| 28 | + | <interface name="zwlr_foreign_toplevel_manager_v1" version="3"> | |||
| 29 | + | <description summary="list and control opened apps"> | |||
| 30 | + | The purpose of this protocol is to enable the creation of taskbars | |||
| 31 | + | and docks by providing them with a list of opened applications and | |||
| 32 | + | letting them request certain actions on them, like maximizing, etc. | |||
| 33 | + | ||||
| 34 | + | After a client binds the zwlr_foreign_toplevel_manager_v1, each opened | |||
| 35 | + | toplevel window will be sent via the toplevel event | |||
| 36 | + | </description> | |||
| 37 | + | ||||
| 38 | + | <event name="toplevel"> | |||
| 39 | + | <description summary="a toplevel has been created"> | |||
| 40 | + | This event is emitted whenever a new toplevel window is created. It | |||
| 41 | + | is emitted for all toplevels, regardless of the app that has created | |||
| 42 | + | them. | |||
| 43 | + | ||||
| 44 | + | All initial details of the toplevel(title, app_id, states, etc.) will | |||
| 45 | + | be sent immediately after this event via the corresponding events in | |||
| 46 | + | zwlr_foreign_toplevel_handle_v1. | |||
| 47 | + | </description> | |||
| 48 | + | <arg name="toplevel" type="new_id" interface="zwlr_foreign_toplevel_handle_v1"/> | |||
| 49 | + | </event> | |||
| 50 | + | ||||
| 51 | + | <request name="stop"> | |||
| 52 | + | <description summary="stop sending events"> | |||
| 53 | + | Indicates the client no longer wishes to receive events for new toplevels. | |||
| 54 | + | However the compositor may emit further toplevel_created events, until | |||
| 55 | + | the finished event is emitted. | |||
| 56 | + | ||||
| 57 | + | The client must not send any more requests after this one. | |||
| 58 | + | </description> | |||
| 59 | + | </request> | |||
| 60 | + | ||||
| 61 | + | <event name="finished" type="destructor"> | |||
| 62 | + | <description summary="the compositor has finished with the toplevel manager"> | |||
| 63 | + | This event indicates that the compositor is done sending events to the | |||
| 64 | + | zwlr_foreign_toplevel_manager_v1. The server will destroy the object | |||
| 65 | + | immediately after sending this request, so it will become invalid and | |||
| 66 | + | the client should free any resources associated with it. | |||
| 67 | + | </description> | |||
| 68 | + | </event> | |||
| 69 | + | </interface> | |||
| 70 | + | ||||
| 71 | + | <interface name="zwlr_foreign_toplevel_handle_v1" version="3"> | |||
| 72 | + | <description summary="an opened toplevel"> | |||
| 73 | + | A zwlr_foreign_toplevel_handle_v1 object represents an opened toplevel | |||
| 74 | + | window. Each app may have multiple opened toplevels. | |||
| 75 | + | ||||
| 76 | + | Each toplevel has a list of outputs it is visible on, conveyed to the | |||
| 77 | + | client with the output_enter and output_leave events. | |||
| 78 | + | </description> | |||
| 79 | + | ||||
| 80 | + | <event name="title"> | |||
| 81 | + | <description summary="title change"> | |||
| 82 | + | This event is emitted whenever the title of the toplevel changes. | |||
| 83 | + | </description> | |||
| 84 | + | <arg name="title" type="string"/> | |||
| 85 | + | </event> | |||
| 86 | + | ||||
| 87 | + | <event name="app_id"> | |||
| 88 | + | <description summary="app-id change"> | |||
| 89 | + | This event is emitted whenever the app-id of the toplevel changes. | |||
| 90 | + | </description> | |||
| 91 | + | <arg name="app_id" type="string"/> | |||
| 92 | + | </event> | |||
| 93 | + | ||||
| 94 | + | <event name="output_enter"> | |||
| 95 | + | <description summary="toplevel entered an output"> | |||
| 96 | + | This event is emitted whenever the toplevel becomes visible on | |||
| 97 | + | the given output. A toplevel may be visible on multiple outputs. | |||
| 98 | + | </description> | |||
| 99 | + | <arg name="output" type="object" interface="wl_output"/> | |||
| 100 | + | </event> | |||
| 101 | + | ||||
| 102 | + | <event name="output_leave"> | |||
| 103 | + | <description summary="toplevel left an output"> | |||
| 104 | + | This event is emitted whenever the toplevel stops being visible on | |||
| 105 | + | the given output. It is guaranteed that an entered-output event | |||
| 106 | + | with the same output has been emitted before this event. | |||
| 107 | + | </description> | |||
| 108 | + | <arg name="output" type="object" interface="wl_output"/> | |||
| 109 | + | </event> | |||
| 110 | + | ||||
| 111 | + | <request name="set_maximized"> | |||
| 112 | + | <description summary="requests that the toplevel be maximized"> | |||
| 113 | + | Requests that the toplevel be maximized. If the maximized state actually | |||
| 114 | + | changes, this will be indicated by the state event. | |||
| 115 | + | </description> | |||
| 116 | + | </request> | |||
| 117 | + | ||||
| 118 | + | <request name="unset_maximized"> | |||
| 119 | + | <description summary="requests that the toplevel be unmaximized"> | |||
| 120 | + | Requests that the toplevel be unmaximized. If the maximized state actually | |||
| 121 | + | changes, this will be indicated by the state event. | |||
| 122 | + | </description> | |||
| 123 | + | </request> | |||
| 124 | + | ||||
| 125 | + | <request name="set_minimized"> | |||
| 126 | + | <description summary="requests that the toplevel be minimized"> | |||
| 127 | + | Requests that the toplevel be minimized. If the minimized state actually | |||
| 128 | + | changes, this will be indicated by the state event. | |||
| 129 | + | </description> | |||
| 130 | + | </request> | |||
| 131 | + | ||||
| 132 | + | <request name="unset_minimized"> | |||
| 133 | + | <description summary="requests that the toplevel be unminimized"> | |||
| 134 | + | Requests that the toplevel be unminimized. If the minimized state actually | |||
| 135 | + | changes, this will be indicated by the state event. | |||
| 136 | + | </description> | |||
| 137 | + | </request> | |||
| 138 | + | ||||
| 139 | + | <request name="activate"> | |||
| 140 | + | <description summary="activate the toplevel"> | |||
| 141 | + | Request that this toplevel be activated on the given seat. | |||
| 142 | + | There is no guarantee the toplevel will be actually activated. | |||
| 143 | + | </description> | |||
| 144 | + | <arg name="seat" type="object" interface="wl_seat"/> | |||
| 145 | + | </request> | |||
| 146 | + | ||||
| 147 | + | <enum name="state"> | |||
| 148 | + | <description summary="types of states on the toplevel"> | |||
| 149 | + | The different states that a toplevel can have. These have the same meaning | |||
| 150 | + | as the states with the same names defined in xdg-toplevel | |||
| 151 | + | </description> | |||
| 152 | + | ||||
| 153 | + | <entry name="maximized" value="0" summary="the toplevel is maximized"/> | |||
| 154 | + | <entry name="minimized" value="1" summary="the toplevel is minimized"/> | |||
| 155 | + | <entry name="activated" value="2" summary="the toplevel is active"/> | |||
| 156 | + | <entry name="fullscreen" value="3" summary="the toplevel is fullscreen" since="2"/> | |||
| 157 | + | </enum> | |||
| 158 | + | ||||
| 159 | + | <event name="state"> | |||
| 160 | + | <description summary="the toplevel state changed"> | |||
| 161 | + | This event is emitted immediately after the zlw_foreign_toplevel_handle_v1 | |||
| 162 | + | is created and each time the toplevel state changes, either because of a | |||
| 163 | + | compositor action or because of a request in this protocol. | |||
| 164 | + | </description> | |||
| 165 | + | ||||
| 166 | + | <arg name="state" type="array"/> | |||
| 167 | + | </event> | |||
| 168 | + | ||||
| 169 | + | <event name="done"> | |||
| 170 | + | <description summary="all information about the toplevel has been sent"> | |||
| 171 | + | This event is sent after all changes in the toplevel state have been | |||
| 172 | + | sent. | |||
| 173 | + | ||||
| 174 | + | This allows changes to the zwlr_foreign_toplevel_handle_v1 properties | |||
| 175 | + | to be seen as atomic, even if they happen via multiple events. | |||
| 176 | + | </description> | |||
| 177 | + | </event> | |||
| 178 | + | ||||
| 179 | + | <request name="close"> | |||
| 180 | + | <description summary="request that the toplevel be closed"> | |||
| 181 | + | Send a request to the toplevel to close itself. The compositor would | |||
| 182 | + | typically use a shell-specific method to carry out this request, for | |||
| 183 | + | example by sending the xdg_toplevel.close event. However, this gives | |||
| 184 | + | no guarantees the toplevel will actually be destroyed. If and when | |||
| 185 | + | this happens, the zwlr_foreign_toplevel_handle_v1.closed event will | |||
| 186 | + | be emitted. | |||
| 187 | + | </description> | |||
| 188 | + | </request> | |||
| 189 | + | ||||
| 190 | + | <request name="set_rectangle"> | |||
| 191 | + | <description summary="the rectangle which represents the toplevel"> | |||
| 192 | + | The rectangle of the surface specified in this request corresponds to | |||
| 193 | + | the place where the app using this protocol represents the given toplevel. | |||
| 194 | + | It can be used by the compositor as a hint for some operations, e.g | |||
| 195 | + | minimizing. The client is however not required to set this, in which | |||
| 196 | + | case the compositor is free to decide some default value. | |||
| 197 | + | ||||
| 198 | + | If the client specifies more than one rectangle, only the last one is | |||
| 199 | + | considered. | |||
| 200 | + | ||||
| 201 | + | The dimensions are given in surface-local coordinates. | |||
| 202 | + | Setting width=height=0 removes the already-set rectangle. | |||
| 203 | + | </description> | |||
| 204 | + | ||||
| 205 | + | <arg name="surface" type="object" interface="wl_surface"/> | |||
| 206 | + | <arg name="x" type="int"/> | |||
| 207 | + | <arg name="y" type="int"/> | |||
| 208 | + | <arg name="width" type="int"/> | |||
| 209 | + | <arg name="height" type="int"/> | |||
| 210 | + | </request> | |||
| 211 | + | ||||
| 212 | + | <enum name="error"> | |||
| 213 | + | <entry name="invalid_rectangle" value="0" | |||
| 214 | + | summary="the provided rectangle is invalid"/> | |||
| 215 | + | </enum> | |||
| 216 | + | ||||
| 217 | + | <event name="closed"> | |||
| 218 | + | <description summary="this toplevel has been destroyed"> | |||
| 219 | + | This event means the toplevel has been destroyed. It is guaranteed there | |||
| 220 | + | won't be any more events for this zwlr_foreign_toplevel_handle_v1. The | |||
| 221 | + | toplevel itself becomes inert so any requests will be ignored except the | |||
| 222 | + | destroy request. | |||
| 223 | + | </description> | |||
| 224 | + | </event> | |||
| 225 | + | ||||
| 226 | + | <request name="destroy" type="destructor"> | |||
| 227 | + | <description summary="destroy the zwlr_foreign_toplevel_handle_v1 object"> | |||
| 228 | + | Destroys the zwlr_foreign_toplevel_handle_v1 object. | |||
| 229 | + | ||||
| 230 | + | This request should be called either when the client does not want to | |||
| 231 | + | use the toplevel anymore or after the closed event to finalize the | |||
| 232 | + | destruction of the object. | |||
| 233 | + | </description> | |||
| 234 | + | </request> | |||
| 235 | + | ||||
| 236 | + | <!-- Version 2 additions --> | |||
| 237 | + | ||||
| 238 | + | <request name="set_fullscreen" since="2"> | |||
| 239 | + | <description summary="request that the toplevel be fullscreened"> | |||
| 240 | + | Requests that the toplevel be fullscreened on the given output. If the | |||
| 241 | + | fullscreen state and/or the outputs the toplevel is visible on actually | |||
| 242 | + | change, this will be indicated by the state and output_enter/leave | |||
| 243 | + | events. | |||
| 244 | + | ||||
| 245 | + | The output parameter is only a hint to the compositor. Also, if output | |||
| 246 | + | is NULL, the compositor should decide which output the toplevel will be | |||
| 247 | + | fullscreened on, if at all. | |||
| 248 | + | </description> | |||
| 249 | + | <arg name="output" type="object" interface="wl_output" allow-null="true"/> | |||
| 250 | + | </request> | |||
| 251 | + | ||||
| 252 | + | <request name="unset_fullscreen" since="2"> | |||
| 253 | + | <description summary="request that the toplevel be unfullscreened"> | |||
| 254 | + | Requests that the toplevel be unfullscreened. If the fullscreen state | |||
| 255 | + | actually changes, this will be indicated by the state event. | |||
| 256 | + | </description> | |||
| 257 | + | </request> | |||
| 258 | + | ||||
| 259 | + | <!-- Version 3 additions --> | |||
| 260 | + | ||||
| 261 | + | <event name="parent" since="3"> | |||
| 262 | + | <description summary="parent change"> | |||
| 263 | + | This event is emitted whenever the parent of the toplevel changes. | |||
| 264 | + | ||||
| 265 | + | No event is emitted when the parent handle is destroyed by the client. | |||
| 266 | + | </description> | |||
| 267 | + | <arg name="parent" type="object" interface="zwlr_foreign_toplevel_handle_v1" allow-null="true"/> | |||
| 268 | + | </event> | |||
| 269 | + | </interface> | |||
| 270 | + | </protocol> | |||
A spec/xml/wlrgammacontrol.xml +126 -0
| @@ -0,0 +1,126 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="wlr_gamma_control_unstable_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2015 Giulio camuffo | |||
| 5 | + | Copyright © 2018 Simon Ser | |||
| 6 | + | ||||
| 7 | + | Permission to use, copy, modify, distribute, and sell this | |||
| 8 | + | software and its documentation for any purpose is hereby granted | |||
| 9 | + | without fee, provided that the above copyright notice appear in | |||
| 10 | + | all copies and that both that copyright notice and this permission | |||
| 11 | + | notice appear in supporting documentation, and that the name of | |||
| 12 | + | the copyright holders not be used in advertising or publicity | |||
| 13 | + | pertaining to distribution of the software without specific, | |||
| 14 | + | written prior permission. The copyright holders make no | |||
| 15 | + | representations about the suitability of this software for any | |||
| 16 | + | purpose. It is provided "as is" without express or implied | |||
| 17 | + | warranty. | |||
| 18 | + | ||||
| 19 | + | THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | |||
| 20 | + | SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||
| 21 | + | FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | |||
| 22 | + | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||
| 23 | + | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | |||
| 24 | + | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |||
| 25 | + | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |||
| 26 | + | THIS SOFTWARE. | |||
| 27 | + | </copyright> | |||
| 28 | + | ||||
| 29 | + | <description summary="manage gamma tables of outputs"> | |||
| 30 | + | This protocol allows a privileged client to set the gamma tables for | |||
| 31 | + | outputs. | |||
| 32 | + | ||||
| 33 | + | Warning! The protocol described in this file is experimental and | |||
| 34 | + | backward incompatible changes may be made. Backward compatible changes | |||
| 35 | + | may be added together with the corresponding interface version bump. | |||
| 36 | + | Backward incompatible changes are done by bumping the version number in | |||
| 37 | + | the protocol and interface names and resetting the interface version. | |||
| 38 | + | Once the protocol is to be declared stable, the 'z' prefix and the | |||
| 39 | + | version number in the protocol and interface names are removed and the | |||
| 40 | + | interface version number is reset. | |||
| 41 | + | </description> | |||
| 42 | + | ||||
| 43 | + | <interface name="zwlr_gamma_control_manager_v1" version="1"> | |||
| 44 | + | <description summary="manager to create per-output gamma controls"> | |||
| 45 | + | This interface is a manager that allows creating per-output gamma | |||
| 46 | + | controls. | |||
| 47 | + | </description> | |||
| 48 | + | ||||
| 49 | + | <request name="get_gamma_control"> | |||
| 50 | + | <description summary="get a gamma control for an output"> | |||
| 51 | + | Create a gamma control that can be used to adjust gamma tables for the | |||
| 52 | + | provided output. | |||
| 53 | + | </description> | |||
| 54 | + | <arg name="id" type="new_id" interface="zwlr_gamma_control_v1"/> | |||
| 55 | + | <arg name="output" type="object" interface="wl_output"/> | |||
| 56 | + | </request> | |||
| 57 | + | ||||
| 58 | + | <request name="destroy" type="destructor"> | |||
| 59 | + | <description summary="destroy the manager"> | |||
| 60 | + | All objects created by the manager will still remain valid, until their | |||
| 61 | + | appropriate destroy request has been called. | |||
| 62 | + | </description> | |||
| 63 | + | </request> | |||
| 64 | + | </interface> | |||
| 65 | + | ||||
| 66 | + | <interface name="zwlr_gamma_control_v1" version="1"> | |||
| 67 | + | <description summary="adjust gamma tables for an output"> | |||
| 68 | + | This interface allows a client to adjust gamma tables for a particular | |||
| 69 | + | output. | |||
| 70 | + | ||||
| 71 | + | The client will receive the gamma size, and will then be able to set gamma | |||
| 72 | + | tables. At any time the compositor can send a failed event indicating that | |||
| 73 | + | this object is no longer valid. | |||
| 74 | + | ||||
| 75 | + | There can only be at most one gamma control object per output, which | |||
| 76 | + | has exclusive access to this particular output. When the gamma control | |||
| 77 | + | object is destroyed, the gamma table is restored to its original value. | |||
| 78 | + | </description> | |||
| 79 | + | ||||
| 80 | + | <event name="gamma_size"> | |||
| 81 | + | <description summary="size of gamma ramps"> | |||
| 82 | + | Advertise the size of each gamma ramp. | |||
| 83 | + | ||||
| 84 | + | This event is sent immediately when the gamma control object is created. | |||
| 85 | + | </description> | |||
| 86 | + | <arg name="size" type="uint" summary="number of elements in a ramp"/> | |||
| 87 | + | </event> | |||
| 88 | + | ||||
| 89 | + | <enum name="error"> | |||
| 90 | + | <entry name="invalid_gamma" value="1" summary="invalid gamma tables"/> | |||
| 91 | + | </enum> | |||
| 92 | + | ||||
| 93 | + | <request name="set_gamma"> | |||
| 94 | + | <description summary="set the gamma table"> | |||
| 95 | + | Set the gamma table. The file descriptor can be memory-mapped to provide | |||
| 96 | + | the raw gamma table, which contains successive gamma ramps for the red, | |||
| 97 | + | green and blue channels. Each gamma ramp is an array of 16-byte unsigned | |||
| 98 | + | integers which has the same length as the gamma size. | |||
| 99 | + | ||||
| 100 | + | The file descriptor data must have the same length as three times the | |||
| 101 | + | gamma size. | |||
| 102 | + | </description> | |||
| 103 | + | <arg name="fd" type="fd" summary="gamma table file descriptor"/> | |||
| 104 | + | </request> | |||
| 105 | + | ||||
| 106 | + | <event name="failed"> | |||
| 107 | + | <description summary="object no longer valid"> | |||
| 108 | + | This event indicates that the gamma control is no longer valid. This | |||
| 109 | + | can happen for a number of reasons, including: | |||
| 110 | + | - The output doesn't support gamma tables | |||
| 111 | + | - Setting the gamma tables failed | |||
| 112 | + | - Another client already has exclusive gamma control for this output | |||
| 113 | + | - The compositor has transferred gamma control to another client | |||
| 114 | + | ||||
| 115 | + | Upon receiving this event, the client should destroy this object. | |||
| 116 | + | </description> | |||
| 117 | + | </event> | |||
| 118 | + | ||||
| 119 | + | <request name="destroy" type="destructor"> | |||
| 120 | + | <description summary="destroy this control"> | |||
| 121 | + | Destroys the gamma control object. If the object is still valid, this | |||
| 122 | + | restores the original gamma tables. | |||
| 123 | + | </description> | |||
| 124 | + | </request> | |||
| 125 | + | </interface> | |||
| 126 | + | </protocol> | |||
A spec/xml/wlrinputinhibitor.xml +71 -0
| @@ -0,0 +1,71 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="wlr_input_inhibit_unstable_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2018 Drew DeVault | |||
| 5 | + | ||||
| 6 | + | Permission to use, copy, modify, distribute, and sell this | |||
| 7 | + | software and its documentation for any purpose is hereby granted | |||
| 8 | + | without fee, provided that the above copyright notice appear in | |||
| 9 | + | all copies and that both that copyright notice and this permission | |||
| 10 | + | notice appear in supporting documentation, and that the name of | |||
| 11 | + | the copyright holders not be used in advertising or publicity | |||
| 12 | + | pertaining to distribution of the software without specific, | |||
| 13 | + | written prior permission. The copyright holders make no | |||
| 14 | + | representations about the suitability of this software for any | |||
| 15 | + | purpose. It is provided "as is" without express or implied | |||
| 16 | + | warranty. | |||
| 17 | + | ||||
| 18 | + | THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | |||
| 19 | + | SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||
| 20 | + | FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | |||
| 21 | + | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||
| 22 | + | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | |||
| 23 | + | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |||
| 24 | + | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |||
| 25 | + | THIS SOFTWARE. | |||
| 26 | + | </copyright> | |||
| 27 | + | ||||
| 28 | + | <interface name="zwlr_input_inhibit_manager_v1" version="1"> | |||
| 29 | + | <description summary="inhibits input events to other clients"> | |||
| 30 | + | Clients can use this interface to prevent input events from being sent to | |||
| 31 | + | any surfaces but its own, which is useful for example in lock screen | |||
| 32 | + | software. It is assumed that access to this interface will be locked down | |||
| 33 | + | to whitelisted clients by the compositor. | |||
| 34 | + | ||||
| 35 | + | Note! This protocol is deprecated and not intended for production use. | |||
| 36 | + | For screen lockers, use the ext-session-lock-v1 protocol. | |||
| 37 | + | </description> | |||
| 38 | + | ||||
| 39 | + | <request name="get_inhibitor"> | |||
| 40 | + | <description summary="inhibit input to other clients"> | |||
| 41 | + | Activates the input inhibitor. As long as the inhibitor is active, the | |||
| 42 | + | compositor will not send input events to other clients. | |||
| 43 | + | </description> | |||
| 44 | + | <arg name="id" type="new_id" interface="zwlr_input_inhibitor_v1"/> | |||
| 45 | + | </request> | |||
| 46 | + | ||||
| 47 | + | <enum name="error"> | |||
| 48 | + | <entry name="already_inhibited" value="0" summary="an input inhibitor is already in use on the compositor"/> | |||
| 49 | + | </enum> | |||
| 50 | + | </interface> | |||
| 51 | + | ||||
| 52 | + | <interface name="zwlr_input_inhibitor_v1" version="1"> | |||
| 53 | + | <description summary="inhibits input to other clients"> | |||
| 54 | + | While this resource exists, input to clients other than the owner of the | |||
| 55 | + | inhibitor resource will not receive input events. Any client which | |||
| 56 | + | previously had focus will receive a leave event and will not be given | |||
| 57 | + | focus again. The client that owns this resource will receive all input | |||
| 58 | + | events normally. The compositor will also disable all of its own input | |||
| 59 | + | processing (such as keyboard shortcuts) while the inhibitor is active. | |||
| 60 | + | ||||
| 61 | + | The compositor may continue to send input events to selected clients, | |||
| 62 | + | such as an on-screen keyboard (via the input-method protocol). | |||
| 63 | + | </description> | |||
| 64 | + | ||||
| 65 | + | <request name="destroy" type="destructor"> | |||
| 66 | + | <description summary="destroy the input inhibitor object"> | |||
| 67 | + | Destroy the inhibitor and allow other clients to receive input. | |||
| 68 | + | </description> | |||
| 69 | + | </request> | |||
| 70 | + | </interface> | |||
| 71 | + | </protocol> | |||
A spec/xml/wlrlayershell.xml +407 -0
| @@ -0,0 +1,407 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="wlr_layer_shell_unstable_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2017 Drew DeVault | |||
| 5 | + | ||||
| 6 | + | Permission to use, copy, modify, distribute, and sell this | |||
| 7 | + | software and its documentation for any purpose is hereby granted | |||
| 8 | + | without fee, provided that the above copyright notice appear in | |||
| 9 | + | all copies and that both that copyright notice and this permission | |||
| 10 | + | notice appear in supporting documentation, and that the name of | |||
| 11 | + | the copyright holders not be used in advertising or publicity | |||
| 12 | + | pertaining to distribution of the software without specific, | |||
| 13 | + | written prior permission. The copyright holders make no | |||
| 14 | + | representations about the suitability of this software for any | |||
| 15 | + | purpose. It is provided "as is" without express or implied | |||
| 16 | + | warranty. | |||
| 17 | + | ||||
| 18 | + | THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | |||
| 19 | + | SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||
| 20 | + | FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | |||
| 21 | + | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||
| 22 | + | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | |||
| 23 | + | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |||
| 24 | + | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |||
| 25 | + | THIS SOFTWARE. | |||
| 26 | + | </copyright> | |||
| 27 | + | ||||
| 28 | + | <interface name="zwlr_layer_shell_v1" version="5"> | |||
| 29 | + | <description summary="create surfaces that are layers of the desktop"> | |||
| 30 | + | Clients can use this interface to assign the surface_layer role to | |||
| 31 | + | wl_surfaces. Such surfaces are assigned to a "layer" of the output and | |||
| 32 | + | rendered with a defined z-depth respective to each other. They may also be | |||
| 33 | + | anchored to the edges and corners of a screen and specify input handling | |||
| 34 | + | semantics. This interface should be suitable for the implementation of | |||
| 35 | + | many desktop shell components, and a broad number of other applications | |||
| 36 | + | that interact with the desktop. | |||
| 37 | + | </description> | |||
| 38 | + | ||||
| 39 | + | <request name="get_layer_surface"> | |||
| 40 | + | <description summary="create a layer_surface from a surface"> | |||
| 41 | + | Create a layer surface for an existing surface. This assigns the role of | |||
| 42 | + | layer_surface, or raises a protocol error if another role is already | |||
| 43 | + | assigned. | |||
| 44 | + | ||||
| 45 | + | Creating a layer surface from a wl_surface which has a buffer attached | |||
| 46 | + | or committed is a client error, and any attempts by a client to attach | |||
| 47 | + | or manipulate a buffer prior to the first layer_surface.configure call | |||
| 48 | + | must also be treated as errors. | |||
| 49 | + | ||||
| 50 | + | After creating a layer_surface object and setting it up, the client | |||
| 51 | + | must perform an initial commit without any buffer attached. | |||
| 52 | + | The compositor will reply with a layer_surface.configure event. | |||
| 53 | + | The client must acknowledge it and is then allowed to attach a buffer | |||
| 54 | + | to map the surface. | |||
| 55 | + | ||||
| 56 | + | You may pass NULL for output to allow the compositor to decide which | |||
| 57 | + | output to use. Generally this will be the one that the user most | |||
| 58 | + | recently interacted with. | |||
| 59 | + | ||||
| 60 | + | Clients can specify a namespace that defines the purpose of the layer | |||
| 61 | + | surface. | |||
| 62 | + | </description> | |||
| 63 | + | <arg name="id" type="new_id" interface="zwlr_layer_surface_v1"/> | |||
| 64 | + | <arg name="surface" type="object" interface="wl_surface"/> | |||
| 65 | + | <arg name="output" type="object" interface="wl_output" allow-null="true"/> | |||
| 66 | + | <arg name="layer" type="uint" enum="layer" summary="layer to add this surface to"/> | |||
| 67 | + | <arg name="namespace" type="string" summary="namespace for the layer surface"/> | |||
| 68 | + | </request> | |||
| 69 | + | ||||
| 70 | + | <enum name="error"> | |||
| 71 | + | <entry name="role" value="0" summary="wl_surface has another role"/> | |||
| 72 | + | <entry name="invalid_layer" value="1" summary="layer value is invalid"/> | |||
| 73 | + | <entry name="already_constructed" value="2" summary="wl_surface has a buffer attached or committed"/> | |||
| 74 | + | </enum> | |||
| 75 | + | ||||
| 76 | + | <enum name="layer"> | |||
| 77 | + | <description summary="available layers for surfaces"> | |||
| 78 | + | These values indicate which layers a surface can be rendered in. They | |||
| 79 | + | are ordered by z depth, bottom-most first. Traditional shell surfaces | |||
| 80 | + | will typically be rendered between the bottom and top layers. | |||
| 81 | + | Fullscreen shell surfaces are typically rendered at the top layer. | |||
| 82 | + | Multiple surfaces can share a single layer, and ordering within a | |||
| 83 | + | single layer is undefined. | |||
| 84 | + | </description> | |||
| 85 | + | ||||
| 86 | + | <entry name="background" value="0"/> | |||
| 87 | + | <entry name="bottom" value="1"/> | |||
| 88 | + | <entry name="top" value="2"/> | |||
| 89 | + | <entry name="overlay" value="3"/> | |||
| 90 | + | </enum> | |||
| 91 | + | ||||
| 92 | + | <!-- Version 3 additions --> | |||
| 93 | + | ||||
| 94 | + | <request name="destroy" type="destructor" since="3"> | |||
| 95 | + | <description summary="destroy the layer_shell object"> | |||
| 96 | + | This request indicates that the client will not use the layer_shell | |||
| 97 | + | object any more. Objects that have been created through this instance | |||
| 98 | + | are not affected. | |||
| 99 | + | </description> | |||
| 100 | + | </request> | |||
| 101 | + | </interface> | |||
| 102 | + | ||||
| 103 | + | <interface name="zwlr_layer_surface_v1" version="5"> | |||
| 104 | + | <description summary="layer metadata interface"> | |||
| 105 | + | An interface that may be implemented by a wl_surface, for surfaces that | |||
| 106 | + | are designed to be rendered as a layer of a stacked desktop-like | |||
| 107 | + | environment. | |||
| 108 | + | ||||
| 109 | + | Layer surface state (layer, size, anchor, exclusive zone, | |||
| 110 | + | margin, interactivity) is double-buffered, and will be applied at the | |||
| 111 | + | time wl_surface.commit of the corresponding wl_surface is called. | |||
| 112 | + | ||||
| 113 | + | Attaching a null buffer to a layer surface unmaps it. | |||
| 114 | + | ||||
| 115 | + | Unmapping a layer_surface means that the surface cannot be shown by the | |||
| 116 | + | compositor until it is explicitly mapped again. The layer_surface | |||
| 117 | + | returns to the state it had right after layer_shell.get_layer_surface. | |||
| 118 | + | The client can re-map the surface by performing a commit without any | |||
| 119 | + | buffer attached, waiting for a configure event and handling it as usual. | |||
| 120 | + | </description> | |||
| 121 | + | ||||
| 122 | + | <request name="set_size"> | |||
| 123 | + | <description summary="sets the size of the surface"> | |||
| 124 | + | Sets the size of the surface in surface-local coordinates. The | |||
| 125 | + | compositor will display the surface centered with respect to its | |||
| 126 | + | anchors. | |||
| 127 | + | ||||
| 128 | + | If you pass 0 for either value, the compositor will assign it and | |||
| 129 | + | inform you of the assignment in the configure event. You must set your | |||
| 130 | + | anchor to opposite edges in the dimensions you omit; not doing so is a | |||
| 131 | + | protocol error. Both values are 0 by default. | |||
| 132 | + | ||||
| 133 | + | Size is double-buffered, see wl_surface.commit. | |||
| 134 | + | </description> | |||
| 135 | + | <arg name="width" type="uint"/> | |||
| 136 | + | <arg name="height" type="uint"/> | |||
| 137 | + | </request> | |||
| 138 | + | ||||
| 139 | + | <request name="set_anchor"> | |||
| 140 | + | <description summary="configures the anchor point of the surface"> | |||
| 141 | + | Requests that the compositor anchor the surface to the specified edges | |||
| 142 | + | and corners. If two orthogonal edges are specified (e.g. 'top' and | |||
| 143 | + | 'left'), then the anchor point will be the intersection of the edges | |||
| 144 | + | (e.g. the top left corner of the output); otherwise the anchor point | |||
| 145 | + | will be centered on that edge, or in the center if none is specified. | |||
| 146 | + | ||||
| 147 | + | Anchor is double-buffered, see wl_surface.commit. | |||
| 148 | + | </description> | |||
| 149 | + | <arg name="anchor" type="uint" enum="anchor"/> | |||
| 150 | + | </request> | |||
| 151 | + | ||||
| 152 | + | <request name="set_exclusive_zone"> | |||
| 153 | + | <description summary="configures the exclusive geometry of this surface"> | |||
| 154 | + | Requests that the compositor avoids occluding an area with other | |||
| 155 | + | surfaces. The compositor's use of this information is | |||
| 156 | + | implementation-dependent - do not assume that this region will not | |||
| 157 | + | actually be occluded. | |||
| 158 | + | ||||
| 159 | + | A positive value is only meaningful if the surface is anchored to one | |||
| 160 | + | edge or an edge and both perpendicular edges. If the surface is not | |||
| 161 | + | anchored, anchored to only two perpendicular edges (a corner), anchored | |||
| 162 | + | to only two parallel edges or anchored to all edges, a positive value | |||
| 163 | + | will be treated the same as zero. | |||
| 164 | + | ||||
| 165 | + | A positive zone is the distance from the edge in surface-local | |||
| 166 | + | coordinates to consider exclusive. | |||
| 167 | + | ||||
| 168 | + | Surfaces that do not wish to have an exclusive zone may instead specify | |||
| 169 | + | how they should interact with surfaces that do. If set to zero, the | |||
| 170 | + | surface indicates that it would like to be moved to avoid occluding | |||
| 171 | + | surfaces with a positive exclusive zone. If set to -1, the surface | |||
| 172 | + | indicates that it would not like to be moved to accommodate for other | |||
| 173 | + | surfaces, and the compositor should extend it all the way to the edges | |||
| 174 | + | it is anchored to. | |||
| 175 | + | ||||
| 176 | + | For example, a panel might set its exclusive zone to 10, so that | |||
| 177 | + | maximized shell surfaces are not shown on top of it. A notification | |||
| 178 | + | might set its exclusive zone to 0, so that it is moved to avoid | |||
| 179 | + | occluding the panel, but shell surfaces are shown underneath it. A | |||
| 180 | + | wallpaper or lock screen might set their exclusive zone to -1, so that | |||
| 181 | + | they stretch below or over the panel. | |||
| 182 | + | ||||
| 183 | + | The default value is 0. | |||
| 184 | + | ||||
| 185 | + | Exclusive zone is double-buffered, see wl_surface.commit. | |||
| 186 | + | </description> | |||
| 187 | + | <arg name="zone" type="int"/> | |||
| 188 | + | </request> | |||
| 189 | + | ||||
| 190 | + | <request name="set_margin"> | |||
| 191 | + | <description summary="sets a margin from the anchor point"> | |||
| 192 | + | Requests that the surface be placed some distance away from the anchor | |||
| 193 | + | point on the output, in surface-local coordinates. Setting this value | |||
| 194 | + | for edges you are not anchored to has no effect. | |||
| 195 | + | ||||
| 196 | + | The exclusive zone includes the margin. | |||
| 197 | + | ||||
| 198 | + | Margin is double-buffered, see wl_surface.commit. | |||
| 199 | + | </description> | |||
| 200 | + | <arg name="top" type="int"/> | |||
| 201 | + | <arg name="right" type="int"/> | |||
| 202 | + | <arg name="bottom" type="int"/> | |||
| 203 | + | <arg name="left" type="int"/> | |||
| 204 | + | </request> | |||
| 205 | + | ||||
| 206 | + | <enum name="keyboard_interactivity"> | |||
| 207 | + | <description summary="types of keyboard interaction possible for a layer shell surface"> | |||
| 208 | + | Types of keyboard interaction possible for layer shell surfaces. The | |||
| 209 | + | rationale for this is twofold: (1) some applications are not interested | |||
| 210 | + | in keyboard events and not allowing them to be focused can improve the | |||
| 211 | + | desktop experience; (2) some applications will want to take exclusive | |||
| 212 | + | keyboard focus. | |||
| 213 | + | </description> | |||
| 214 | + | ||||
| 215 | + | <entry name="none" value="0"> | |||
| 216 | + | <description summary="no keyboard focus is possible"> | |||
| 217 | + | This value indicates that this surface is not interested in keyboard | |||
| 218 | + | events and the compositor should never assign it the keyboard focus. | |||
| 219 | + | ||||
| 220 | + | This is the default value, set for newly created layer shell surfaces. | |||
| 221 | + | ||||
| 222 | + | This is useful for e.g. desktop widgets that display information or | |||
| 223 | + | only have interaction with non-keyboard input devices. | |||
| 224 | + | </description> | |||
| 225 | + | </entry> | |||
| 226 | + | <entry name="exclusive" value="1"> | |||
| 227 | + | <description summary="request exclusive keyboard focus"> | |||
| 228 | + | Request exclusive keyboard focus if this surface is above the shell surface layer. | |||
| 229 | + | ||||
| 230 | + | For the top and overlay layers, the seat will always give | |||
| 231 | + | exclusive keyboard focus to the top-most layer which has keyboard | |||
| 232 | + | interactivity set to exclusive. If this layer contains multiple | |||
| 233 | + | surfaces with keyboard interactivity set to exclusive, the compositor | |||
| 234 | + | determines the one receiving keyboard events in an implementation- | |||
| 235 | + | defined manner. In this case, no guarantee is made when this surface | |||
| 236 | + | will receive keyboard focus (if ever). | |||
| 237 | + | ||||
| 238 | + | For the bottom and background layers, the compositor is allowed to use | |||
| 239 | + | normal focus semantics. | |||
| 240 | + | ||||
| 241 | + | This setting is mainly intended for applications that need to ensure | |||
| 242 | + | they receive all keyboard events, such as a lock screen or a password | |||
| 243 | + | prompt. | |||
| 244 | + | </description> | |||
| 245 | + | </entry> | |||
| 246 | + | <entry name="on_demand" value="2" since="4"> | |||
| 247 | + | <description summary="request regular keyboard focus semantics"> | |||
| 248 | + | This requests the compositor to allow this surface to be focused and | |||
| 249 | + | unfocused by the user in an implementation-defined manner. The user | |||
| 250 | + | should be able to unfocus this surface even regardless of the layer | |||
| 251 | + | it is on. | |||
| 252 | + | ||||
| 253 | + | Typically, the compositor will want to use its normal mechanism to | |||
| 254 | + | manage keyboard focus between layer shell surfaces with this setting | |||
| 255 | + | and regular toplevels on the desktop layer (e.g. click to focus). | |||
| 256 | + | Nevertheless, it is possible for a compositor to require a special | |||
| 257 | + | interaction to focus or unfocus layer shell surfaces (e.g. requiring | |||
| 258 | + | a click even if focus follows the mouse normally, or providing a | |||
| 259 | + | keybinding to switch focus between layers). | |||
| 260 | + | ||||
| 261 | + | This setting is mainly intended for desktop shell components (e.g. | |||
| 262 | + | panels) that allow keyboard interaction. Using this option can allow | |||
| 263 | + | implementing a desktop shell that can be fully usable without the | |||
| 264 | + | mouse. | |||
| 265 | + | </description> | |||
| 266 | + | </entry> | |||
| 267 | + | </enum> | |||
| 268 | + | ||||
| 269 | + | <request name="set_keyboard_interactivity"> | |||
| 270 | + | <description summary="requests keyboard events"> | |||
| 271 | + | Set how keyboard events are delivered to this surface. By default, | |||
| 272 | + | layer shell surfaces do not receive keyboard events; this request can | |||
| 273 | + | be used to change this. | |||
| 274 | + | ||||
| 275 | + | This setting is inherited by child surfaces set by the get_popup | |||
| 276 | + | request. | |||
| 277 | + | ||||
| 278 | + | Layer surfaces receive pointer, touch, and tablet events normally. If | |||
| 279 | + | you do not want to receive them, set the input region on your surface | |||
| 280 | + | to an empty region. | |||
| 281 | + | ||||
| 282 | + | Keyboard interactivity is double-buffered, see wl_surface.commit. | |||
| 283 | + | </description> | |||
| 284 | + | <arg name="keyboard_interactivity" type="uint" enum="keyboard_interactivity"/> | |||
| 285 | + | </request> | |||
| 286 | + | ||||
| 287 | + | <request name="get_popup"> | |||
| 288 | + | <description summary="assign this layer_surface as an xdg_popup parent"> | |||
| 289 | + | This assigns an xdg_popup's parent to this layer_surface. This popup | |||
| 290 | + | should have been created via xdg_surface::get_popup with the parent set | |||
| 291 | + | to NULL, and this request must be invoked before committing the popup's | |||
| 292 | + | initial state. | |||
| 293 | + | ||||
| 294 | + | See the documentation of xdg_popup for more details about what an | |||
| 295 | + | xdg_popup is and how it is used. | |||
| 296 | + | </description> | |||
| 297 | + | <arg name="popup" type="object" interface="xdg_popup"/> | |||
| 298 | + | </request> | |||
| 299 | + | ||||
| 300 | + | <request name="ack_configure"> | |||
| 301 | + | <description summary="ack a configure event"> | |||
| 302 | + | When a configure event is received, if a client commits the | |||
| 303 | + | surface in response to the configure event, then the client | |||
| 304 | + | must make an ack_configure request sometime before the commit | |||
| 305 | + | request, passing along the serial of the configure event. | |||
| 306 | + | ||||
| 307 | + | If the client receives multiple configure events before it | |||
| 308 | + | can respond to one, it only has to ack the last configure event. | |||
| 309 | + | ||||
| 310 | + | A client is not required to commit immediately after sending | |||
| 311 | + | an ack_configure request - it may even ack_configure several times | |||
| 312 | + | before its next surface commit. | |||
| 313 | + | ||||
| 314 | + | A client may send multiple ack_configure requests before committing, but | |||
| 315 | + | only the last request sent before a commit indicates which configure | |||
| 316 | + | event the client really is responding to. | |||
| 317 | + | </description> | |||
| 318 | + | <arg name="serial" type="uint" summary="the serial from the configure event"/> | |||
| 319 | + | </request> | |||
| 320 | + | ||||
| 321 | + | <request name="destroy" type="destructor"> | |||
| 322 | + | <description summary="destroy the layer_surface"> | |||
| 323 | + | This request destroys the layer surface. | |||
| 324 | + | </description> | |||
| 325 | + | </request> | |||
| 326 | + | ||||
| 327 | + | <event name="configure"> | |||
| 328 | + | <description summary="suggest a surface change"> | |||
| 329 | + | The configure event asks the client to resize its surface. | |||
| 330 | + | ||||
| 331 | + | Clients should arrange their surface for the new states, and then send | |||
| 332 | + | an ack_configure request with the serial sent in this configure event at | |||
| 333 | + | some point before committing the new surface. | |||
| 334 | + | ||||
| 335 | + | The client is free to dismiss all but the last configure event it | |||
| 336 | + | received. | |||
| 337 | + | ||||
| 338 | + | The width and height arguments specify the size of the window in | |||
| 339 | + | surface-local coordinates. | |||
| 340 | + | ||||
| 341 | + | The size is a hint, in the sense that the client is free to ignore it if | |||
| 342 | + | it doesn't resize, pick a smaller size (to satisfy aspect ratio or | |||
| 343 | + | resize in steps of NxM pixels). If the client picks a smaller size and | |||
| 344 | + | is anchored to two opposite anchors (e.g. 'top' and 'bottom'), the | |||
| 345 | + | surface will be centered on this axis. | |||
| 346 | + | ||||
| 347 | + | If the width or height arguments are zero, it means the client should | |||
| 348 | + | decide its own window dimension. | |||
| 349 | + | </description> | |||
| 350 | + | <arg name="serial" type="uint"/> | |||
| 351 | + | <arg name="width" type="uint"/> | |||
| 352 | + | <arg name="height" type="uint"/> | |||
| 353 | + | </event> | |||
| 354 | + | ||||
| 355 | + | <event name="closed"> | |||
| 356 | + | <description summary="surface should be closed"> | |||
| 357 | + | The closed event is sent by the compositor when the surface will no | |||
| 358 | + | longer be shown. The output may have been destroyed or the user may | |||
| 359 | + | have asked for it to be removed. Further changes to the surface will be | |||
| 360 | + | ignored. The client should destroy the resource after receiving this | |||
| 361 | + | event, and create a new surface if they so choose. | |||
| 362 | + | </description> | |||
| 363 | + | </event> | |||
| 364 | + | ||||
| 365 | + | <enum name="error"> | |||
| 366 | + | <entry name="invalid_surface_state" value="0" summary="provided surface state is invalid"/> | |||
| 367 | + | <entry name="invalid_size" value="1" summary="size is invalid"/> | |||
| 368 | + | <entry name="invalid_anchor" value="2" summary="anchor bitfield is invalid"/> | |||
| 369 | + | <entry name="invalid_keyboard_interactivity" value="3" summary="keyboard interactivity is invalid"/> | |||
| 370 | + | <entry name="invalid_exclusive_edge" value="4" summary="exclusive edge is invalid given the surface anchors"/> | |||
| 371 | + | </enum> | |||
| 372 | + | ||||
| 373 | + | <enum name="anchor" bitfield="true"> | |||
| 374 | + | <entry name="top" value="1" summary="the top edge of the anchor rectangle"/> | |||
| 375 | + | <entry name="bottom" value="2" summary="the bottom edge of the anchor rectangle"/> | |||
| 376 | + | <entry name="left" value="4" summary="the left edge of the anchor rectangle"/> | |||
| 377 | + | <entry name="right" value="8" summary="the right edge of the anchor rectangle"/> | |||
| 378 | + | </enum> | |||
| 379 | + | ||||
| 380 | + | <!-- Version 2 additions --> | |||
| 381 | + | ||||
| 382 | + | <request name="set_layer" since="2"> | |||
| 383 | + | <description summary="change the layer of the surface"> | |||
| 384 | + | Change the layer that the surface is rendered on. | |||
| 385 | + | ||||
| 386 | + | Layer is double-buffered, see wl_surface.commit. | |||
| 387 | + | </description> | |||
| 388 | + | <arg name="layer" type="uint" enum="zwlr_layer_shell_v1.layer" summary="layer to move this surface to"/> | |||
| 389 | + | </request> | |||
| 390 | + | ||||
| 391 | + | <!-- Version 5 additions --> | |||
| 392 | + | ||||
| 393 | + | <request name="set_exclusive_edge" since="5"> | |||
| 394 | + | <description summary="set the edge the exclusive zone will be applied to"> | |||
| 395 | + | Requests an edge for the exclusive zone to apply. The exclusive | |||
| 396 | + | edge will be automatically deduced from anchor points when possible, | |||
| 397 | + | but when the surface is anchored to a corner, it will be necessary | |||
| 398 | + | to set it explicitly to disambiguate, as it is not possible to deduce | |||
| 399 | + | which one of the two corner edges should be used. | |||
| 400 | + | ||||
| 401 | + | The edge must be one the surface is anchored to, otherwise the | |||
| 402 | + | invalid_exclusive_edge protocol error will be raised. | |||
| 403 | + | </description> | |||
| 404 | + | <arg name="edge" type="uint" enum="anchor"/> | |||
| 405 | + | </request> | |||
| 406 | + | </interface> | |||
| 407 | + | </protocol> | |||
A spec/xml/wlroutputmanagement.xml +611 -0
| @@ -0,0 +1,611 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="wlr_output_management_unstable_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2019 Purism SPC | |||
| 5 | + | ||||
| 6 | + | Permission to use, copy, modify, distribute, and sell this | |||
| 7 | + | software and its documentation for any purpose is hereby granted | |||
| 8 | + | without fee, provided that the above copyright notice appear in | |||
| 9 | + | all copies and that both that copyright notice and this permission | |||
| 10 | + | notice appear in supporting documentation, and that the name of | |||
| 11 | + | the copyright holders not be used in advertising or publicity | |||
| 12 | + | pertaining to distribution of the software without specific, | |||
| 13 | + | written prior permission. The copyright holders make no | |||
| 14 | + | representations about the suitability of this software for any | |||
| 15 | + | purpose. It is provided "as is" without express or implied | |||
| 16 | + | warranty. | |||
| 17 | + | ||||
| 18 | + | THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | |||
| 19 | + | SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||
| 20 | + | FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | |||
| 21 | + | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||
| 22 | + | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | |||
| 23 | + | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |||
| 24 | + | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |||
| 25 | + | THIS SOFTWARE. | |||
| 26 | + | </copyright> | |||
| 27 | + | ||||
| 28 | + | <description summary="protocol to configure output devices"> | |||
| 29 | + | This protocol exposes interfaces to obtain and modify output device | |||
| 30 | + | configuration. | |||
| 31 | + | ||||
| 32 | + | Warning! The protocol described in this file is experimental and | |||
| 33 | + | backward incompatible changes may be made. Backward compatible changes | |||
| 34 | + | may be added together with the corresponding interface version bump. | |||
| 35 | + | Backward incompatible changes are done by bumping the version number in | |||
| 36 | + | the protocol and interface names and resetting the interface version. | |||
| 37 | + | Once the protocol is to be declared stable, the 'z' prefix and the | |||
| 38 | + | version number in the protocol and interface names are removed and the | |||
| 39 | + | interface version number is reset. | |||
| 40 | + | </description> | |||
| 41 | + | ||||
| 42 | + | <interface name="zwlr_output_manager_v1" version="4"> | |||
| 43 | + | <description summary="output device configuration manager"> | |||
| 44 | + | This interface is a manager that allows reading and writing the current | |||
| 45 | + | output device configuration. | |||
| 46 | + | ||||
| 47 | + | Output devices that display pixels (e.g. a physical monitor or a virtual | |||
| 48 | + | output in a window) are represented as heads. Heads cannot be created nor | |||
| 49 | + | destroyed by the client, but they can be enabled or disabled and their | |||
| 50 | + | properties can be changed. Each head may have one or more available modes. | |||
| 51 | + | ||||
| 52 | + | Whenever a head appears (e.g. a monitor is plugged in), it will be | |||
| 53 | + | advertised via the head event. Immediately after the output manager is | |||
| 54 | + | bound, all current heads are advertised. | |||
| 55 | + | ||||
| 56 | + | Whenever a head's properties change, the relevant wlr_output_head events | |||
| 57 | + | will be sent. Not all head properties will be sent: only properties that | |||
| 58 | + | have changed need to. | |||
| 59 | + | ||||
| 60 | + | Whenever a head disappears (e.g. a monitor is unplugged), a | |||
| 61 | + | wlr_output_head.finished event will be sent. | |||
| 62 | + | ||||
| 63 | + | After one or more heads appear, change or disappear, the done event will | |||
| 64 | + | be sent. It carries a serial which can be used in a create_configuration | |||
| 65 | + | request to update heads properties. | |||
| 66 | + | ||||
| 67 | + | The information obtained from this protocol should only be used for output | |||
| 68 | + | configuration purposes. This protocol is not designed to be a generic | |||
| 69 | + | output property advertisement protocol for regular clients. Instead, | |||
| 70 | + | protocols such as xdg-output should be used. | |||
| 71 | + | </description> | |||
| 72 | + | ||||
| 73 | + | <event name="head"> | |||
| 74 | + | <description summary="introduce a new head"> | |||
| 75 | + | This event introduces a new head. This happens whenever a new head | |||
| 76 | + | appears (e.g. a monitor is plugged in) or after the output manager is | |||
| 77 | + | bound. | |||
| 78 | + | </description> | |||
| 79 | + | <arg name="head" type="new_id" interface="zwlr_output_head_v1"/> | |||
| 80 | + | </event> | |||
| 81 | + | ||||
| 82 | + | <event name="done"> | |||
| 83 | + | <description summary="sent all information about current configuration"> | |||
| 84 | + | This event is sent after all information has been sent after binding to | |||
| 85 | + | the output manager object and after any subsequent changes. This applies | |||
| 86 | + | to child head and mode objects as well. In other words, this event is | |||
| 87 | + | sent whenever a head or mode is created or destroyed and whenever one of | |||
| 88 | + | their properties has been changed. Not all state is re-sent each time | |||
| 89 | + | the current configuration changes: only the actual changes are sent. | |||
| 90 | + | ||||
| 91 | + | This allows changes to the output configuration to be seen as atomic, | |||
| 92 | + | even if they happen via multiple events. | |||
| 93 | + | ||||
| 94 | + | A serial is sent to be used in a future create_configuration request. | |||
| 95 | + | </description> | |||
| 96 | + | <arg name="serial" type="uint" summary="current configuration serial"/> | |||
| 97 | + | </event> | |||
| 98 | + | ||||
| 99 | + | <request name="create_configuration"> | |||
| 100 | + | <description summary="create a new output configuration object"> | |||
| 101 | + | Create a new output configuration object. This allows to update head | |||
| 102 | + | properties. | |||
| 103 | + | </description> | |||
| 104 | + | <arg name="id" type="new_id" interface="zwlr_output_configuration_v1"/> | |||
| 105 | + | <arg name="serial" type="uint"/> | |||
| 106 | + | </request> | |||
| 107 | + | ||||
| 108 | + | <request name="stop"> | |||
| 109 | + | <description summary="stop sending events"> | |||
| 110 | + | Indicates the client no longer wishes to receive events for output | |||
| 111 | + | configuration changes. However the compositor may emit further events, | |||
| 112 | + | until the finished event is emitted. | |||
| 113 | + | ||||
| 114 | + | The client must not send any more requests after this one. | |||
| 115 | + | </description> | |||
| 116 | + | </request> | |||
| 117 | + | ||||
| 118 | + | <event name="finished" type="destructor"> | |||
| 119 | + | <description summary="the compositor has finished with the manager"> | |||
| 120 | + | This event indicates that the compositor is done sending manager events. | |||
| 121 | + | The compositor will destroy the object immediately after sending this | |||
| 122 | + | event, so it will become invalid and the client should release any | |||
| 123 | + | resources associated with it. | |||
| 124 | + | </description> | |||
| 125 | + | </event> | |||
| 126 | + | </interface> | |||
| 127 | + | ||||
| 128 | + | <interface name="zwlr_output_head_v1" version="4"> | |||
| 129 | + | <description summary="output device"> | |||
| 130 | + | A head is an output device. The difference between a wl_output object and | |||
| 131 | + | a head is that heads are advertised even if they are turned off. A head | |||
| 132 | + | object only advertises properties and cannot be used directly to change | |||
| 133 | + | them. | |||
| 134 | + | ||||
| 135 | + | A head has some read-only properties: modes, name, description and | |||
| 136 | + | physical_size. These cannot be changed by clients. | |||
| 137 | + | ||||
| 138 | + | Other properties can be updated via a wlr_output_configuration object. | |||
| 139 | + | ||||
| 140 | + | Properties sent via this interface are applied atomically via the | |||
| 141 | + | wlr_output_manager.done event. No guarantees are made regarding the order | |||
| 142 | + | in which properties are sent. | |||
| 143 | + | </description> | |||
| 144 | + | ||||
| 145 | + | <event name="name"> | |||
| 146 | + | <description summary="head name"> | |||
| 147 | + | This event describes the head name. | |||
| 148 | + | ||||
| 149 | + | The naming convention is compositor defined, but limited to alphanumeric | |||
| 150 | + | characters and dashes (-). Each name is unique among all wlr_output_head | |||
| 151 | + | objects, but if a wlr_output_head object is destroyed the same name may | |||
| 152 | + | be reused later. The names will also remain consistent across sessions | |||
| 153 | + | with the same hardware and software configuration. | |||
| 154 | + | ||||
| 155 | + | Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc. However, do | |||
| 156 | + | not assume that the name is a reflection of an underlying DRM | |||
| 157 | + | connector, X11 connection, etc. | |||
| 158 | + | ||||
| 159 | + | If this head matches a wl_output, the wl_output.name event must report | |||
| 160 | + | the same name. | |||
| 161 | + | ||||
| 162 | + | The name event is sent after a wlr_output_head object is created. This | |||
| 163 | + | event is only sent once per object, and the name does not change over | |||
| 164 | + | the lifetime of the wlr_output_head object. | |||
| 165 | + | </description> | |||
| 166 | + | <arg name="name" type="string"/> | |||
| 167 | + | </event> | |||
| 168 | + | ||||
| 169 | + | <event name="description"> | |||
| 170 | + | <description summary="head description"> | |||
| 171 | + | This event describes a human-readable description of the head. | |||
| 172 | + | ||||
| 173 | + | The description is a UTF-8 string with no convention defined for its | |||
| 174 | + | contents. Examples might include 'Foocorp 11" Display' or 'Virtual X11 | |||
| 175 | + | output via :1'. However, do not assume that the name is a reflection of | |||
| 176 | + | the make, model, serial of the underlying DRM connector or the display | |||
| 177 | + | name of the underlying X11 connection, etc. | |||
| 178 | + | ||||
| 179 | + | If this head matches a wl_output, the wl_output.description event must | |||
| 180 | + | report the same name. | |||
| 181 | + | ||||
| 182 | + | The description event is sent after a wlr_output_head object is created. | |||
| 183 | + | This event is only sent once per object, and the description does not | |||
| 184 | + | change over the lifetime of the wlr_output_head object. | |||
| 185 | + | </description> | |||
| 186 | + | <arg name="description" type="string"/> | |||
| 187 | + | </event> | |||
| 188 | + | ||||
| 189 | + | <event name="physical_size"> | |||
| 190 | + | <description summary="head physical size"> | |||
| 191 | + | This event describes the physical size of the head. This event is only | |||
| 192 | + | sent if the head has a physical size (e.g. is not a projector or a | |||
| 193 | + | virtual device). | |||
| 194 | + | ||||
| 195 | + | The physical size event is sent after a wlr_output_head object is created. This | |||
| 196 | + | event is only sent once per object, and the physical size does not change over | |||
| 197 | + | the lifetime of the wlr_output_head object. | |||
| 198 | + | </description> | |||
| 199 | + | <arg name="width" type="int" summary="width in millimeters of the output"/> | |||
| 200 | + | <arg name="height" type="int" summary="height in millimeters of the output"/> | |||
| 201 | + | </event> | |||
| 202 | + | ||||
| 203 | + | <event name="mode"> | |||
| 204 | + | <description summary="introduce a mode"> | |||
| 205 | + | This event introduces a mode for this head. It is sent once per | |||
| 206 | + | supported mode. | |||
| 207 | + | </description> | |||
| 208 | + | <arg name="mode" type="new_id" interface="zwlr_output_mode_v1"/> | |||
| 209 | + | </event> | |||
| 210 | + | ||||
| 211 | + | <event name="enabled"> | |||
| 212 | + | <description summary="head is enabled or disabled"> | |||
| 213 | + | This event describes whether the head is enabled. A disabled head is not | |||
| 214 | + | mapped to a region of the global compositor space. | |||
| 215 | + | ||||
| 216 | + | When a head is disabled, some properties (current_mode, position, | |||
| 217 | + | transform and scale) are irrelevant. | |||
| 218 | + | </description> | |||
| 219 | + | <arg name="enabled" type="int" summary="zero if disabled, non-zero if enabled"/> | |||
| 220 | + | </event> | |||
| 221 | + | ||||
| 222 | + | <event name="current_mode"> | |||
| 223 | + | <description summary="current mode"> | |||
| 224 | + | This event describes the mode currently in use for this head. It is only | |||
| 225 | + | sent if the output is enabled. | |||
| 226 | + | </description> | |||
| 227 | + | <arg name="mode" type="object" interface="zwlr_output_mode_v1"/> | |||
| 228 | + | </event> | |||
| 229 | + | ||||
| 230 | + | <event name="position"> | |||
| 231 | + | <description summary="current position"> | |||
| 232 | + | This events describes the position of the head in the global compositor | |||
| 233 | + | space. It is only sent if the output is enabled. | |||
| 234 | + | </description> | |||
| 235 | + | <arg name="x" type="int" | |||
| 236 | + | summary="x position within the global compositor space"/> | |||
| 237 | + | <arg name="y" type="int" | |||
| 238 | + | summary="y position within the global compositor space"/> | |||
| 239 | + | </event> | |||
| 240 | + | ||||
| 241 | + | <event name="transform"> | |||
| 242 | + | <description summary="current transformation"> | |||
| 243 | + | This event describes the transformation currently applied to the head. | |||
| 244 | + | It is only sent if the output is enabled. | |||
| 245 | + | </description> | |||
| 246 | + | <arg name="transform" type="int" enum="wl_output.transform"/> | |||
| 247 | + | </event> | |||
| 248 | + | ||||
| 249 | + | <event name="scale"> | |||
| 250 | + | <description summary="current scale"> | |||
| 251 | + | This events describes the scale of the head in the global compositor | |||
| 252 | + | space. It is only sent if the output is enabled. | |||
| 253 | + | </description> | |||
| 254 | + | <arg name="scale" type="fixed"/> | |||
| 255 | + | </event> | |||
| 256 | + | ||||
| 257 | + | <event name="finished"> | |||
| 258 | + | <description summary="the head has disappeared"> | |||
| 259 | + | This event indicates that the head is no longer available. The head | |||
| 260 | + | object becomes inert. Clients should send a destroy request and release | |||
| 261 | + | any resources associated with it. | |||
| 262 | + | </description> | |||
| 263 | + | </event> | |||
| 264 | + | ||||
| 265 | + | <!-- Version 2 additions --> | |||
| 266 | + | ||||
| 267 | + | <event name="make" since="2"> | |||
| 268 | + | <description summary="head manufacturer"> | |||
| 269 | + | This event describes the manufacturer of the head. | |||
| 270 | + | ||||
| 271 | + | Together with the model and serial_number events the purpose is to | |||
| 272 | + | allow clients to recognize heads from previous sessions and for example | |||
| 273 | + | load head-specific configurations back. | |||
| 274 | + | ||||
| 275 | + | It is not guaranteed this event will be ever sent. A reason for that | |||
| 276 | + | can be that the compositor does not have information about the make of | |||
| 277 | + | the head or the definition of a make is not sensible in the current | |||
| 278 | + | setup, for example in a virtual session. Clients can still try to | |||
| 279 | + | identify the head by available information from other events but should | |||
| 280 | + | be aware that there is an increased risk of false positives. | |||
| 281 | + | ||||
| 282 | + | If sent, the make event is sent after a wlr_output_head object is | |||
| 283 | + | created and only sent once per object. The make does not change over | |||
| 284 | + | the lifetime of the wlr_output_head object. | |||
| 285 | + | ||||
| 286 | + | It is not recommended to display the make string in UI to users. For | |||
| 287 | + | that the string provided by the description event should be preferred. | |||
| 288 | + | </description> | |||
| 289 | + | <arg name="make" type="string"/> | |||
| 290 | + | </event> | |||
| 291 | + | ||||
| 292 | + | <event name="model" since="2"> | |||
| 293 | + | <description summary="head model"> | |||
| 294 | + | This event describes the model of the head. | |||
| 295 | + | ||||
| 296 | + | Together with the make and serial_number events the purpose is to | |||
| 297 | + | allow clients to recognize heads from previous sessions and for example | |||
| 298 | + | load head-specific configurations back. | |||
| 299 | + | ||||
| 300 | + | It is not guaranteed this event will be ever sent. A reason for that | |||
| 301 | + | can be that the compositor does not have information about the model of | |||
| 302 | + | the head or the definition of a model is not sensible in the current | |||
| 303 | + | setup, for example in a virtual session. Clients can still try to | |||
| 304 | + | identify the head by available information from other events but should | |||
| 305 | + | be aware that there is an increased risk of false positives. | |||
| 306 | + | ||||
| 307 | + | If sent, the model event is sent after a wlr_output_head object is | |||
| 308 | + | created and only sent once per object. The model does not change over | |||
| 309 | + | the lifetime of the wlr_output_head object. | |||
| 310 | + | ||||
| 311 | + | It is not recommended to display the model string in UI to users. For | |||
| 312 | + | that the string provided by the description event should be preferred. | |||
| 313 | + | </description> | |||
| 314 | + | <arg name="model" type="string"/> | |||
| 315 | + | </event> | |||
| 316 | + | ||||
| 317 | + | <event name="serial_number" since="2"> | |||
| 318 | + | <description summary="head serial number"> | |||
| 319 | + | This event describes the serial number of the head. | |||
| 320 | + | ||||
| 321 | + | Together with the make and model events the purpose is to allow clients | |||
| 322 | + | to recognize heads from previous sessions and for example load head- | |||
| 323 | + | specific configurations back. | |||
| 324 | + | ||||
| 325 | + | It is not guaranteed this event will be ever sent. A reason for that | |||
| 326 | + | can be that the compositor does not have information about the serial | |||
| 327 | + | number of the head or the definition of a serial number is not sensible | |||
| 328 | + | in the current setup. Clients can still try to identify the head by | |||
| 329 | + | available information from other events but should be aware that there | |||
| 330 | + | is an increased risk of false positives. | |||
| 331 | + | ||||
| 332 | + | If sent, the serial number event is sent after a wlr_output_head object | |||
| 333 | + | is created and only sent once per object. The serial number does not | |||
| 334 | + | change over the lifetime of the wlr_output_head object. | |||
| 335 | + | ||||
| 336 | + | It is not recommended to display the serial_number string in UI to | |||
| 337 | + | users. For that the string provided by the description event should be | |||
| 338 | + | preferred. | |||
| 339 | + | </description> | |||
| 340 | + | <arg name="serial_number" type="string"/> | |||
| 341 | + | </event> | |||
| 342 | + | ||||
| 343 | + | <!-- Version 3 additions --> | |||
| 344 | + | ||||
| 345 | + | <request name="release" type="destructor" since="3"> | |||
| 346 | + | <description summary="destroy the head object"> | |||
| 347 | + | This request indicates that the client will no longer use this head | |||
| 348 | + | object. | |||
| 349 | + | </description> | |||
| 350 | + | </request> | |||
| 351 | + | ||||
| 352 | + | <!-- Version 4 additions --> | |||
| 353 | + | ||||
| 354 | + | <enum name="adaptive_sync_state" since="4"> | |||
| 355 | + | <entry name="disabled" value="0" summary="adaptive sync is disabled"/> | |||
| 356 | + | <entry name="enabled" value="1" summary="adaptive sync is enabled"/> | |||
| 357 | + | </enum> | |||
| 358 | + | ||||
| 359 | + | <event name="adaptive_sync" since="4"> | |||
| 360 | + | <description summary="current adaptive sync state"> | |||
| 361 | + | This event describes whether adaptive sync is currently enabled for | |||
| 362 | + | the head or not. Adaptive sync is also known as Variable Refresh | |||
| 363 | + | Rate or VRR. | |||
| 364 | + | </description> | |||
| 365 | + | <arg name="state" type="uint" enum="adaptive_sync_state"/> | |||
| 366 | + | </event> | |||
| 367 | + | </interface> | |||
| 368 | + | ||||
| 369 | + | <interface name="zwlr_output_mode_v1" version="3"> | |||
| 370 | + | <description summary="output mode"> | |||
| 371 | + | This object describes an output mode. | |||
| 372 | + | ||||
| 373 | + | Some heads don't support output modes, in which case modes won't be | |||
| 374 | + | advertised. | |||
| 375 | + | ||||
| 376 | + | Properties sent via this interface are applied atomically via the | |||
| 377 | + | wlr_output_manager.done event. No guarantees are made regarding the order | |||
| 378 | + | in which properties are sent. | |||
| 379 | + | </description> | |||
| 380 | + | ||||
| 381 | + | <event name="size"> | |||
| 382 | + | <description summary="mode size"> | |||
| 383 | + | This event describes the mode size. The size is given in physical | |||
| 384 | + | hardware units of the output device. This is not necessarily the same as | |||
| 385 | + | the output size in the global compositor space. For instance, the output | |||
| 386 | + | may be scaled or transformed. | |||
| 387 | + | </description> | |||
| 388 | + | <arg name="width" type="int" summary="width of the mode in hardware units"/> | |||
| 389 | + | <arg name="height" type="int" summary="height of the mode in hardware units"/> | |||
| 390 | + | </event> | |||
| 391 | + | ||||
| 392 | + | <event name="refresh"> | |||
| 393 | + | <description summary="mode refresh rate"> | |||
| 394 | + | This event describes the mode's fixed vertical refresh rate. It is only | |||
| 395 | + | sent if the mode has a fixed refresh rate. | |||
| 396 | + | </description> | |||
| 397 | + | <arg name="refresh" type="int" summary="vertical refresh rate in mHz"/> | |||
| 398 | + | </event> | |||
| 399 | + | ||||
| 400 | + | <event name="preferred"> | |||
| 401 | + | <description summary="mode is preferred"> | |||
| 402 | + | This event advertises this mode as preferred. | |||
| 403 | + | </description> | |||
| 404 | + | </event> | |||
| 405 | + | ||||
| 406 | + | <event name="finished"> | |||
| 407 | + | <description summary="the mode has disappeared"> | |||
| 408 | + | This event indicates that the mode is no longer available. The mode | |||
| 409 | + | object becomes inert. Clients should send a destroy request and release | |||
| 410 | + | any resources associated with it. | |||
| 411 | + | </description> | |||
| 412 | + | </event> | |||
| 413 | + | ||||
| 414 | + | <!-- Version 3 additions --> | |||
| 415 | + | ||||
| 416 | + | <request name="release" type="destructor" since="3"> | |||
| 417 | + | <description summary="destroy the mode object"> | |||
| 418 | + | This request indicates that the client will no longer use this mode | |||
| 419 | + | object. | |||
| 420 | + | </description> | |||
| 421 | + | </request> | |||
| 422 | + | </interface> | |||
| 423 | + | ||||
| 424 | + | <interface name="zwlr_output_configuration_v1" version="4"> | |||
| 425 | + | <description summary="output configuration"> | |||
| 426 | + | This object is used by the client to describe a full output configuration. | |||
| 427 | + | ||||
| 428 | + | First, the client needs to setup the output configuration. Each head can | |||
| 429 | + | be either enabled (and configured) or disabled. It is a protocol error to | |||
| 430 | + | send two enable_head or disable_head requests with the same head. It is a | |||
| 431 | + | protocol error to omit a head in a configuration. | |||
| 432 | + | ||||
| 433 | + | Then, the client can apply or test the configuration. The compositor will | |||
| 434 | + | then reply with a succeeded, failed or cancelled event. Finally the client | |||
| 435 | + | should destroy the configuration object. | |||
| 436 | + | </description> | |||
| 437 | + | ||||
| 438 | + | <enum name="error"> | |||
| 439 | + | <entry name="already_configured_head" value="1" | |||
| 440 | + | summary="head has been configured twice"/> | |||
| 441 | + | <entry name="unconfigured_head" value="2" | |||
| 442 | + | summary="head has not been configured"/> | |||
| 443 | + | <entry name="already_used" value="3" | |||
| 444 | + | summary="request sent after configuration has been applied or tested"/> | |||
| 445 | + | </enum> | |||
| 446 | + | ||||
| 447 | + | <request name="enable_head"> | |||
| 448 | + | <description summary="enable and configure a head"> | |||
| 449 | + | Enable a head. This request creates a head configuration object that can | |||
| 450 | + | be used to change the head's properties. | |||
| 451 | + | </description> | |||
| 452 | + | <arg name="id" type="new_id" interface="zwlr_output_configuration_head_v1" | |||
| 453 | + | summary="a new object to configure the head"/> | |||
| 454 | + | <arg name="head" type="object" interface="zwlr_output_head_v1" | |||
| 455 | + | summary="the head to be enabled"/> | |||
| 456 | + | </request> | |||
| 457 | + | ||||
| 458 | + | <request name="disable_head"> | |||
| 459 | + | <description summary="disable a head"> | |||
| 460 | + | Disable a head. | |||
| 461 | + | </description> | |||
| 462 | + | <arg name="head" type="object" interface="zwlr_output_head_v1" | |||
| 463 | + | summary="the head to be disabled"/> | |||
| 464 | + | </request> | |||
| 465 | + | ||||
| 466 | + | <request name="apply"> | |||
| 467 | + | <description summary="apply the configuration"> | |||
| 468 | + | Apply the new output configuration. | |||
| 469 | + | ||||
| 470 | + | In case the configuration is successfully applied, there is no guarantee | |||
| 471 | + | that the new output state matches completely the requested | |||
| 472 | + | configuration. For instance, a compositor might round the scale if it | |||
| 473 | + | doesn't support fractional scaling. | |||
| 474 | + | ||||
| 475 | + | After this request has been sent, the compositor must respond with an | |||
| 476 | + | succeeded, failed or cancelled event. Sending a request that isn't the | |||
| 477 | + | destructor is a protocol error. | |||
| 478 | + | </description> | |||
| 479 | + | </request> | |||
| 480 | + | ||||
| 481 | + | <request name="test"> | |||
| 482 | + | <description summary="test the configuration"> | |||
| 483 | + | Test the new output configuration. The configuration won't be applied, | |||
| 484 | + | but will only be validated. | |||
| 485 | + | ||||
| 486 | + | Even if the compositor succeeds to test a configuration, applying it may | |||
| 487 | + | fail. | |||
| 488 | + | ||||
| 489 | + | After this request has been sent, the compositor must respond with an | |||
| 490 | + | succeeded, failed or cancelled event. Sending a request that isn't the | |||
| 491 | + | destructor is a protocol error. | |||
| 492 | + | </description> | |||
| 493 | + | </request> | |||
| 494 | + | ||||
| 495 | + | <event name="succeeded"> | |||
| 496 | + | <description summary="configuration changes succeeded"> | |||
| 497 | + | Sent after the compositor has successfully applied the changes or | |||
| 498 | + | tested them. | |||
| 499 | + | ||||
| 500 | + | Upon receiving this event, the client should destroy this object. | |||
| 501 | + | ||||
| 502 | + | If the current configuration has changed, events to describe the changes | |||
| 503 | + | will be sent followed by a wlr_output_manager.done event. | |||
| 504 | + | </description> | |||
| 505 | + | </event> | |||
| 506 | + | ||||
| 507 | + | <event name="failed"> | |||
| 508 | + | <description summary="configuration changes failed"> | |||
| 509 | + | Sent if the compositor rejects the changes or failed to apply them. The | |||
| 510 | + | compositor should revert any changes made by the apply request that | |||
| 511 | + | triggered this event. | |||
| 512 | + | ||||
| 513 | + | Upon receiving this event, the client should destroy this object. | |||
| 514 | + | </description> | |||
| 515 | + | </event> | |||
| 516 | + | ||||
| 517 | + | <event name="cancelled"> | |||
| 518 | + | <description summary="configuration has been cancelled"> | |||
| 519 | + | Sent if the compositor cancels the configuration because the state of an | |||
| 520 | + | output changed and the client has outdated information (e.g. after an | |||
| 521 | + | output has been hotplugged). | |||
| 522 | + | ||||
| 523 | + | The client can create a new configuration with a newer serial and try | |||
| 524 | + | again. | |||
| 525 | + | ||||
| 526 | + | Upon receiving this event, the client should destroy this object. | |||
| 527 | + | </description> | |||
| 528 | + | </event> | |||
| 529 | + | ||||
| 530 | + | <request name="destroy" type="destructor"> | |||
| 531 | + | <description summary="destroy the output configuration"> | |||
| 532 | + | Using this request a client can tell the compositor that it is not going | |||
| 533 | + | to use the configuration object anymore. Any changes to the outputs | |||
| 534 | + | that have not been applied will be discarded. | |||
| 535 | + | ||||
| 536 | + | This request also destroys wlr_output_configuration_head objects created | |||
| 537 | + | via this object. | |||
| 538 | + | </description> | |||
| 539 | + | </request> | |||
| 540 | + | </interface> | |||
| 541 | + | ||||
| 542 | + | <interface name="zwlr_output_configuration_head_v1" version="4"> | |||
| 543 | + | <description summary="head configuration"> | |||
| 544 | + | This object is used by the client to update a single head's configuration. | |||
| 545 | + | ||||
| 546 | + | It is a protocol error to set the same property twice. | |||
| 547 | + | </description> | |||
| 548 | + | ||||
| 549 | + | <enum name="error"> | |||
| 550 | + | <entry name="already_set" value="1" summary="property has already been set"/> | |||
| 551 | + | <entry name="invalid_mode" value="2" summary="mode doesn't belong to head"/> | |||
| 552 | + | <entry name="invalid_custom_mode" value="3" summary="mode is invalid"/> | |||
| 553 | + | <entry name="invalid_transform" value="4" summary="transform value outside enum"/> | |||
| 554 | + | <entry name="invalid_scale" value="5" summary="scale negative or zero"/> | |||
| 555 | + | <entry name="invalid_adaptive_sync_state" value="6" since="4" | |||
| 556 | + | summary="invalid enum value used in the set_adaptive_sync request"/> | |||
| 557 | + | </enum> | |||
| 558 | + | ||||
| 559 | + | <request name="set_mode"> | |||
| 560 | + | <description summary="set the mode"> | |||
| 561 | + | This request sets the head's mode. | |||
| 562 | + | </description> | |||
| 563 | + | <arg name="mode" type="object" interface="zwlr_output_mode_v1"/> | |||
| 564 | + | </request> | |||
| 565 | + | ||||
| 566 | + | <request name="set_custom_mode"> | |||
| 567 | + | <description summary="set a custom mode"> | |||
| 568 | + | This request assigns a custom mode to the head. The size is given in | |||
| 569 | + | physical hardware units of the output device. If set to zero, the | |||
| 570 | + | refresh rate is unspecified. | |||
| 571 | + | ||||
| 572 | + | It is a protocol error to set both a mode and a custom mode. | |||
| 573 | + | </description> | |||
| 574 | + | <arg name="width" type="int" summary="width of the mode in hardware units"/> | |||
| 575 | + | <arg name="height" type="int" summary="height of the mode in hardware units"/> | |||
| 576 | + | <arg name="refresh" type="int" summary="vertical refresh rate in mHz or zero"/> | |||
| 577 | + | </request> | |||
| 578 | + | ||||
| 579 | + | <request name="set_position"> | |||
| 580 | + | <description summary="set the position"> | |||
| 581 | + | This request sets the head's position in the global compositor space. | |||
| 582 | + | </description> | |||
| 583 | + | <arg name="x" type="int" summary="x position in the global compositor space"/> | |||
| 584 | + | <arg name="y" type="int" summary="y position in the global compositor space"/> | |||
| 585 | + | </request> | |||
| 586 | + | ||||
| 587 | + | <request name="set_transform"> | |||
| 588 | + | <description summary="set the transform"> | |||
| 589 | + | This request sets the head's transform. | |||
| 590 | + | </description> | |||
| 591 | + | <arg name="transform" type="int" enum="wl_output.transform"/> | |||
| 592 | + | </request> | |||
| 593 | + | ||||
| 594 | + | <request name="set_scale"> | |||
| 595 | + | <description summary="set the scale"> | |||
| 596 | + | This request sets the head's scale. | |||
| 597 | + | </description> | |||
| 598 | + | <arg name="scale" type="fixed"/> | |||
| 599 | + | </request> | |||
| 600 | + | ||||
| 601 | + | <!-- Version 4 additions --> | |||
| 602 | + | ||||
| 603 | + | <request name="set_adaptive_sync" since="4"> | |||
| 604 | + | <description summary="enable/disable adaptive sync"> | |||
| 605 | + | This request enables/disables adaptive sync. Adaptive sync is also | |||
| 606 | + | known as Variable Refresh Rate or VRR. | |||
| 607 | + | </description> | |||
| 608 | + | <arg name="state" type="uint" enum="zwlr_output_head_v1.adaptive_sync_state"/> | |||
| 609 | + | </request> | |||
| 610 | + | </interface> | |||
| 611 | + | </protocol> | |||
A spec/xml/wlroutputpowermanagement.xml +128 -0
| @@ -0,0 +1,128 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="wlr_output_power_management_unstable_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2019 Purism SPC | |||
| 5 | + | ||||
| 6 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 7 | + | copy of this software and associated documentation files (the "Software"), | |||
| 8 | + | to deal in the Software without restriction, including without limitation | |||
| 9 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 10 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 11 | + | Software is furnished to do so, subject to the following conditions: | |||
| 12 | + | ||||
| 13 | + | The above copyright notice and this permission notice (including the next | |||
| 14 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 15 | + | Software. | |||
| 16 | + | ||||
| 17 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 18 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 19 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 20 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 21 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 22 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 23 | + | DEALINGS IN THE SOFTWARE. | |||
| 24 | + | </copyright> | |||
| 25 | + | ||||
| 26 | + | <description summary="Control power management modes of outputs"> | |||
| 27 | + | This protocol allows clients to control power management modes | |||
| 28 | + | of outputs that are currently part of the compositor space. The | |||
| 29 | + | intent is to allow special clients like desktop shells to power | |||
| 30 | + | down outputs when the system is idle. | |||
| 31 | + | ||||
| 32 | + | To modify outputs not currently part of the compositor space see | |||
| 33 | + | wlr-output-management. | |||
| 34 | + | ||||
| 35 | + | Warning! The protocol described in this file is experimental and | |||
| 36 | + | backward incompatible changes may be made. Backward compatible changes | |||
| 37 | + | may be added together with the corresponding interface version bump. | |||
| 38 | + | Backward incompatible changes are done by bumping the version number in | |||
| 39 | + | the protocol and interface names and resetting the interface version. | |||
| 40 | + | Once the protocol is to be declared stable, the 'z' prefix and the | |||
| 41 | + | version number in the protocol and interface names are removed and the | |||
| 42 | + | interface version number is reset. | |||
| 43 | + | </description> | |||
| 44 | + | ||||
| 45 | + | <interface name="zwlr_output_power_manager_v1" version="1"> | |||
| 46 | + | <description summary="manager to create per-output power management"> | |||
| 47 | + | This interface is a manager that allows creating per-output power | |||
| 48 | + | management mode controls. | |||
| 49 | + | </description> | |||
| 50 | + | ||||
| 51 | + | <request name="get_output_power"> | |||
| 52 | + | <description summary="get a power management for an output"> | |||
| 53 | + | Create an output power management mode control that can be used to | |||
| 54 | + | adjust the power management mode for a given output. | |||
| 55 | + | </description> | |||
| 56 | + | <arg name="id" type="new_id" interface="zwlr_output_power_v1"/> | |||
| 57 | + | <arg name="output" type="object" interface="wl_output"/> | |||
| 58 | + | </request> | |||
| 59 | + | ||||
| 60 | + | <request name="destroy" type="destructor"> | |||
| 61 | + | <description summary="destroy the manager"> | |||
| 62 | + | All objects created by the manager will still remain valid, until their | |||
| 63 | + | appropriate destroy request has been called. | |||
| 64 | + | </description> | |||
| 65 | + | </request> | |||
| 66 | + | </interface> | |||
| 67 | + | ||||
| 68 | + | <interface name="zwlr_output_power_v1" version="1"> | |||
| 69 | + | <description summary="adjust power management mode for an output"> | |||
| 70 | + | This object offers requests to set the power management mode of | |||
| 71 | + | an output. | |||
| 72 | + | </description> | |||
| 73 | + | ||||
| 74 | + | <enum name="mode"> | |||
| 75 | + | <entry name="off" value="0" | |||
| 76 | + | summary="Output is turned off."/> | |||
| 77 | + | <entry name="on" value="1" | |||
| 78 | + | summary="Output is turned on, no power saving"/> | |||
| 79 | + | </enum> | |||
| 80 | + | ||||
| 81 | + | <enum name="error"> | |||
| 82 | + | <entry name="invalid_mode" value="1" summary="nonexistent power save mode"/> | |||
| 83 | + | </enum> | |||
| 84 | + | ||||
| 85 | + | <request name="set_mode"> | |||
| 86 | + | <description summary="Set an outputs power save mode"> | |||
| 87 | + | Set an output's power save mode to the given mode. The mode change | |||
| 88 | + | is effective immediately. If the output does not support the given | |||
| 89 | + | mode a failed event is sent. | |||
| 90 | + | </description> | |||
| 91 | + | <arg name="mode" type="uint" enum="mode" summary="the power save mode to set"/> | |||
| 92 | + | </request> | |||
| 93 | + | ||||
| 94 | + | <event name="mode"> | |||
| 95 | + | <description summary="Report a power management mode change"> | |||
| 96 | + | Report the power management mode change of an output. | |||
| 97 | + | ||||
| 98 | + | The mode event is sent after an output changed its power | |||
| 99 | + | management mode. The reason can be a client using set_mode or the | |||
| 100 | + | compositor deciding to change an output's mode. | |||
| 101 | + | This event is also sent immediately when the object is created | |||
| 102 | + | so the client is informed about the current power management mode. | |||
| 103 | + | </description> | |||
| 104 | + | <arg name="mode" type="uint" enum="mode" | |||
| 105 | + | summary="the output's new power management mode"/> | |||
| 106 | + | </event> | |||
| 107 | + | ||||
| 108 | + | <event name="failed"> | |||
| 109 | + | <description summary="object no longer valid"> | |||
| 110 | + | This event indicates that the output power management mode control | |||
| 111 | + | is no longer valid. This can happen for a number of reasons, | |||
| 112 | + | including: | |||
| 113 | + | - The output doesn't support power management | |||
| 114 | + | - Another client already has exclusive power management mode control | |||
| 115 | + | for this output | |||
| 116 | + | - The output disappeared | |||
| 117 | + | ||||
| 118 | + | Upon receiving this event, the client should destroy this object. | |||
| 119 | + | </description> | |||
| 120 | + | </event> | |||
| 121 | + | ||||
| 122 | + | <request name="destroy" type="destructor"> | |||
| 123 | + | <description summary="destroy this power management"> | |||
| 124 | + | Destroys the output power management mode control object. | |||
| 125 | + | </description> | |||
| 126 | + | </request> | |||
| 127 | + | </interface> | |||
| 128 | + | </protocol> | |||
A spec/xml/wlrscreencopy.xml +234 -0
| @@ -0,0 +1,234 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="wlr_screencopy_unstable_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2018 Simon Ser | |||
| 5 | + | Copyright © 2019 Andri Yngvason | |||
| 6 | + | ||||
| 7 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 8 | + | copy of this software and associated documentation files (the "Software"), | |||
| 9 | + | to deal in the Software without restriction, including without limitation | |||
| 10 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 11 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 12 | + | Software is furnished to do so, subject to the following conditions: | |||
| 13 | + | ||||
| 14 | + | The above copyright notice and this permission notice (including the next | |||
| 15 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 16 | + | Software. | |||
| 17 | + | ||||
| 18 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 19 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 20 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 21 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 22 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 23 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 24 | + | DEALINGS IN THE SOFTWARE. | |||
| 25 | + | </copyright> | |||
| 26 | + | ||||
| 27 | + | <description summary="screen content capturing on client buffers"> | |||
| 28 | + | This protocol allows clients to ask the compositor to copy part of the | |||
| 29 | + | screen content to a client buffer. | |||
| 30 | + | ||||
| 31 | + | Warning! The protocol described in this file is experimental and | |||
| 32 | + | backward incompatible changes may be made. Backward compatible changes | |||
| 33 | + | may be added together with the corresponding interface version bump. | |||
| 34 | + | Backward incompatible changes are done by bumping the version number in | |||
| 35 | + | the protocol and interface names and resetting the interface version. | |||
| 36 | + | Once the protocol is to be declared stable, the 'z' prefix and the | |||
| 37 | + | version number in the protocol and interface names are removed and the | |||
| 38 | + | interface version number is reset. | |||
| 39 | + | ||||
| 40 | + | Note! This protocol is deprecated and not intended for production use. | |||
| 41 | + | The ext-image-copy-capture-v1 protocol should be used instead. | |||
| 42 | + | </description> | |||
| 43 | + | ||||
| 44 | + | <interface name="zwlr_screencopy_manager_v1" version="3"> | |||
| 45 | + | <description summary="manager to inform clients and begin capturing"> | |||
| 46 | + | This object is a manager which offers requests to start capturing from a | |||
| 47 | + | source. | |||
| 48 | + | </description> | |||
| 49 | + | ||||
| 50 | + | <request name="capture_output"> | |||
| 51 | + | <description summary="capture an output"> | |||
| 52 | + | Capture the next frame of an entire output. | |||
| 53 | + | </description> | |||
| 54 | + | <arg name="frame" type="new_id" interface="zwlr_screencopy_frame_v1"/> | |||
| 55 | + | <arg name="overlay_cursor" type="int" | |||
| 56 | + | summary="composite cursor onto the frame"/> | |||
| 57 | + | <arg name="output" type="object" interface="wl_output"/> | |||
| 58 | + | </request> | |||
| 59 | + | ||||
| 60 | + | <request name="capture_output_region"> | |||
| 61 | + | <description summary="capture an output's region"> | |||
| 62 | + | Capture the next frame of an output's region. | |||
| 63 | + | ||||
| 64 | + | The region is given in output logical coordinates, see | |||
| 65 | + | xdg_output.logical_size. The region will be clipped to the output's | |||
| 66 | + | extents. | |||
| 67 | + | </description> | |||
| 68 | + | <arg name="frame" type="new_id" interface="zwlr_screencopy_frame_v1"/> | |||
| 69 | + | <arg name="overlay_cursor" type="int" | |||
| 70 | + | summary="composite cursor onto the frame"/> | |||
| 71 | + | <arg name="output" type="object" interface="wl_output"/> | |||
| 72 | + | <arg name="x" type="int"/> | |||
| 73 | + | <arg name="y" type="int"/> | |||
| 74 | + | <arg name="width" type="int"/> | |||
| 75 | + | <arg name="height" type="int"/> | |||
| 76 | + | </request> | |||
| 77 | + | ||||
| 78 | + | <request name="destroy" type="destructor"> | |||
| 79 | + | <description summary="destroy the manager"> | |||
| 80 | + | All objects created by the manager will still remain valid, until their | |||
| 81 | + | appropriate destroy request has been called. | |||
| 82 | + | </description> | |||
| 83 | + | </request> | |||
| 84 | + | </interface> | |||
| 85 | + | ||||
| 86 | + | <interface name="zwlr_screencopy_frame_v1" version="3"> | |||
| 87 | + | <description summary="a frame ready for copy"> | |||
| 88 | + | This object represents a single frame. | |||
| 89 | + | ||||
| 90 | + | When created, a series of buffer events will be sent, each representing a | |||
| 91 | + | supported buffer type. The "buffer_done" event is sent afterwards to | |||
| 92 | + | indicate that all supported buffer types have been enumerated. The client | |||
| 93 | + | will then be able to send a "copy" request. If the capture is successful, | |||
| 94 | + | the compositor will send a "flags" event followed by a "ready" event. | |||
| 95 | + | ||||
| 96 | + | For objects version 2 or lower, wl_shm buffers are always supported, ie. | |||
| 97 | + | the "buffer" event is guaranteed to be sent. | |||
| 98 | + | ||||
| 99 | + | If the capture failed, the "failed" event is sent. This can happen anytime | |||
| 100 | + | before the "ready" event. | |||
| 101 | + | ||||
| 102 | + | Once either a "ready" or a "failed" event is received, the client should | |||
| 103 | + | destroy the frame. | |||
| 104 | + | </description> | |||
| 105 | + | ||||
| 106 | + | <event name="buffer"> | |||
| 107 | + | <description summary="wl_shm buffer information"> | |||
| 108 | + | Provides information about wl_shm buffer parameters that need to be | |||
| 109 | + | used for this frame. This event is sent once after the frame is created | |||
| 110 | + | if wl_shm buffers are supported. | |||
| 111 | + | </description> | |||
| 112 | + | <arg name="format" type="uint" enum="wl_shm.format" summary="buffer format"/> | |||
| 113 | + | <arg name="width" type="uint" summary="buffer width"/> | |||
| 114 | + | <arg name="height" type="uint" summary="buffer height"/> | |||
| 115 | + | <arg name="stride" type="uint" summary="buffer stride"/> | |||
| 116 | + | </event> | |||
| 117 | + | ||||
| 118 | + | <request name="copy"> | |||
| 119 | + | <description summary="copy the frame"> | |||
| 120 | + | Copy the frame to the supplied buffer. The buffer must have the | |||
| 121 | + | correct size, see zwlr_screencopy_frame_v1.buffer and | |||
| 122 | + | zwlr_screencopy_frame_v1.linux_dmabuf. The buffer needs to have a | |||
| 123 | + | supported format. | |||
| 124 | + | ||||
| 125 | + | If the frame is successfully copied, "flags" and "ready" events are | |||
| 126 | + | sent. Otherwise, a "failed" event is sent. | |||
| 127 | + | </description> | |||
| 128 | + | <arg name="buffer" type="object" interface="wl_buffer"/> | |||
| 129 | + | </request> | |||
| 130 | + | ||||
| 131 | + | <enum name="error"> | |||
| 132 | + | <entry name="already_used" value="0" | |||
| 133 | + | summary="the object has already been used to copy a wl_buffer"/> | |||
| 134 | + | <entry name="invalid_buffer" value="1" | |||
| 135 | + | summary="buffer attributes are invalid"/> | |||
| 136 | + | </enum> | |||
| 137 | + | ||||
| 138 | + | <enum name="flags" bitfield="true"> | |||
| 139 | + | <entry name="y_invert" value="1" summary="contents are y-inverted"/> | |||
| 140 | + | </enum> | |||
| 141 | + | ||||
| 142 | + | <event name="flags"> | |||
| 143 | + | <description summary="frame flags"> | |||
| 144 | + | Provides flags about the frame. This event is sent once before the | |||
| 145 | + | "ready" event. | |||
| 146 | + | </description> | |||
| 147 | + | <arg name="flags" type="uint" enum="flags" summary="frame flags"/> | |||
| 148 | + | </event> | |||
| 149 | + | ||||
| 150 | + | <event name="ready"> | |||
| 151 | + | <description summary="indicates frame is available for reading"> | |||
| 152 | + | Called as soon as the frame is copied, indicating it is available | |||
| 153 | + | for reading. This event includes the time at which the presentation took place. | |||
| 154 | + | ||||
| 155 | + | The timestamp is expressed as tv_sec_hi, tv_sec_lo, tv_nsec triples, | |||
| 156 | + | each component being an unsigned 32-bit value. Whole seconds are in | |||
| 157 | + | tv_sec which is a 64-bit value combined from tv_sec_hi and tv_sec_lo, | |||
| 158 | + | and the additional fractional part in tv_nsec as nanoseconds. Hence, | |||
| 159 | + | for valid timestamps tv_nsec must be in [0, 999999999]. The seconds part | |||
| 160 | + | may have an arbitrary offset at start. | |||
| 161 | + | ||||
| 162 | + | After receiving this event, the client should destroy the object. | |||
| 163 | + | </description> | |||
| 164 | + | <arg name="tv_sec_hi" type="uint" | |||
| 165 | + | summary="high 32 bits of the seconds part of the timestamp"/> | |||
| 166 | + | <arg name="tv_sec_lo" type="uint" | |||
| 167 | + | summary="low 32 bits of the seconds part of the timestamp"/> | |||
| 168 | + | <arg name="tv_nsec" type="uint" | |||
| 169 | + | summary="nanoseconds part of the timestamp"/> | |||
| 170 | + | </event> | |||
| 171 | + | ||||
| 172 | + | <event name="failed"> | |||
| 173 | + | <description summary="frame copy failed"> | |||
| 174 | + | This event indicates that the attempted frame copy has failed. | |||
| 175 | + | ||||
| 176 | + | After receiving this event, the client should destroy the object. | |||
| 177 | + | </description> | |||
| 178 | + | </event> | |||
| 179 | + | ||||
| 180 | + | <request name="destroy" type="destructor"> | |||
| 181 | + | <description summary="delete this object, used or not"> | |||
| 182 | + | Destroys the frame. This request can be sent at any time by the client. | |||
| 183 | + | </description> | |||
| 184 | + | </request> | |||
| 185 | + | ||||
| 186 | + | <!-- Version 2 additions --> | |||
| 187 | + | <request name="copy_with_damage" since="2"> | |||
| 188 | + | <description summary="copy the frame when it's damaged"> | |||
| 189 | + | Same as copy, except it waits until there is damage to copy. | |||
| 190 | + | </description> | |||
| 191 | + | <arg name="buffer" type="object" interface="wl_buffer"/> | |||
| 192 | + | </request> | |||
| 193 | + | ||||
| 194 | + | <event name="damage" since="2"> | |||
| 195 | + | <description summary="carries the coordinates of the damaged region"> | |||
| 196 | + | This event is sent right before the ready event when copy_with_damage is | |||
| 197 | + | requested. It may be generated multiple times for each copy_with_damage | |||
| 198 | + | request. | |||
| 199 | + | ||||
| 200 | + | The arguments describe a box around an area that has changed since the | |||
| 201 | + | last copy request that was derived from the current screencopy manager | |||
| 202 | + | instance. | |||
| 203 | + | ||||
| 204 | + | The union of all regions received between the call to copy_with_damage | |||
| 205 | + | and a ready event is the total damage since the prior ready event. | |||
| 206 | + | </description> | |||
| 207 | + | <arg name="x" type="uint" summary="damaged x coordinates"/> | |||
| 208 | + | <arg name="y" type="uint" summary="damaged y coordinates"/> | |||
| 209 | + | <arg name="width" type="uint" summary="current width"/> | |||
| 210 | + | <arg name="height" type="uint" summary="current height"/> | |||
| 211 | + | </event> | |||
| 212 | + | ||||
| 213 | + | <!-- Version 3 additions --> | |||
| 214 | + | <event name="linux_dmabuf" since="3"> | |||
| 215 | + | <description summary="linux-dmabuf buffer information"> | |||
| 216 | + | Provides information about linux-dmabuf buffer parameters that need to | |||
| 217 | + | be used for this frame. This event is sent once after the frame is | |||
| 218 | + | created if linux-dmabuf buffers are supported. | |||
| 219 | + | </description> | |||
| 220 | + | <arg name="format" type="uint" summary="fourcc pixel format"/> | |||
| 221 | + | <arg name="width" type="uint" summary="buffer width"/> | |||
| 222 | + | <arg name="height" type="uint" summary="buffer height"/> | |||
| 223 | + | </event> | |||
| 224 | + | ||||
| 225 | + | <event name="buffer_done" since="3"> | |||
| 226 | + | <description summary="all buffer types reported"> | |||
| 227 | + | This event is sent once after all buffer events have been sent. | |||
| 228 | + | ||||
| 229 | + | The client should proceed to create a buffer of one of the supported | |||
| 230 | + | types, and send a "copy" request. | |||
| 231 | + | </description> | |||
| 232 | + | </event> | |||
| 233 | + | </interface> | |||
| 234 | + | </protocol> | |||
A spec/xml/wlrvirtualpointer.xml +152 -0
| @@ -0,0 +1,152 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="wlr_virtual_pointer_unstable_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2019 Josef Gajdusek | |||
| 5 | + | ||||
| 6 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 7 | + | copy of this software and associated documentation files (the "Software"), | |||
| 8 | + | to deal in the Software without restriction, including without limitation | |||
| 9 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 10 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 11 | + | Software is furnished to do so, subject to the following conditions: | |||
| 12 | + | ||||
| 13 | + | The above copyright notice and this permission notice (including the next | |||
| 14 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 15 | + | Software. | |||
| 16 | + | ||||
| 17 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 18 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 19 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 20 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 21 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 22 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 23 | + | DEALINGS IN THE SOFTWARE. | |||
| 24 | + | </copyright> | |||
| 25 | + | ||||
| 26 | + | <interface name="zwlr_virtual_pointer_v1" version="2"> | |||
| 27 | + | <description summary="virtual pointer"> | |||
| 28 | + | This protocol allows clients to emulate a physical pointer device. The | |||
| 29 | + | requests are mostly mirror opposites of those specified in wl_pointer. | |||
| 30 | + | </description> | |||
| 31 | + | ||||
| 32 | + | <enum name="error"> | |||
| 33 | + | <entry name="invalid_axis" value="0" | |||
| 34 | + | summary="client sent invalid axis enumeration value" /> | |||
| 35 | + | <entry name="invalid_axis_source" value="1" | |||
| 36 | + | summary="client sent invalid axis source enumeration value" /> | |||
| 37 | + | </enum> | |||
| 38 | + | ||||
| 39 | + | <request name="motion"> | |||
| 40 | + | <description summary="pointer relative motion event"> | |||
| 41 | + | The pointer has moved by a relative amount to the previous request. | |||
| 42 | + | ||||
| 43 | + | Values are in the global compositor space. | |||
| 44 | + | </description> | |||
| 45 | + | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |||
| 46 | + | <arg name="dx" type="fixed" summary="displacement on the x-axis"/> | |||
| 47 | + | <arg name="dy" type="fixed" summary="displacement on the y-axis"/> | |||
| 48 | + | </request> | |||
| 49 | + | ||||
| 50 | + | <request name="motion_absolute"> | |||
| 51 | + | <description summary="pointer absolute motion event"> | |||
| 52 | + | The pointer has moved in an absolute coordinate frame. | |||
| 53 | + | ||||
| 54 | + | Value of x can range from 0 to x_extent, value of y can range from 0 | |||
| 55 | + | to y_extent. | |||
| 56 | + | </description> | |||
| 57 | + | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |||
| 58 | + | <arg name="x" type="uint" summary="position on the x-axis"/> | |||
| 59 | + | <arg name="y" type="uint" summary="position on the y-axis"/> | |||
| 60 | + | <arg name="x_extent" type="uint" summary="extent of the x-axis"/> | |||
| 61 | + | <arg name="y_extent" type="uint" summary="extent of the y-axis"/> | |||
| 62 | + | </request> | |||
| 63 | + | ||||
| 64 | + | <request name="button"> | |||
| 65 | + | <description summary="button event"> | |||
| 66 | + | A button was pressed or released. | |||
| 67 | + | </description> | |||
| 68 | + | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |||
| 69 | + | <arg name="button" type="uint" summary="button that produced the event"/> | |||
| 70 | + | <arg name="state" type="uint" enum="wl_pointer.button_state" summary="physical state of the button"/> | |||
| 71 | + | </request> | |||
| 72 | + | ||||
| 73 | + | <request name="axis"> | |||
| 74 | + | <description summary="axis event"> | |||
| 75 | + | Scroll and other axis requests. | |||
| 76 | + | </description> | |||
| 77 | + | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |||
| 78 | + | <arg name="axis" type="uint" enum="wl_pointer.axis" summary="axis type"/> | |||
| 79 | + | <arg name="value" type="fixed" summary="length of vector in touchpad coordinates"/> | |||
| 80 | + | </request> | |||
| 81 | + | ||||
| 82 | + | <request name="frame"> | |||
| 83 | + | <description summary="end of a pointer event sequence"> | |||
| 84 | + | Indicates the set of events that logically belong together. | |||
| 85 | + | </description> | |||
| 86 | + | </request> | |||
| 87 | + | ||||
| 88 | + | <request name="axis_source"> | |||
| 89 | + | <description summary="axis source event"> | |||
| 90 | + | Source information for scroll and other axis. | |||
| 91 | + | </description> | |||
| 92 | + | <arg name="axis_source" type="uint" enum="wl_pointer.axis_source" summary="source of the axis event"/> | |||
| 93 | + | </request> | |||
| 94 | + | ||||
| 95 | + | <request name="axis_stop"> | |||
| 96 | + | <description summary="axis stop event"> | |||
| 97 | + | Stop notification for scroll and other axes. | |||
| 98 | + | </description> | |||
| 99 | + | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |||
| 100 | + | <arg name="axis" type="uint" enum="wl_pointer.axis" summary="the axis stopped with this event"/> | |||
| 101 | + | </request> | |||
| 102 | + | ||||
| 103 | + | <request name="axis_discrete"> | |||
| 104 | + | <description summary="axis click event"> | |||
| 105 | + | Discrete step information for scroll and other axes. | |||
| 106 | + | ||||
| 107 | + | This event allows the client to extend data normally sent using the axis | |||
| 108 | + | event with discrete value. | |||
| 109 | + | </description> | |||
| 110 | + | <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> | |||
| 111 | + | <arg name="axis" type="uint" enum="wl_pointer.axis" summary="axis type"/> | |||
| 112 | + | <arg name="value" type="fixed" summary="length of vector in touchpad coordinates"/> | |||
| 113 | + | <arg name="discrete" type="int" summary="number of steps"/> | |||
| 114 | + | </request> | |||
| 115 | + | ||||
| 116 | + | <request name="destroy" type="destructor" since="1"> | |||
| 117 | + | <description summary="destroy the virtual pointer object"/> | |||
| 118 | + | </request> | |||
| 119 | + | </interface> | |||
| 120 | + | ||||
| 121 | + | <interface name="zwlr_virtual_pointer_manager_v1" version="2"> | |||
| 122 | + | <description summary="virtual pointer manager"> | |||
| 123 | + | This object allows clients to create individual virtual pointer objects. | |||
| 124 | + | </description> | |||
| 125 | + | ||||
| 126 | + | <request name="create_virtual_pointer"> | |||
| 127 | + | <description summary="Create a new virtual pointer"> | |||
| 128 | + | Creates a new virtual pointer. The optional seat is a suggestion to the | |||
| 129 | + | compositor. | |||
| 130 | + | </description> | |||
| 131 | + | <arg name="seat" type="object" interface="wl_seat" allow-null="true"/> | |||
| 132 | + | <arg name="id" type="new_id" interface="zwlr_virtual_pointer_v1"/> | |||
| 133 | + | </request> | |||
| 134 | + | ||||
| 135 | + | <request name="destroy" type="destructor" since="1"> | |||
| 136 | + | <description summary="destroy the virtual pointer manager"/> | |||
| 137 | + | </request> | |||
| 138 | + | ||||
| 139 | + | <!-- Version 2 additions --> | |||
| 140 | + | <request name="create_virtual_pointer_with_output" since="2"> | |||
| 141 | + | <description summary="Create a new virtual pointer"> | |||
| 142 | + | Creates a new virtual pointer. The seat and the output arguments are | |||
| 143 | + | optional. If the seat argument is set, the compositor should assign the | |||
| 144 | + | input device to the requested seat. If the output argument is set, the | |||
| 145 | + | compositor should map the input device to the requested output. | |||
| 146 | + | </description> | |||
| 147 | + | <arg name="seat" type="object" interface="wl_seat" allow-null="true"/> | |||
| 148 | + | <arg name="output" type="object" interface="wl_output" allow-null="true"/> | |||
| 149 | + | <arg name="id" type="new_id" interface="zwlr_virtual_pointer_v1"/> | |||
| 150 | + | </request> | |||
| 151 | + | </interface> | |||
| 152 | + | </protocol> | |||
A spec/xml/xdgactivation.xml +200 -0
| @@ -0,0 +1,200 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="xdg_activation_v1"> | |||
| 3 | + | ||||
| 4 | + | <copyright> | |||
| 5 | + | Copyright © 2020 Aleix Pol Gonzalez <aleixpol@kde.org> | |||
| 6 | + | Copyright © 2020 Carlos Garnacho <carlosg@gnome.org> | |||
| 7 | + | ||||
| 8 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 9 | + | copy of this software and associated documentation files (the "Software"), | |||
| 10 | + | to deal in the Software without restriction, including without limitation | |||
| 11 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 12 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 13 | + | Software is furnished to do so, subject to the following conditions: | |||
| 14 | + | ||||
| 15 | + | The above copyright notice and this permission notice (including the next | |||
| 16 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 17 | + | Software. | |||
| 18 | + | ||||
| 19 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 20 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 21 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 22 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 23 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 24 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 25 | + | DEALINGS IN THE SOFTWARE. | |||
| 26 | + | </copyright> | |||
| 27 | + | ||||
| 28 | + | <description summary="Protocol for requesting activation of surfaces"> | |||
| 29 | + | The way for a client to pass focus to another toplevel is as follows. | |||
| 30 | + | ||||
| 31 | + | The client that intends to activate another toplevel uses the | |||
| 32 | + | xdg_activation_v1.get_activation_token request to get an activation token. | |||
| 33 | + | This token is then forwarded to the client, which is supposed to activate | |||
| 34 | + | one of its surfaces, through a separate band of communication. | |||
| 35 | + | ||||
| 36 | + | One established way of doing this is through the XDG_ACTIVATION_TOKEN | |||
| 37 | + | environment variable of a newly launched child process. The child process | |||
| 38 | + | should unset the environment variable again right after reading it out in | |||
| 39 | + | order to avoid propagating it to other child processes. | |||
| 40 | + | ||||
| 41 | + | Another established way exists for Applications implementing the D-Bus | |||
| 42 | + | interface org.freedesktop.Application, which should get their token under | |||
| 43 | + | activation-token on their platform_data. | |||
| 44 | + | ||||
| 45 | + | In general activation tokens may be transferred across clients through | |||
| 46 | + | means not described in this protocol. | |||
| 47 | + | ||||
| 48 | + | The client to be activated will then pass the token | |||
| 49 | + | it received to the xdg_activation_v1.activate request. The compositor can | |||
| 50 | + | then use this token to decide how to react to the activation request. | |||
| 51 | + | ||||
| 52 | + | The token the activating client gets may be ineffective either already at | |||
| 53 | + | the time it receives it, for example if it was not focused, for focus | |||
| 54 | + | stealing prevention. The activating client will have no way to discover | |||
| 55 | + | the validity of the token, and may still forward it to the to be activated | |||
| 56 | + | client. | |||
| 57 | + | ||||
| 58 | + | The created activation token may optionally get information attached to it | |||
| 59 | + | that can be used by the compositor to identify the application that we | |||
| 60 | + | intend to activate. This can for example be used to display a visual hint | |||
| 61 | + | about what application is being started. | |||
| 62 | + | ||||
| 63 | + | Warning! The protocol described in this file is currently in the testing | |||
| 64 | + | phase. Backward compatible changes may be added together with the | |||
| 65 | + | corresponding interface version bump. Backward incompatible changes can | |||
| 66 | + | only be done by creating a new major version of the extension. | |||
| 67 | + | </description> | |||
| 68 | + | ||||
| 69 | + | <interface name="xdg_activation_v1" version="1"> | |||
| 70 | + | <description summary="interface for activating surfaces"> | |||
| 71 | + | A global interface used for informing the compositor about applications | |||
| 72 | + | being activated or started, or for applications to request to be | |||
| 73 | + | activated. | |||
| 74 | + | </description> | |||
| 75 | + | ||||
| 76 | + | <request name="destroy" type="destructor"> | |||
| 77 | + | <description summary="destroy the xdg_activation object"> | |||
| 78 | + | Notify the compositor that the xdg_activation object will no longer be | |||
| 79 | + | used. | |||
| 80 | + | ||||
| 81 | + | The child objects created via this interface are unaffected and should | |||
| 82 | + | be destroyed separately. | |||
| 83 | + | </description> | |||
| 84 | + | </request> | |||
| 85 | + | ||||
| 86 | + | <request name="get_activation_token"> | |||
| 87 | + | <description summary="requests a token"> | |||
| 88 | + | Creates an xdg_activation_token_v1 object that will provide | |||
| 89 | + | the initiating client with a unique token for this activation. This | |||
| 90 | + | token should be offered to the clients to be activated. | |||
| 91 | + | </description> | |||
| 92 | + | ||||
| 93 | + | <arg name="id" type="new_id" interface="xdg_activation_token_v1"/> | |||
| 94 | + | </request> | |||
| 95 | + | ||||
| 96 | + | <request name="activate"> | |||
| 97 | + | <description summary="notify new interaction being available"> | |||
| 98 | + | Requests surface activation. It's up to the compositor to display | |||
| 99 | + | this information as desired, for example by placing the surface above | |||
| 100 | + | the rest. | |||
| 101 | + | ||||
| 102 | + | The compositor may know who requested this by checking the activation | |||
| 103 | + | token and might decide not to follow through with the activation if it's | |||
| 104 | + | considered unwanted. | |||
| 105 | + | ||||
| 106 | + | Compositors can ignore unknown activation tokens when an invalid | |||
| 107 | + | token is passed. | |||
| 108 | + | </description> | |||
| 109 | + | <arg name="token" type="string" summary="the activation token of the initiating client"/> | |||
| 110 | + | <arg name="surface" type="object" interface="wl_surface" | |||
| 111 | + | summary="the wl_surface to activate"/> | |||
| 112 | + | </request> | |||
| 113 | + | </interface> | |||
| 114 | + | ||||
| 115 | + | <interface name="xdg_activation_token_v1" version="1"> | |||
| 116 | + | <description summary="an exported activation handle"> | |||
| 117 | + | An object for setting up a token and receiving a token handle that can | |||
| 118 | + | be passed as an activation token to another client. | |||
| 119 | + | ||||
| 120 | + | The object is created using the xdg_activation_v1.get_activation_token | |||
| 121 | + | request. This object should then be populated with the app_id, surface | |||
| 122 | + | and serial information and committed. The compositor shall then issue a | |||
| 123 | + | done event with the token. In case the request's parameters are invalid, | |||
| 124 | + | the compositor will provide an invalid token. | |||
| 125 | + | </description> | |||
| 126 | + | ||||
| 127 | + | <enum name="error"> | |||
| 128 | + | <entry name="already_used" value="0" | |||
| 129 | + | summary="The token has already been used previously"/> | |||
| 130 | + | </enum> | |||
| 131 | + | ||||
| 132 | + | <request name="set_serial"> | |||
| 133 | + | <description summary="specifies the seat and serial of the activating event"> | |||
| 134 | + | Provides information about the seat and serial event that requested the | |||
| 135 | + | token. | |||
| 136 | + | ||||
| 137 | + | The serial can come from an input or focus event. For instance, if a | |||
| 138 | + | click triggers the launch of a third-party client, the launcher client | |||
| 139 | + | should send a set_serial request with the serial and seat from the | |||
| 140 | + | wl_pointer.button event. | |||
| 141 | + | ||||
| 142 | + | Some compositors might refuse to activate toplevels when the token | |||
| 143 | + | doesn't have a valid and recent enough event serial. | |||
| 144 | + | ||||
| 145 | + | Must be sent before commit. This information is optional. | |||
| 146 | + | </description> | |||
| 147 | + | <arg name="serial" type="uint" | |||
| 148 | + | summary="the serial of the event that triggered the activation"/> | |||
| 149 | + | <arg name="seat" type="object" interface="wl_seat" | |||
| 150 | + | summary="the wl_seat of the event"/> | |||
| 151 | + | </request> | |||
| 152 | + | ||||
| 153 | + | <request name="set_app_id"> | |||
| 154 | + | <description summary="specifies the application being activated"> | |||
| 155 | + | The requesting client can specify an app_id to associate the token | |||
| 156 | + | being created with it. | |||
| 157 | + | ||||
| 158 | + | Must be sent before commit. This information is optional. | |||
| 159 | + | </description> | |||
| 160 | + | <arg name="app_id" type="string" | |||
| 161 | + | summary="the application id of the client being activated."/> | |||
| 162 | + | </request> | |||
| 163 | + | ||||
| 164 | + | <request name="set_surface"> | |||
| 165 | + | <description summary="specifies the surface requesting activation"> | |||
| 166 | + | This request sets the surface requesting the activation. Note, this is | |||
| 167 | + | different from the surface that will be activated. | |||
| 168 | + | ||||
| 169 | + | Some compositors might refuse to activate toplevels when the token | |||
| 170 | + | doesn't have a requesting surface. | |||
| 171 | + | ||||
| 172 | + | Must be sent before commit. This information is optional. | |||
| 173 | + | </description> | |||
| 174 | + | <arg name="surface" type="object" interface="wl_surface" | |||
| 175 | + | summary="the requesting surface"/> | |||
| 176 | + | </request> | |||
| 177 | + | ||||
| 178 | + | <request name="commit"> | |||
| 179 | + | <description summary="issues the token request"> | |||
| 180 | + | Requests an activation token based on the different parameters that | |||
| 181 | + | have been offered through set_serial, set_surface and set_app_id. | |||
| 182 | + | </description> | |||
| 183 | + | </request> | |||
| 184 | + | ||||
| 185 | + | <event name="done"> | |||
| 186 | + | <description summary="the exported activation token"> | |||
| 187 | + | The 'done' event contains the unique token of this activation request | |||
| 188 | + | and notifies that the provider is done. | |||
| 189 | + | </description> | |||
| 190 | + | <arg name="token" type="string" summary="the exported activation token"/> | |||
| 191 | + | </event> | |||
| 192 | + | ||||
| 193 | + | <request name="destroy" type="destructor"> | |||
| 194 | + | <description summary="destroy the xdg_activation_token_v1 object"> | |||
| 195 | + | Notify the compositor that the xdg_activation_token_v1 object will no | |||
| 196 | + | longer be used. The received token stays valid. | |||
| 197 | + | </description> | |||
| 198 | + | </request> | |||
| 199 | + | </interface> | |||
| 200 | + | </protocol> | |||
A spec/xml/xdgdecoration.xml +176 -0
| @@ -0,0 +1,176 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="xdg_decoration_unstable_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2018 Simon Ser | |||
| 5 | + | ||||
| 6 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 7 | + | copy of this software and associated documentation files (the "Software"), | |||
| 8 | + | to deal in the Software without restriction, including without limitation | |||
| 9 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 10 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 11 | + | Software is furnished to do so, subject to the following conditions: | |||
| 12 | + | ||||
| 13 | + | The above copyright notice and this permission notice (including the next | |||
| 14 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 15 | + | Software. | |||
| 16 | + | ||||
| 17 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 18 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 19 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 20 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 21 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 22 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 23 | + | DEALINGS IN THE SOFTWARE. | |||
| 24 | + | </copyright> | |||
| 25 | + | ||||
| 26 | + | <interface name="zxdg_decoration_manager_v1" version="2"> | |||
| 27 | + | <description summary="window decoration manager"> | |||
| 28 | + | This interface allows a compositor to announce support for server-side | |||
| 29 | + | decorations. | |||
| 30 | + | ||||
| 31 | + | A window decoration is a set of window controls as deemed appropriate by | |||
| 32 | + | the party managing them, such as user interface components used to move, | |||
| 33 | + | resize and change a window's state. | |||
| 34 | + | ||||
| 35 | + | A client can use this protocol to request being decorated by a supporting | |||
| 36 | + | compositor. | |||
| 37 | + | ||||
| 38 | + | If compositor and client do not negotiate the use of a server-side | |||
| 39 | + | decoration using this protocol, clients continue to self-decorate as they | |||
| 40 | + | see fit. | |||
| 41 | + | ||||
| 42 | + | Warning! The protocol described in this file is experimental and | |||
| 43 | + | backward incompatible changes may be made. Backward compatible changes | |||
| 44 | + | may be added together with the corresponding interface version bump. | |||
| 45 | + | Backward incompatible changes are done by bumping the version number in | |||
| 46 | + | the protocol and interface names and resetting the interface version. | |||
| 47 | + | Once the protocol is to be declared stable, the 'z' prefix and the | |||
| 48 | + | version number in the protocol and interface names are removed and the | |||
| 49 | + | interface version number is reset. | |||
| 50 | + | </description> | |||
| 51 | + | ||||
| 52 | + | <request name="destroy" type="destructor"> | |||
| 53 | + | <description summary="destroy the decoration manager object"> | |||
| 54 | + | Destroy the decoration manager. This doesn't destroy objects created | |||
| 55 | + | with the manager. | |||
| 56 | + | </description> | |||
| 57 | + | </request> | |||
| 58 | + | ||||
| 59 | + | <request name="get_toplevel_decoration"> | |||
| 60 | + | <description summary="create a new toplevel decoration object"> | |||
| 61 | + | Create a new decoration object associated with the given toplevel. | |||
| 62 | + | ||||
| 63 | + | For objects of version 1, creating an xdg_toplevel_decoration from an | |||
| 64 | + | xdg_toplevel which has a buffer attached or committed is a client | |||
| 65 | + | error, and any attempts by a client to attach or manipulate a buffer | |||
| 66 | + | prior to the first xdg_toplevel_decoration.configure event must also be | |||
| 67 | + | treated as errors. | |||
| 68 | + | ||||
| 69 | + | For objects of version 2 or newer, creating an xdg_toplevel_decoration | |||
| 70 | + | from an xdg_toplevel which has a buffer attached or committed is | |||
| 71 | + | allowed. The initial decoration mode of the surface if a buffer is | |||
| 72 | + | already attached depends on whether a xdg_toplevel_decoration object | |||
| 73 | + | has been associated with the surface or not prior to this request. | |||
| 74 | + | ||||
| 75 | + | If an xdg_toplevel_decoration was associated with the surface, then | |||
| 76 | + | destroyed without a surface commit, the previous decoration mode is | |||
| 77 | + | retained. | |||
| 78 | + | ||||
| 79 | + | If no xdg_toplevel_decoration was associated with the surface prior to | |||
| 80 | + | this request, or if a surface commit has been performed after a previous | |||
| 81 | + | xdg_toplevel_decoration object associated with the surface was | |||
| 82 | + | destroyed, the decoration mode is assumed to be client-side. | |||
| 83 | + | </description> | |||
| 84 | + | <arg name="id" type="new_id" interface="zxdg_toplevel_decoration_v1"/> | |||
| 85 | + | <arg name="toplevel" type="object" interface="xdg_toplevel"/> | |||
| 86 | + | </request> | |||
| 87 | + | </interface> | |||
| 88 | + | ||||
| 89 | + | <interface name="zxdg_toplevel_decoration_v1" version="2"> | |||
| 90 | + | <description summary="decoration object for a toplevel surface"> | |||
| 91 | + | The decoration object allows the compositor to toggle server-side window | |||
| 92 | + | decorations for a toplevel surface. The client can request to switch to | |||
| 93 | + | another mode. | |||
| 94 | + | ||||
| 95 | + | The xdg_toplevel_decoration object must be destroyed before its | |||
| 96 | + | xdg_toplevel. | |||
| 97 | + | </description> | |||
| 98 | + | ||||
| 99 | + | <enum name="error"> | |||
| 100 | + | <entry name="unconfigured_buffer" value="0" | |||
| 101 | + | summary="xdg_toplevel has a buffer attached before configure"/> | |||
| 102 | + | <entry name="already_constructed" value="1" | |||
| 103 | + | summary="xdg_toplevel already has a decoration object"/> | |||
| 104 | + | <entry name="orphaned" value="2" | |||
| 105 | + | summary="xdg_toplevel destroyed before the decoration object"/> | |||
| 106 | + | <entry name="invalid_mode" value="3" summary="invalid mode"/> | |||
| 107 | + | </enum> | |||
| 108 | + | ||||
| 109 | + | <request name="destroy" type="destructor"> | |||
| 110 | + | <description summary="destroy the decoration object"> | |||
| 111 | + | Switch back to a mode without any server-side decorations at the next | |||
| 112 | + | commit, unless a new xdg_toplevel_decoration is created for the surface | |||
| 113 | + | first. | |||
| 114 | + | </description> | |||
| 115 | + | </request> | |||
| 116 | + | ||||
| 117 | + | <enum name="mode"> | |||
| 118 | + | <description summary="window decoration modes"> | |||
| 119 | + | These values describe window decoration modes. | |||
| 120 | + | </description> | |||
| 121 | + | <entry name="client_side" value="1" | |||
| 122 | + | summary="no server-side window decoration"/> | |||
| 123 | + | <entry name="server_side" value="2" | |||
| 124 | + | summary="server-side window decoration"/> | |||
| 125 | + | </enum> | |||
| 126 | + | ||||
| 127 | + | <request name="set_mode"> | |||
| 128 | + | <description summary="set the decoration mode"> | |||
| 129 | + | Set the toplevel surface decoration mode. This informs the compositor | |||
| 130 | + | that the client prefers the provided decoration mode. | |||
| 131 | + | ||||
| 132 | + | After requesting a decoration mode, the compositor will respond by | |||
| 133 | + | emitting an xdg_surface.configure event. The client should then update | |||
| 134 | + | its content, drawing it without decorations if the received mode is | |||
| 135 | + | server-side decorations. The client must also acknowledge the configure | |||
| 136 | + | when committing the new content (see xdg_surface.ack_configure). | |||
| 137 | + | ||||
| 138 | + | The compositor can decide not to use the client's mode and enforce a | |||
| 139 | + | different mode instead. | |||
| 140 | + | ||||
| 141 | + | Clients whose decoration mode depend on the xdg_toplevel state may send | |||
| 142 | + | a set_mode request in response to an xdg_surface.configure event and wait | |||
| 143 | + | for the next xdg_surface.configure event to prevent unwanted state. | |||
| 144 | + | Such clients are responsible for preventing configure loops and must | |||
| 145 | + | make sure not to send multiple successive set_mode requests with the | |||
| 146 | + | same decoration mode. | |||
| 147 | + | ||||
| 148 | + | If an invalid mode is supplied by the client, the invalid_mode protocol | |||
| 149 | + | error is raised by the compositor. | |||
| 150 | + | </description> | |||
| 151 | + | <arg name="mode" type="uint" enum="mode" summary="the decoration mode"/> | |||
| 152 | + | </request> | |||
| 153 | + | ||||
| 154 | + | <request name="unset_mode"> | |||
| 155 | + | <description summary="unset the decoration mode"> | |||
| 156 | + | Unset the toplevel surface decoration mode. This informs the compositor | |||
| 157 | + | that the client doesn't prefer a particular decoration mode. | |||
| 158 | + | ||||
| 159 | + | This request has the same semantics as set_mode. | |||
| 160 | + | </description> | |||
| 161 | + | </request> | |||
| 162 | + | ||||
| 163 | + | <event name="configure"> | |||
| 164 | + | <description summary="notify a decoration mode change"> | |||
| 165 | + | The configure event configures the effective decoration mode. The | |||
| 166 | + | configured state should not be applied immediately. Clients must send an | |||
| 167 | + | ack_configure in response to this event. See xdg_surface.configure and | |||
| 168 | + | xdg_surface.ack_configure for details. | |||
| 169 | + | ||||
| 170 | + | A configure event can be sent at any time. The specified mode must be | |||
| 171 | + | obeyed by the client. | |||
| 172 | + | </description> | |||
| 173 | + | <arg name="mode" type="uint" enum="mode" summary="the decoration mode"/> | |||
| 174 | + | </event> | |||
| 175 | + | </interface> | |||
| 176 | + | </protocol> | |||
A spec/xml/xdgdialog.xml +110 -0
| @@ -0,0 +1,110 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="xdg_dialog_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2023 Carlos Garnacho | |||
| 5 | + | ||||
| 6 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 7 | + | copy of this software and associated documentation files (the "Software"), | |||
| 8 | + | to deal in the Software without restriction, including without limitation | |||
| 9 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 10 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 11 | + | Software is furnished to do so, subject to the following conditions: | |||
| 12 | + | ||||
| 13 | + | The above copyright notice and this permission notice (including the next | |||
| 14 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 15 | + | Software. | |||
| 16 | + | ||||
| 17 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 18 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 19 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 20 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 21 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 22 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 23 | + | DEALINGS IN THE SOFTWARE. | |||
| 24 | + | </copyright> | |||
| 25 | + | ||||
| 26 | + | <interface name="xdg_wm_dialog_v1" version="1"> | |||
| 27 | + | <description summary="create dialogs related to other toplevels"> | |||
| 28 | + | The xdg_wm_dialog_v1 interface is exposed as a global object allowing | |||
| 29 | + | to register surfaces with a xdg_toplevel role as "dialogs" relative to | |||
| 30 | + | another toplevel. | |||
| 31 | + | ||||
| 32 | + | The compositor may let this relation influence how the surface is | |||
| 33 | + | placed, displayed or interacted with. | |||
| 34 | + | ||||
| 35 | + | Warning! The protocol described in this file is currently in the testing | |||
| 36 | + | phase. Backward compatible changes may be added together with the | |||
| 37 | + | corresponding interface version bump. Backward incompatible changes can | |||
| 38 | + | only be done by creating a new major version of the extension. | |||
| 39 | + | </description> | |||
| 40 | + | ||||
| 41 | + | <enum name="error"> | |||
| 42 | + | <entry name="already_used" value="0" | |||
| 43 | + | summary="the xdg_toplevel object has already been used to create a xdg_dialog_v1"/> | |||
| 44 | + | </enum> | |||
| 45 | + | ||||
| 46 | + | <request name="destroy" type="destructor"> | |||
| 47 | + | <description summary="destroy the dialog manager object"> | |||
| 48 | + | Destroys the xdg_wm_dialog_v1 object. This does not affect | |||
| 49 | + | the xdg_dialog_v1 objects generated through it. | |||
| 50 | + | </description> | |||
| 51 | + | </request> | |||
| 52 | + | ||||
| 53 | + | <request name="get_xdg_dialog"> | |||
| 54 | + | <description summary="create a dialog object"> | |||
| 55 | + | Creates a xdg_dialog_v1 object for the given toplevel. See the interface | |||
| 56 | + | description for more details. | |||
| 57 | + | ||||
| 58 | + | Compositors must raise an already_used error if clients attempt to | |||
| 59 | + | create multiple xdg_dialog_v1 objects for the same xdg_toplevel. | |||
| 60 | + | </description> | |||
| 61 | + | <arg name="id" type="new_id" interface="xdg_dialog_v1"/> | |||
| 62 | + | <arg name="toplevel" type="object" interface="xdg_toplevel"/> | |||
| 63 | + | </request> | |||
| 64 | + | </interface> | |||
| 65 | + | ||||
| 66 | + | <interface name="xdg_dialog_v1" version="1"> | |||
| 67 | + | <description summary="dialog object"> | |||
| 68 | + | A xdg_dialog_v1 object is an ancillary object tied to a xdg_toplevel. Its | |||
| 69 | + | purpose is hinting the compositor that the toplevel is a "dialog" (e.g. a | |||
| 70 | + | temporary window) relative to another toplevel (see | |||
| 71 | + | xdg_toplevel.set_parent). If the xdg_toplevel is destroyed, the xdg_dialog_v1 | |||
| 72 | + | becomes inert. | |||
| 73 | + | ||||
| 74 | + | Through this object, the client may provide additional hints about | |||
| 75 | + | the purpose of the secondary toplevel. This interface has no effect | |||
| 76 | + | on toplevels that are not attached to a parent toplevel. | |||
| 77 | + | </description> | |||
| 78 | + | ||||
| 79 | + | <request name="destroy" type="destructor"> | |||
| 80 | + | <description summary="destroy the dialog object"> | |||
| 81 | + | Destroys the xdg_dialog_v1 object. If this object is destroyed | |||
| 82 | + | before the related xdg_toplevel, the compositor should unapply its | |||
| 83 | + | effects. | |||
| 84 | + | </description> | |||
| 85 | + | </request> | |||
| 86 | + | ||||
| 87 | + | <request name="set_modal"> | |||
| 88 | + | <description summary="mark dialog as modal"> | |||
| 89 | + | Hints that the dialog has "modal" behavior. Modal dialogs typically | |||
| 90 | + | require to be fully addressed by the user (i.e. closed) before resuming | |||
| 91 | + | interaction with the parent toplevel, and may require a distinct | |||
| 92 | + | presentation. | |||
| 93 | + | ||||
| 94 | + | Clients must implement the logic to filter events in the parent | |||
| 95 | + | toplevel on their own. | |||
| 96 | + | ||||
| 97 | + | Compositors may choose any policy in event delivery to the parent | |||
| 98 | + | toplevel, from delivering all events unfiltered to using them for | |||
| 99 | + | internal consumption. | |||
| 100 | + | </description> | |||
| 101 | + | </request> | |||
| 102 | + | ||||
| 103 | + | <request name="unset_modal"> | |||
| 104 | + | <description summary="mark dialog as not modal"> | |||
| 105 | + | Drops the hint that this dialog has "modal" behavior. See | |||
| 106 | + | xdg_dialog_v1.set_modal for more details. | |||
| 107 | + | </description> | |||
| 108 | + | </request> | |||
| 109 | + | </interface> | |||
| 110 | + | </protocol> | |||
A spec/xml/xdgforeign.xml +200 -0
| @@ -0,0 +1,200 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="xdg_foreign_unstable_v2"> | |||
| 3 | + | ||||
| 4 | + | <copyright> | |||
| 5 | + | Copyright © 2015-2016 Red Hat Inc. | |||
| 6 | + | ||||
| 7 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 8 | + | copy of this software and associated documentation files (the "Software"), | |||
| 9 | + | to deal in the Software without restriction, including without limitation | |||
| 10 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 11 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 12 | + | Software is furnished to do so, subject to the following conditions: | |||
| 13 | + | ||||
| 14 | + | The above copyright notice and this permission notice (including the next | |||
| 15 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 16 | + | Software. | |||
| 17 | + | ||||
| 18 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 19 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 20 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 21 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 22 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 23 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 24 | + | DEALINGS IN THE SOFTWARE. | |||
| 25 | + | </copyright> | |||
| 26 | + | ||||
| 27 | + | <description summary="Protocol for exporting xdg surface handles"> | |||
| 28 | + | This protocol specifies a way for making it possible to reference a surface | |||
| 29 | + | of a different client. With such a reference, a client can, by using the | |||
| 30 | + | interfaces provided by this protocol, manipulate the relationship between | |||
| 31 | + | its own surfaces and the surface of some other client. For example, stack | |||
| 32 | + | some of its own surface above the other clients surface. | |||
| 33 | + | ||||
| 34 | + | In order for a client A to get a reference of a surface of client B, client | |||
| 35 | + | B must first export its surface using xdg_exporter.export_toplevel. Upon | |||
| 36 | + | doing this, client B will receive a handle (a unique string) that it may | |||
| 37 | + | share with client A in some way (for example D-Bus). After client A has | |||
| 38 | + | received the handle from client B, it may use xdg_importer.import_toplevel | |||
| 39 | + | to create a reference to the surface client B just exported. See the | |||
| 40 | + | corresponding requests for details. | |||
| 41 | + | ||||
| 42 | + | A possible use case for this is out-of-process dialogs. For example when a | |||
| 43 | + | sandboxed client without file system access needs the user to select a file | |||
| 44 | + | on the file system, given sandbox environment support, it can export its | |||
| 45 | + | surface, passing the exported surface handle to an unsandboxed process that | |||
| 46 | + | can show a file browser dialog and stack it above the sandboxed client's | |||
| 47 | + | surface. | |||
| 48 | + | ||||
| 49 | + | Warning! The protocol described in this file is experimental and backward | |||
| 50 | + | incompatible changes may be made. Backward compatible changes may be added | |||
| 51 | + | together with the corresponding interface version bump. Backward | |||
| 52 | + | incompatible changes are done by bumping the version number in the protocol | |||
| 53 | + | and interface names and resetting the interface version. Once the protocol | |||
| 54 | + | is to be declared stable, the 'z' prefix and the version number in the | |||
| 55 | + | protocol and interface names are removed and the interface version number is | |||
| 56 | + | reset. | |||
| 57 | + | </description> | |||
| 58 | + | ||||
| 59 | + | <interface name="zxdg_exporter_v2" version="1"> | |||
| 60 | + | <description summary="interface for exporting surfaces"> | |||
| 61 | + | A global interface used for exporting surfaces that can later be imported | |||
| 62 | + | using xdg_importer. | |||
| 63 | + | </description> | |||
| 64 | + | ||||
| 65 | + | <request name="destroy" type="destructor"> | |||
| 66 | + | <description summary="destroy the xdg_exporter object"> | |||
| 67 | + | Notify the compositor that the xdg_exporter object will no longer be | |||
| 68 | + | used. | |||
| 69 | + | </description> | |||
| 70 | + | </request> | |||
| 71 | + | ||||
| 72 | + | <enum name="error"> | |||
| 73 | + | <description summary="error values"> | |||
| 74 | + | These errors can be emitted in response to invalid xdg_exporter | |||
| 75 | + | requests. | |||
| 76 | + | </description> | |||
| 77 | + | <entry name="invalid_surface" value="0" summary="surface is not an xdg_toplevel"/> | |||
| 78 | + | </enum> | |||
| 79 | + | ||||
| 80 | + | <request name="export_toplevel"> | |||
| 81 | + | <description summary="export a toplevel surface"> | |||
| 82 | + | The export_toplevel request exports the passed surface so that it can later be | |||
| 83 | + | imported via xdg_importer. When called, a new xdg_exported object will | |||
| 84 | + | be created and xdg_exported.handle will be sent immediately. See the | |||
| 85 | + | corresponding interface and event for details. | |||
| 86 | + | ||||
| 87 | + | A surface may be exported multiple times, and each exported handle may | |||
| 88 | + | be used to create an xdg_imported multiple times. Only xdg_toplevel | |||
| 89 | + | equivalent surfaces may be exported, otherwise an invalid_surface | |||
| 90 | + | protocol error is sent. | |||
| 91 | + | </description> | |||
| 92 | + | <arg name="id" type="new_id" interface="zxdg_exported_v2" | |||
| 93 | + | summary="the new xdg_exported object"/> | |||
| 94 | + | <arg name="surface" type="object" interface="wl_surface" | |||
| 95 | + | summary="the surface to export"/> | |||
| 96 | + | </request> | |||
| 97 | + | </interface> | |||
| 98 | + | ||||
| 99 | + | <interface name="zxdg_importer_v2" version="1"> | |||
| 100 | + | <description summary="interface for importing surfaces"> | |||
| 101 | + | A global interface used for importing surfaces exported by xdg_exporter. | |||
| 102 | + | With this interface, a client can create a reference to a surface of | |||
| 103 | + | another client. | |||
| 104 | + | </description> | |||
| 105 | + | ||||
| 106 | + | <request name="destroy" type="destructor"> | |||
| 107 | + | <description summary="destroy the xdg_importer object"> | |||
| 108 | + | Notify the compositor that the xdg_importer object will no longer be | |||
| 109 | + | used. | |||
| 110 | + | </description> | |||
| 111 | + | </request> | |||
| 112 | + | ||||
| 113 | + | <request name="import_toplevel"> | |||
| 114 | + | <description summary="import a toplevel surface"> | |||
| 115 | + | The import_toplevel request imports a surface from any client given a handle | |||
| 116 | + | retrieved by exporting said surface using xdg_exporter.export_toplevel. | |||
| 117 | + | When called, a new xdg_imported object will be created. This new object | |||
| 118 | + | represents the imported surface, and the importing client can | |||
| 119 | + | manipulate its relationship using it. See xdg_imported for details. | |||
| 120 | + | </description> | |||
| 121 | + | <arg name="id" type="new_id" interface="zxdg_imported_v2" | |||
| 122 | + | summary="the new xdg_imported object"/> | |||
| 123 | + | <arg name="handle" type="string" | |||
| 124 | + | summary="the exported surface handle"/> | |||
| 125 | + | </request> | |||
| 126 | + | </interface> | |||
| 127 | + | ||||
| 128 | + | <interface name="zxdg_exported_v2" version="1"> | |||
| 129 | + | <description summary="an exported surface handle"> | |||
| 130 | + | An xdg_exported object represents an exported reference to a surface. The | |||
| 131 | + | exported surface may be referenced as long as the xdg_exported object not | |||
| 132 | + | destroyed. Destroying the xdg_exported invalidates any relationship the | |||
| 133 | + | importer may have established using xdg_imported. | |||
| 134 | + | </description> | |||
| 135 | + | ||||
| 136 | + | <request name="destroy" type="destructor"> | |||
| 137 | + | <description summary="unexport the exported surface"> | |||
| 138 | + | Revoke the previously exported surface. This invalidates any | |||
| 139 | + | relationship the importer may have set up using the xdg_imported created | |||
| 140 | + | given the handle sent via xdg_exported.handle. | |||
| 141 | + | </description> | |||
| 142 | + | </request> | |||
| 143 | + | ||||
| 144 | + | <event name="handle"> | |||
| 145 | + | <description summary="the exported surface handle"> | |||
| 146 | + | The handle event contains the unique handle of this exported surface | |||
| 147 | + | reference. It may be shared with any client, which then can use it to | |||
| 148 | + | import the surface by calling xdg_importer.import_toplevel. A handle | |||
| 149 | + | may be used to import the surface multiple times. | |||
| 150 | + | </description> | |||
| 151 | + | <arg name="handle" type="string" summary="the exported surface handle"/> | |||
| 152 | + | </event> | |||
| 153 | + | </interface> | |||
| 154 | + | ||||
| 155 | + | <interface name="zxdg_imported_v2" version="1"> | |||
| 156 | + | <description summary="an imported surface handle"> | |||
| 157 | + | An xdg_imported object represents an imported reference to surface exported | |||
| 158 | + | by some client. A client can use this interface to manipulate | |||
| 159 | + | relationships between its own surfaces and the imported surface. | |||
| 160 | + | </description> | |||
| 161 | + | ||||
| 162 | + | <enum name="error"> | |||
| 163 | + | <description summary="error values"> | |||
| 164 | + | These errors can be emitted in response to invalid xdg_imported | |||
| 165 | + | requests. | |||
| 166 | + | </description> | |||
| 167 | + | <entry name="invalid_surface" value="0" summary="surface is not an xdg_toplevel"/> | |||
| 168 | + | </enum> | |||
| 169 | + | ||||
| 170 | + | <request name="destroy" type="destructor"> | |||
| 171 | + | <description summary="destroy the xdg_imported object"> | |||
| 172 | + | Notify the compositor that it will no longer use the xdg_imported | |||
| 173 | + | object. Any relationship that may have been set up will at this point | |||
| 174 | + | be invalidated. | |||
| 175 | + | </description> | |||
| 176 | + | </request> | |||
| 177 | + | ||||
| 178 | + | <request name="set_parent_of"> | |||
| 179 | + | <description summary="set as the parent of some surface"> | |||
| 180 | + | Set the imported surface as the parent of some surface of the client. | |||
| 181 | + | The passed surface must be an xdg_toplevel equivalent, otherwise an | |||
| 182 | + | invalid_surface protocol error is sent. Calling this function sets up | |||
| 183 | + | a surface to surface relation with the same stacking and positioning | |||
| 184 | + | semantics as xdg_toplevel.set_parent. | |||
| 185 | + | </description> | |||
| 186 | + | <arg name="surface" type="object" interface="wl_surface" | |||
| 187 | + | summary="the child surface"/> | |||
| 188 | + | </request> | |||
| 189 | + | ||||
| 190 | + | <event name="destroyed"> | |||
| 191 | + | <description summary="the imported surface handle has been destroyed"> | |||
| 192 | + | The imported surface handle has been destroyed and any relationship set | |||
| 193 | + | up has been invalidated. This may happen for various reasons, for | |||
| 194 | + | example if the exported surface or the exported surface handle has been | |||
| 195 | + | destroyed, if the handle used for importing was invalid. | |||
| 196 | + | </description> | |||
| 197 | + | </event> | |||
| 198 | + | </interface> | |||
| 199 | + | ||||
| 200 | + | </protocol> | |||
A spec/xml/xdgoutput.xml +222 -0
| @@ -0,0 +1,222 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="xdg_output_unstable_v1"> | |||
| 3 | + | ||||
| 4 | + | <copyright> | |||
| 5 | + | Copyright © 2017 Red Hat Inc. | |||
| 6 | + | ||||
| 7 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 8 | + | copy of this software and associated documentation files (the "Software"), | |||
| 9 | + | to deal in the Software without restriction, including without limitation | |||
| 10 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 11 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 12 | + | Software is furnished to do so, subject to the following conditions: | |||
| 13 | + | ||||
| 14 | + | The above copyright notice and this permission notice (including the next | |||
| 15 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 16 | + | Software. | |||
| 17 | + | ||||
| 18 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 19 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 20 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 21 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 22 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 23 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 24 | + | DEALINGS IN THE SOFTWARE. | |||
| 25 | + | </copyright> | |||
| 26 | + | ||||
| 27 | + | <description summary="Protocol to describe output regions"> | |||
| 28 | + | This protocol aims at describing outputs in a way which is more in line | |||
| 29 | + | with the concept of an output on desktop oriented systems. | |||
| 30 | + | ||||
| 31 | + | Some information are more specific to the concept of an output for | |||
| 32 | + | a desktop oriented system and may not make sense in other applications, | |||
| 33 | + | such as IVI systems for example. | |||
| 34 | + | ||||
| 35 | + | Typically, the global compositor space on a desktop system is made of | |||
| 36 | + | a contiguous or overlapping set of rectangular regions. | |||
| 37 | + | ||||
| 38 | + | The logical_position and logical_size events defined in this protocol | |||
| 39 | + | might provide information identical to their counterparts already | |||
| 40 | + | available from wl_output, in which case the information provided by this | |||
| 41 | + | protocol should be preferred to their equivalent in wl_output. The goal is | |||
| 42 | + | to move the desktop specific concepts (such as output location within the | |||
| 43 | + | global compositor space, etc.) out of the core wl_output protocol. | |||
| 44 | + | ||||
| 45 | + | Warning! The protocol described in this file is experimental and | |||
| 46 | + | backward incompatible changes may be made. Backward compatible | |||
| 47 | + | changes may be added together with the corresponding interface | |||
| 48 | + | version bump. | |||
| 49 | + | Backward incompatible changes are done by bumping the version | |||
| 50 | + | number in the protocol and interface names and resetting the | |||
| 51 | + | interface version. Once the protocol is to be declared stable, | |||
| 52 | + | the 'z' prefix and the version number in the protocol and | |||
| 53 | + | interface names are removed and the interface version number is | |||
| 54 | + | reset. | |||
| 55 | + | </description> | |||
| 56 | + | ||||
| 57 | + | <interface name="zxdg_output_manager_v1" version="3"> | |||
| 58 | + | <description summary="manage xdg_output objects"> | |||
| 59 | + | A global factory interface for xdg_output objects. | |||
| 60 | + | </description> | |||
| 61 | + | ||||
| 62 | + | <request name="destroy" type="destructor"> | |||
| 63 | + | <description summary="destroy the xdg_output_manager object"> | |||
| 64 | + | Using this request a client can tell the server that it is not | |||
| 65 | + | going to use the xdg_output_manager object anymore. | |||
| 66 | + | ||||
| 67 | + | Any objects already created through this instance are not affected. | |||
| 68 | + | </description> | |||
| 69 | + | </request> | |||
| 70 | + | ||||
| 71 | + | <request name="get_xdg_output"> | |||
| 72 | + | <description summary="create an xdg output from a wl_output"> | |||
| 73 | + | This creates a new xdg_output object for the given wl_output. | |||
| 74 | + | </description> | |||
| 75 | + | <arg name="id" type="new_id" interface="zxdg_output_v1"/> | |||
| 76 | + | <arg name="output" type="object" interface="wl_output"/> | |||
| 77 | + | </request> | |||
| 78 | + | </interface> | |||
| 79 | + | ||||
| 80 | + | <interface name="zxdg_output_v1" version="3"> | |||
| 81 | + | <description summary="compositor logical output region"> | |||
| 82 | + | An xdg_output describes part of the compositor geometry. | |||
| 83 | + | ||||
| 84 | + | This typically corresponds to a monitor that displays part of the | |||
| 85 | + | compositor space. | |||
| 86 | + | ||||
| 87 | + | For objects version 3 onwards, after all xdg_output properties have been | |||
| 88 | + | sent (when the object is created and when properties are updated), a | |||
| 89 | + | wl_output.done event is sent. This allows changes to the output | |||
| 90 | + | properties to be seen as atomic, even if they happen via multiple events. | |||
| 91 | + | </description> | |||
| 92 | + | ||||
| 93 | + | <request name="destroy" type="destructor"> | |||
| 94 | + | <description summary="destroy the xdg_output object"> | |||
| 95 | + | Using this request a client can tell the server that it is not | |||
| 96 | + | going to use the xdg_output object anymore. | |||
| 97 | + | </description> | |||
| 98 | + | </request> | |||
| 99 | + | ||||
| 100 | + | <event name="logical_position"> | |||
| 101 | + | <description summary="position of the output within the global compositor space"> | |||
| 102 | + | The position event describes the location of the wl_output within | |||
| 103 | + | the global compositor space. | |||
| 104 | + | ||||
| 105 | + | The logical_position event is sent after creating an xdg_output | |||
| 106 | + | (see xdg_output_manager.get_xdg_output) and whenever the location | |||
| 107 | + | of the output changes within the global compositor space. | |||
| 108 | + | </description> | |||
| 109 | + | <arg name="x" type="int" | |||
| 110 | + | summary="x position within the global compositor space"/> | |||
| 111 | + | <arg name="y" type="int" | |||
| 112 | + | summary="y position within the global compositor space"/> | |||
| 113 | + | </event> | |||
| 114 | + | ||||
| 115 | + | <event name="logical_size"> | |||
| 116 | + | <description summary="size of the output in the global compositor space"> | |||
| 117 | + | The logical_size event describes the size of the output in the | |||
| 118 | + | global compositor space. | |||
| 119 | + | ||||
| 120 | + | Most regular Wayland clients should not pay attention to the | |||
| 121 | + | logical size and would rather rely on xdg_shell interfaces. | |||
| 122 | + | ||||
| 123 | + | Some clients such as Xwayland, however, need this to configure | |||
| 124 | + | their surfaces in the global compositor space as the compositor | |||
| 125 | + | may apply a different scale from what is advertised by the output | |||
| 126 | + | scaling property (to achieve fractional scaling, for example). | |||
| 127 | + | ||||
| 128 | + | For example, for a wl_output mode 3840×2160 and a scale factor 2: | |||
| 129 | + | ||||
| 130 | + | - A compositor not scaling the monitor viewport in its compositing space | |||
| 131 | + | will advertise a logical size of 3840×2160, | |||
| 132 | + | ||||
| 133 | + | - A compositor scaling the monitor viewport with scale factor 2 will | |||
| 134 | + | advertise a logical size of 1920×1080, | |||
| 135 | + | ||||
| 136 | + | - A compositor scaling the monitor viewport using a fractional scale of | |||
| 137 | + | 1.5 will advertise a logical size of 2560×1440. | |||
| 138 | + | ||||
| 139 | + | For example, for a wl_output mode 1920×1080 and a 90 degree rotation, | |||
| 140 | + | the compositor will advertise a logical size of 1080x1920. | |||
| 141 | + | ||||
| 142 | + | The logical_size event is sent after creating an xdg_output | |||
| 143 | + | (see xdg_output_manager.get_xdg_output) and whenever the logical | |||
| 144 | + | size of the output changes, either as a result of a change in the | |||
| 145 | + | applied scale or because of a change in the corresponding output | |||
| 146 | + | mode(see wl_output.mode) or transform (see wl_output.transform). | |||
| 147 | + | </description> | |||
| 148 | + | <arg name="width" type="int" | |||
| 149 | + | summary="width in global compositor space"/> | |||
| 150 | + | <arg name="height" type="int" | |||
| 151 | + | summary="height in global compositor space"/> | |||
| 152 | + | </event> | |||
| 153 | + | ||||
| 154 | + | <event name="done" deprecated-since="3"> | |||
| 155 | + | <description summary="all information about the output have been sent"> | |||
| 156 | + | This event is sent after all other properties of an xdg_output | |||
| 157 | + | have been sent. | |||
| 158 | + | ||||
| 159 | + | This allows changes to the xdg_output properties to be seen as | |||
| 160 | + | atomic, even if they happen via multiple events. | |||
| 161 | + | ||||
| 162 | + | For objects version 3 onwards, this event is deprecated. Compositors | |||
| 163 | + | are not required to send it anymore and must send wl_output.done | |||
| 164 | + | instead. | |||
| 165 | + | </description> | |||
| 166 | + | </event> | |||
| 167 | + | ||||
| 168 | + | <!-- Version 2 additions --> | |||
| 169 | + | ||||
| 170 | + | <event name="name" since="2"> | |||
| 171 | + | <description summary="name of this output"> | |||
| 172 | + | Many compositors will assign names to their outputs, show them to the | |||
| 173 | + | user, allow them to be configured by name, etc. The client may wish to | |||
| 174 | + | know this name as well to offer the user similar behaviors. | |||
| 175 | + | ||||
| 176 | + | The naming convention is compositor defined, but limited to | |||
| 177 | + | alphanumeric characters and dashes (-). Each name is unique among all | |||
| 178 | + | wl_output globals, but if a wl_output global is destroyed the same name | |||
| 179 | + | may be reused later. The names will also remain consistent across | |||
| 180 | + | sessions with the same hardware and software configuration. | |||
| 181 | + | ||||
| 182 | + | Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc. However, do | |||
| 183 | + | not assume that the name is a reflection of an underlying DRM | |||
| 184 | + | connector, X11 connection, etc. | |||
| 185 | + | ||||
| 186 | + | The name event is sent after creating an xdg_output (see | |||
| 187 | + | xdg_output_manager.get_xdg_output). This event is only sent once per | |||
| 188 | + | xdg_output, and the name does not change over the lifetime of the | |||
| 189 | + | wl_output global. | |||
| 190 | + | ||||
| 191 | + | This event is deprecated, instead clients should use wl_output.name. | |||
| 192 | + | Compositors must still support this event. | |||
| 193 | + | </description> | |||
| 194 | + | <arg name="name" type="string" summary="output name"/> | |||
| 195 | + | </event> | |||
| 196 | + | ||||
| 197 | + | <event name="description" since="2"> | |||
| 198 | + | <description summary="human-readable description of this output"> | |||
| 199 | + | Many compositors can produce human-readable descriptions of their | |||
| 200 | + | outputs. The client may wish to know this description as well, to | |||
| 201 | + | communicate the user for various purposes. | |||
| 202 | + | ||||
| 203 | + | The description is a UTF-8 string with no convention defined for its | |||
| 204 | + | contents. Examples might include 'Foocorp 11" Display' or 'Virtual X11 | |||
| 205 | + | output via :1'. | |||
| 206 | + | ||||
| 207 | + | The description event is sent after creating an xdg_output (see | |||
| 208 | + | xdg_output_manager.get_xdg_output) and whenever the description | |||
| 209 | + | changes. The description is optional, and may not be sent at all. | |||
| 210 | + | ||||
| 211 | + | For objects of version 2 and lower, this event is only sent once per | |||
| 212 | + | xdg_output, and the description does not change over the lifetime of | |||
| 213 | + | the wl_output global. | |||
| 214 | + | ||||
| 215 | + | This event is deprecated, instead clients should use | |||
| 216 | + | wl_output.description. Compositors must still support this event. | |||
| 217 | + | </description> | |||
| 218 | + | <arg name="description" type="string" summary="output description"/> | |||
| 219 | + | </event> | |||
| 220 | + | ||||
| 221 | + | </interface> | |||
| 222 | + | </protocol> | |||
A spec/xml/xdgsessionmanagement.xml +333 -0
| @@ -0,0 +1,333 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="xdg_session_management_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright 2018 Mike Blumenkrantz | |||
| 5 | + | Copyright 2018 Samsung Electronics Co., Ltd | |||
| 6 | + | Copyright 2018 Red Hat Inc. | |||
| 7 | + | ||||
| 8 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 9 | + | copy of this software and associated documentation files (the "Software"), | |||
| 10 | + | to deal in the Software without restriction, including without limitation | |||
| 11 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 12 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 13 | + | Software is furnished to do so, subject to the following conditions: | |||
| 14 | + | ||||
| 15 | + | The above copyright notice and this permission notice (including the next | |||
| 16 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 17 | + | Software. | |||
| 18 | + | ||||
| 19 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 20 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 21 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 22 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 23 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 24 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 25 | + | DEALINGS IN THE SOFTWARE. | |||
| 26 | + | </copyright> | |||
| 27 | + | ||||
| 28 | + | <description summary="Protocol for managing application sessions"> | |||
| 29 | + | This description provides a high-level overview of the interplay between | |||
| 30 | + | the interfaces defined this protocol. For details, see the protocol | |||
| 31 | + | specification. | |||
| 32 | + | ||||
| 33 | + | The xdg_session_manager protocol declares interfaces necessary to | |||
| 34 | + | allow clients to restore toplevel state from previous executions. The | |||
| 35 | + | xdg_session_manager_v1.get_session request can be used to obtain a | |||
| 36 | + | xdg_session_v1 resource representing the state of a set of toplevels. | |||
| 37 | + | ||||
| 38 | + | Clients may obtain the session string to use in future calls through | |||
| 39 | + | the xdg_session_v1.created event. Compositors will use this string | |||
| 40 | + | as an identifiable token for future runs, possibly storing data about | |||
| 41 | + | the related toplevels in persistent storage. Clients that wish to | |||
| 42 | + | track sessions in multiple environments may use the $XDG_CURRENT_DESKTOP | |||
| 43 | + | environment variable. | |||
| 44 | + | ||||
| 45 | + | Toplevels are managed through the xdg_session_v1.add_toplevel and | |||
| 46 | + | xdg_session_v1.remove_toplevel pair of requests. Clients will explicitly | |||
| 47 | + | request a toplevel to be restored according to prior state through the | |||
| 48 | + | xdg_session_v1.restore_toplevel request before the toplevel is mapped. | |||
| 49 | + | ||||
| 50 | + | Compositors may store session information up to any arbitrary level, and | |||
| 51 | + | apply any limits and policies to the amount of data stored and its lifetime. | |||
| 52 | + | Clients must account for missing sessions and partial session restoration. | |||
| 53 | + | ||||
| 54 | + | Warning! The protocol described in this file is currently in the testing | |||
| 55 | + | phase. Backward compatible changes may be added together with the | |||
| 56 | + | corresponding interface version bump. Backward incompatible changes can | |||
| 57 | + | only be done by creating a new major version of the extension. | |||
| 58 | + | </description> | |||
| 59 | + | ||||
| 60 | + | <interface name="xdg_session_manager_v1" version="1"> | |||
| 61 | + | <description summary="manage sessions for applications"> | |||
| 62 | + | The xdg_session_manager_v1 interface defines base requests for creating and | |||
| 63 | + | managing a session for an application. Sessions persist across application | |||
| 64 | + | and compositor restarts unless explicitly destroyed. A session is created | |||
| 65 | + | for the purpose of maintaining an application's xdg_toplevel surfaces | |||
| 66 | + | across compositor or application restarts. The compositor should remember | |||
| 67 | + | as many states as possible for surfaces in a given session, but there is | |||
| 68 | + | no requirement for which states must be remembered. | |||
| 69 | + | ||||
| 70 | + | Policies such as cache eviction are declared an implementation detail of | |||
| 71 | + | the compositor. Clients should account for no longer existing sessions. | |||
| 72 | + | </description> | |||
| 73 | + | ||||
| 74 | + | <enum name="error"> | |||
| 75 | + | <entry name="in_use" summary="a requested session is already in use" | |||
| 76 | + | value="1"/> | |||
| 77 | + | <entry name="invalid_session_id" summary="invalid session identifier" | |||
| 78 | + | value="2"/> | |||
| 79 | + | <entry name="invalid_reason" summary="invalid reason" value="3"/> | |||
| 80 | + | </enum> | |||
| 81 | + | ||||
| 82 | + | <enum name="reason"> | |||
| 83 | + | <description summary="reason for getting a session"> | |||
| 84 | + | The reason may determine in what way a session restores the window | |||
| 85 | + | management state of associated toplevels. | |||
| 86 | + | ||||
| 87 | + | For example newly launched applications might be launched on the active | |||
| 88 | + | workspace with restored size and position, while a recovered | |||
| 89 | + | application might restore additional state such as active workspace and | |||
| 90 | + | stacking order. | |||
| 91 | + | </description> | |||
| 92 | + | <entry name="launch" value="1"> | |||
| 93 | + | <description summary="an app is newly launched"> | |||
| 94 | + | A new app instance is launched, for example from an app launcher. | |||
| 95 | + | </description> | |||
| 96 | + | </entry> | |||
| 97 | + | <entry name="recover" value="2"> | |||
| 98 | + | <description summary="an app recovered"> | |||
| 99 | + | An app instance is recovering from for example a compositor or app crash. | |||
| 100 | + | </description> | |||
| 101 | + | </entry> | |||
| 102 | + | <entry name="session_restore" value="3"> | |||
| 103 | + | <description summary="an app restored"> | |||
| 104 | + | An app instance is restored, for example part of a restored session, or | |||
| 105 | + | restored from having been temporarily terminated due to resource | |||
| 106 | + | constraints. | |||
| 107 | + | </description> | |||
| 108 | + | </entry> | |||
| 109 | + | </enum> | |||
| 110 | + | ||||
| 111 | + | <request name="destroy" type="destructor"> | |||
| 112 | + | <description summary="Destroy this object"> | |||
| 113 | + | Destroy the manager object. The existing session objects will be | |||
| 114 | + | unaffected. | |||
| 115 | + | </description> | |||
| 116 | + | </request> | |||
| 117 | + | ||||
| 118 | + | <request name="get_session"> | |||
| 119 | + | <description summary="create or restore a session"> | |||
| 120 | + | Create a session object corresponding to either an existing session | |||
| 121 | + | identified by the given session identifier string or a new session. | |||
| 122 | + | While the session object exists, the session is considered to be "in | |||
| 123 | + | use". | |||
| 124 | + | ||||
| 125 | + | If an identifier string represents a session that is currently actively | |||
| 126 | + | in use by the the same client, an 'in_use' error is raised. If some | |||
| 127 | + | other client is currently using the same session, the new session will | |||
| 128 | + | replace managing the associated state. | |||
| 129 | + | ||||
| 130 | + | If the reason is not a valid enum entry, the 'invalid_reason' protocol | |||
| 131 | + | error is raised. | |||
| 132 | + | ||||
| 133 | + | NULL is passed to initiate a new session. If a session_id is passed | |||
| 134 | + | which does not represent a valid session, the compositor treats it as if | |||
| 135 | + | NULL had been passed. | |||
| 136 | + | ||||
| 137 | + | The session id string must be UTF-8 encoded. It is also limited by the | |||
| 138 | + | maximum length of wayland messages (around 4KB). The 'invalid_session_id' | |||
| 139 | + | protocol error will be raised if an invalid string is provided. | |||
| 140 | + | ||||
| 141 | + | A client is allowed to have any number of in use sessions at the same | |||
| 142 | + | time. | |||
| 143 | + | </description> | |||
| 144 | + | <arg name="id" type="new_id" interface="xdg_session_v1"/> | |||
| 145 | + | <arg name="reason" type="uint" enum="reason" | |||
| 146 | + | summary="reason for session"/> | |||
| 147 | + | <arg name="session_id" type="string" | |||
| 148 | + | summary="the session to restore" | |||
| 149 | + | allow-null="true"/> | |||
| 150 | + | </request> | |||
| 151 | + | </interface> | |||
| 152 | + | ||||
| 153 | + | <interface name="xdg_session_v1" version="1"> | |||
| 154 | + | <description summary="A session for an application"> | |||
| 155 | + | A xdg_session_v1 object represents a session for an application. While the | |||
| 156 | + | object exists, all surfaces which have been added to the session will | |||
| 157 | + | have states stored by the compositor which can be reapplied at a later | |||
| 158 | + | time. Two sessions cannot exist for the same identifier string. | |||
| 159 | + | ||||
| 160 | + | States for surfaces added to a session are automatically updated by the | |||
| 161 | + | compositor when they are changed. | |||
| 162 | + | </description> | |||
| 163 | + | ||||
| 164 | + | <enum name="error"> | |||
| 165 | + | <entry name="name_in_use" | |||
| 166 | + | summary="toplevel name is already in use" | |||
| 167 | + | value="1"/> | |||
| 168 | + | <entry name="already_mapped" | |||
| 169 | + | summary="toplevel was already mapped when restored" | |||
| 170 | + | value="2"/> | |||
| 171 | + | <entry name="invalid_name" | |||
| 172 | + | summary="provided toplevel name is invalid" | |||
| 173 | + | value="3"/> | |||
| 174 | + | <entry name="already_added" | |||
| 175 | + | summary="toplevel already added" | |||
| 176 | + | value="4"/> | |||
| 177 | + | </enum> | |||
| 178 | + | ||||
| 179 | + | <request name="destroy" type="destructor"> | |||
| 180 | + | <description summary="Destroy the session"> | |||
| 181 | + | Destroy a session object, preserving the current state but not continuing | |||
| 182 | + | to make further updates if state changes occur. This makes the associated | |||
| 183 | + | xdg_toplevel_session_v1 objects inert. | |||
| 184 | + | </description> | |||
| 185 | + | </request> | |||
| 186 | + | ||||
| 187 | + | <request name="remove" type="destructor"> | |||
| 188 | + | <description summary="Remove the session"> | |||
| 189 | + | Remove the session, making it no longer available for restoration. A | |||
| 190 | + | compositor should in response to this request remove the data related to | |||
| 191 | + | this session from its storage. | |||
| 192 | + | </description> | |||
| 193 | + | </request> | |||
| 194 | + | ||||
| 195 | + | <request name="add_toplevel"> | |||
| 196 | + | <description summary="add a new surface to the session"> | |||
| 197 | + | Attempt to add a given surface to the session. The passed name is used | |||
| 198 | + | to identify what window is being restored, and may be used to store | |||
| 199 | + | window specific state within the session. | |||
| 200 | + | ||||
| 201 | + | The name given to the toplevel must not correspond to any previously | |||
| 202 | + | existing toplevel names in the session. If the name matches an already | |||
| 203 | + | known toplevel name in the session, a 'name_in_use' protocol error will | |||
| 204 | + | be raised. | |||
| 205 | + | ||||
| 206 | + | The toplevel object must not be added more than once to any session | |||
| 207 | + | created by the client, otherwise the 'already_added' protocol error | |||
| 208 | + | will be raised. | |||
| 209 | + | ||||
| 210 | + | This request will return a xdg_toplevel_session_v1 for later | |||
| 211 | + | manipulation. As this resource is created from an empty initial state, | |||
| 212 | + | compositors must not emit a xdg_toplevel_session_v1.restored event for | |||
| 213 | + | resources created through this request. | |||
| 214 | + | ||||
| 215 | + | The name string must be UTF-8 encoded. It is also limited by the maximum | |||
| 216 | + | length of wayland messages (around 4KB). The 'invalid_name' protocol | |||
| 217 | + | error will be raised if an invalid string is provided. | |||
| 218 | + | </description> | |||
| 219 | + | <arg name="id" type="new_id" interface="xdg_toplevel_session_v1"/> | |||
| 220 | + | <arg name="toplevel" type="object" interface="xdg_toplevel"/> | |||
| 221 | + | <arg name="name" type="string" summary="name identifying the toplevel"/> | |||
| 222 | + | </request> | |||
| 223 | + | ||||
| 224 | + | <request name="restore_toplevel"> | |||
| 225 | + | <description summary="restore a surface state"> | |||
| 226 | + | Inform the compositor that the toplevel associated with the passed name | |||
| 227 | + | should have its window management state restored. | |||
| 228 | + | ||||
| 229 | + | If the toplevel name was previously granted to another xdg_toplevel, | |||
| 230 | + | the 'name_in_use' protocol error will be raised. | |||
| 231 | + | ||||
| 232 | + | The toplevel object must not be added more than once to any session | |||
| 233 | + | created by the client, otherwise the 'already_added' protocol error | |||
| 234 | + | will be raised. | |||
| 235 | + | ||||
| 236 | + | This request must be called prior to the first commit on the associated | |||
| 237 | + | wl_surface after creating the toplevel, otherwise an 'already_mapped' | |||
| 238 | + | error is raised. | |||
| 239 | + | ||||
| 240 | + | As part of the initial configure sequence, if the toplevel was | |||
| 241 | + | successfully restored, a xdg_toplevel_session_v1.restored event is | |||
| 242 | + | emitted. If the toplevel name was not known in the session, this request | |||
| 243 | + | will be equivalent to the xdg_toplevel_session_v1.add_toplevel request, | |||
| 244 | + | and no such event will be emitted. See the xdg_toplevel_session_v1.restored | |||
| 245 | + | event for further details. | |||
| 246 | + | ||||
| 247 | + | The name string must be UTF-8 encoded. It is also limited by the maximum | |||
| 248 | + | length of wayland messages (around 4KB). The 'invalid_name' protocol | |||
| 249 | + | error will be raised if an invalid string is provided. | |||
| 250 | + | </description> | |||
| 251 | + | <arg name="id" type="new_id" interface="xdg_toplevel_session_v1"/> | |||
| 252 | + | <arg name="toplevel" type="object" interface="xdg_toplevel"/> | |||
| 253 | + | <arg name="name" type="string" summary="name identifying the toplevel"/> | |||
| 254 | + | </request> | |||
| 255 | + | ||||
| 256 | + | <request name="remove_toplevel"> | |||
| 257 | + | <description summary="remove a surface from the session"> | |||
| 258 | + | Remove a specified surface from the session and render any related | |||
| 259 | + | xdg_toplevel_session_v1 object inert. The compositor should remove any | |||
| 260 | + | data related to the toplevel in the corresponding session from its internal | |||
| 261 | + | storage. | |||
| 262 | + | ||||
| 263 | + | The window is specified by its name in the session. The name string | |||
| 264 | + | must be encoded in UTF-8, and it is limited in size by the maximum | |||
| 265 | + | length of wayland messages (around 4KB). | |||
| 266 | + | </description> | |||
| 267 | + | <arg name="name" type="string" summary="name identifying the toplevel"/> | |||
| 268 | + | </request> | |||
| 269 | + | ||||
| 270 | + | <event name="created"> | |||
| 271 | + | <description summary="newly-created session id"> | |||
| 272 | + | Emitted at most once some time after getting a new session object. It | |||
| 273 | + | means that no previous state was restored, and a new session was created. | |||
| 274 | + | The passed id can be persistently stored and used to restore previous | |||
| 275 | + | sessions. | |||
| 276 | + | </description> | |||
| 277 | + | <arg name="session_id" type="string"/> | |||
| 278 | + | </event> | |||
| 279 | + | ||||
| 280 | + | <event name="restored"> | |||
| 281 | + | <description summary="the session has been restored"> | |||
| 282 | + | Emitted at most once some time after getting a new session object. It | |||
| 283 | + | means that previous state was at least partially restored. The same id | |||
| 284 | + | can again be used to restore previous sessions. | |||
| 285 | + | </description> | |||
| 286 | + | </event> | |||
| 287 | + | ||||
| 288 | + | <event name="replaced"> | |||
| 289 | + | <description summary="the session has been replaced"> | |||
| 290 | + | Emitted at most once, if the session was taken over by some other | |||
| 291 | + | client. When this happens, the session and all its toplevel session | |||
| 292 | + | objects become inert, and should be destroyed. | |||
| 293 | + | </description> | |||
| 294 | + | </event> | |||
| 295 | + | </interface> | |||
| 296 | + | ||||
| 297 | + | <interface name="xdg_toplevel_session_v1" version="1"> | |||
| 298 | + | <description summary="A session for an application"> | |||
| 299 | + | A xdg_toplevel_session_v1 resource acts as a handle for the given | |||
| 300 | + | toplevel in the session. It allows for receiving events after a | |||
| 301 | + | toplevel state was restored, and has the requests to manage them. | |||
| 302 | + | </description> | |||
| 303 | + | ||||
| 304 | + | <request name="destroy" type="destructor"> | |||
| 305 | + | <description summary="Destroy the object"> | |||
| 306 | + | Destroy the object. This has no effect over window management of the | |||
| 307 | + | associated toplevel. | |||
| 308 | + | </description> | |||
| 309 | + | </request> | |||
| 310 | + | ||||
| 311 | + | <request name="rename"> | |||
| 312 | + | <description summary="change the name of toplevel session"> | |||
| 313 | + | Renames the toplevel session. The new name can be used in subsequent requests | |||
| 314 | + | to identify this session object. The state associated with this toplevel | |||
| 315 | + | session will be preserved. | |||
| 316 | + | ||||
| 317 | + | If the xdg_session_v1 already contains a toplevel with the specified name, | |||
| 318 | + | the 'name_in_use' protocol error will be raised. | |||
| 319 | + | </description> | |||
| 320 | + | <arg name="name" type="string" summary="new name to identify the toplevel"/> | |||
| 321 | + | </request> | |||
| 322 | + | ||||
| 323 | + | <event name="restored"> | |||
| 324 | + | <description summary="a toplevel's session has been restored"> | |||
| 325 | + | The "restored" event is emitted prior to the first | |||
| 326 | + | xdg_toplevel.configure for the toplevel. It will only be emitted after | |||
| 327 | + | xdg_session_v1.restore_toplevel, and the initial empty surface state has | |||
| 328 | + | been applied, and it indicates that the surface's session is being | |||
| 329 | + | restored with this configure event. | |||
| 330 | + | </description> | |||
| 331 | + | </event> | |||
| 332 | + | </interface> | |||
| 333 | + | </protocol> | |||
A spec/xml/xdgshell.xml +1420 -0 collapsed to keep the page light
A spec/xml/xdgsystembell.xml +58 -0
| @@ -0,0 +1,58 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="xdg_system_bell_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2016, 2023 Red Hat | |||
| 5 | + | ||||
| 6 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 7 | + | copy of this software and associated documentation files (the "Software"), | |||
| 8 | + | to deal in the Software without restriction, including without limitation | |||
| 9 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 10 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 11 | + | Software is furnished to do so, subject to the following conditions: | |||
| 12 | + | ||||
| 13 | + | The above copyright notice and this permission notice (including the next | |||
| 14 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 15 | + | Software. | |||
| 16 | + | ||||
| 17 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 18 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 19 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 20 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 21 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 22 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 23 | + | DEALINGS IN THE SOFTWARE. | |||
| 24 | + | </copyright> | |||
| 25 | + | ||||
| 26 | + | <interface name="xdg_system_bell_v1" version="1"> | |||
| 27 | + | <description summary="system bell"> | |||
| 28 | + | This global interface enables clients to ring the system bell. | |||
| 29 | + | ||||
| 30 | + | Warning! The protocol described in this file is currently in the testing | |||
| 31 | + | phase. Backward compatible changes may be added together with the | |||
| 32 | + | corresponding interface version bump. Backward incompatible changes can | |||
| 33 | + | only be done by creating a new major version of the extension. | |||
| 34 | + | </description> | |||
| 35 | + | ||||
| 36 | + | <request name="destroy" type="destructor"> | |||
| 37 | + | <description summary="destroy the system bell object"> | |||
| 38 | + | Notify that the object will no longer be used. | |||
| 39 | + | </description> | |||
| 40 | + | </request> | |||
| 41 | + | ||||
| 42 | + | <request name="ring"> | |||
| 43 | + | <description summary="ring the system bell"> | |||
| 44 | + | This requests rings the system bell on behalf of a client. How ringing | |||
| 45 | + | the bell is implemented is up to the compositor. It may be an audible | |||
| 46 | + | sound, a visual feedback of some kind, or any other thing including | |||
| 47 | + | nothing. | |||
| 48 | + | ||||
| 49 | + | The passed surface should correspond to a toplevel like surface role, | |||
| 50 | + | or be null, meaning the client doesn't have a particular toplevel it | |||
| 51 | + | wants to associate the bell ringing with. See the xdg-shell protocol | |||
| 52 | + | extension for a toplevel like surface role. | |||
| 53 | + | </description> | |||
| 54 | + | <arg name="surface" type="object" interface="wl_surface" | |||
| 55 | + | allow-null="true" summary="associated surface"/> | |||
| 56 | + | </request> | |||
| 57 | + | </interface> | |||
| 58 | + | </protocol> | |||
A spec/xml/xdgtopleveldrag.xml +142 -0
| @@ -0,0 +1,142 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="xdg_toplevel_drag_v1"> | |||
| 3 | + | ||||
| 4 | + | <copyright> | |||
| 5 | + | Copyright 2023 David Redondo | |||
| 6 | + | ||||
| 7 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 8 | + | copy of this software and associated documentation files (the "Software"), | |||
| 9 | + | to deal in the Software without restriction, including without limitation | |||
| 10 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 11 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 12 | + | Software is furnished to do so, subject to the following conditions: | |||
| 13 | + | ||||
| 14 | + | The above copyright notice and this permission notice (including the next | |||
| 15 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 16 | + | Software. | |||
| 17 | + | ||||
| 18 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 19 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 20 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 21 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 22 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 23 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 24 | + | DEALINGS IN THE SOFTWARE. | |||
| 25 | + | </copyright> | |||
| 26 | + | ||||
| 27 | + | <interface name="xdg_toplevel_drag_manager_v1" version="1"> | |||
| 28 | + | <description summary="Move a window during a drag"> | |||
| 29 | + | This protocol enhances normal drag and drop with the ability to move a | |||
| 30 | + | window at the same time. This allows having detachable parts of a window | |||
| 31 | + | that when dragged out of it become a new window and can be dragged over | |||
| 32 | + | an existing window to be reattached. | |||
| 33 | + | ||||
| 34 | + | A typical workflow would be when the user starts dragging on top of a | |||
| 35 | + | detachable part of a window, the client would create a wl_data_source and | |||
| 36 | + | a xdg_toplevel_drag_v1 object and start the drag as normal via | |||
| 37 | + | wl_data_device.start_drag. Once the client determines that the detachable | |||
| 38 | + | window contents should be detached from the originating window, it creates | |||
| 39 | + | a new xdg_toplevel with these contents and issues a | |||
| 40 | + | xdg_toplevel_drag_v1.attach request before mapping it. From now on the new | |||
| 41 | + | window is moved by the compositor during the drag as if the client called | |||
| 42 | + | xdg_toplevel.move. | |||
| 43 | + | ||||
| 44 | + | Dragging an existing window is similar. The client creates a | |||
| 45 | + | xdg_toplevel_drag_v1 object and attaches the existing toplevel before | |||
| 46 | + | starting the drag. | |||
| 47 | + | ||||
| 48 | + | Clients use the existing drag and drop mechanism to detect when a window | |||
| 49 | + | can be docked or undocked. If the client wants to snap a window into a | |||
| 50 | + | parent window it should delete or unmap the dragged top-level. If the | |||
| 51 | + | contents should be detached again it attaches a new toplevel as described | |||
| 52 | + | above. If a drag operation is cancelled without being dropped, clients | |||
| 53 | + | should revert to the previous state, deleting any newly created windows | |||
| 54 | + | as appropriate. When a drag operation ends as indicated by | |||
| 55 | + | wl_data_source.dnd_drop_performed the dragged toplevel window's final | |||
| 56 | + | position is determined as if a xdg_toplevel_move operation ended. | |||
| 57 | + | ||||
| 58 | + | Warning! The protocol described in this file is currently in the testing | |||
| 59 | + | phase. Backward compatible changes may be added together with the | |||
| 60 | + | corresponding interface version bump. Backward incompatible changes can | |||
| 61 | + | only be done by creating a new major version of the extension. | |||
| 62 | + | </description> | |||
| 63 | + | ||||
| 64 | + | <enum name="error"> | |||
| 65 | + | <entry name="invalid_source" value="0" | |||
| 66 | + | summary="data_source already used for toplevel drag"/> | |||
| 67 | + | </enum> | |||
| 68 | + | ||||
| 69 | + | <request name="destroy" type="destructor"> | |||
| 70 | + | <description summary="destroy the xdg_toplevel_drag_manager_v1 object"> | |||
| 71 | + | Destroy this xdg_toplevel_drag_manager_v1 object. Other objects, | |||
| 72 | + | including xdg_toplevel_drag_v1 objects created by this factory, are not | |||
| 73 | + | affected by this request. | |||
| 74 | + | </description> | |||
| 75 | + | </request> | |||
| 76 | + | ||||
| 77 | + | <request name="get_xdg_toplevel_drag"> | |||
| 78 | + | <description summary="get an xdg_toplevel_drag for a wl_data_source"> | |||
| 79 | + | Create an xdg_toplevel_drag for a drag and drop operation that is going | |||
| 80 | + | to be started with data_source. | |||
| 81 | + | ||||
| 82 | + | This request can only be made on sources used in drag-and-drop, so it | |||
| 83 | + | must be performed before wl_data_device.start_drag. Attempting to use | |||
| 84 | + | the source other than for drag-and-drop such as in | |||
| 85 | + | wl_data_device.set_selection will raise an invalid_source error. | |||
| 86 | + | ||||
| 87 | + | Destroying data_source while a toplevel is attached to the | |||
| 88 | + | xdg_toplevel_drag is undefined. | |||
| 89 | + | </description> | |||
| 90 | + | ||||
| 91 | + | <arg name="id" type="new_id" interface="xdg_toplevel_drag_v1"/> | |||
| 92 | + | <arg name="data_source" type="object" interface="wl_data_source"/> | |||
| 93 | + | </request> | |||
| 94 | + | </interface> | |||
| 95 | + | ||||
| 96 | + | <interface name="xdg_toplevel_drag_v1" version="1"> | |||
| 97 | + | <description summary="Object representing a toplevel move during a drag"> | |||
| 98 | + | </description> | |||
| 99 | + | ||||
| 100 | + | <enum name="error"> | |||
| 101 | + | <entry name="toplevel_attached" value="0" | |||
| 102 | + | summary="valid toplevel already attached"/> | |||
| 103 | + | <entry name="ongoing_drag" value="1" | |||
| 104 | + | summary="drag has not ended" /> | |||
| 105 | + | </enum> | |||
| 106 | + | ||||
| 107 | + | <request name="destroy" type="destructor"> | |||
| 108 | + | <description summary="destroy an xdg_toplevel_drag_v1 object"> | |||
| 109 | + | Destroy this xdg_toplevel_drag_v1 object. This request must only be | |||
| 110 | + | called after the underlying wl_data_source drag has ended, as indicated | |||
| 111 | + | by the dnd_drop_performed or cancelled events. In any other case an | |||
| 112 | + | ongoing_drag error is raised. | |||
| 113 | + | </description> | |||
| 114 | + | </request> | |||
| 115 | + | ||||
| 116 | + | <request name="attach"> | |||
| 117 | + | <description summary="Move a toplevel with the drag operation"> | |||
| 118 | + | Request that the window will be moved with the cursor during the drag | |||
| 119 | + | operation. The offset is a hint to the compositor how the toplevel | |||
| 120 | + | should be positioned relative to the cursor hotspot in surface local | |||
| 121 | + | coordinates and relative to the geometry of the toplevel being attached. | |||
| 122 | + | See xdg_surface.set_window_geometry. For example it might only | |||
| 123 | + | be used when an unmapped window is attached. The attached window | |||
| 124 | + | does not participate in the selection of the drag target. | |||
| 125 | + | ||||
| 126 | + | If the toplevel is unmapped while it is attached, it is automatically | |||
| 127 | + | detached from the drag. In this case this request has to be called again | |||
| 128 | + | if the window should be attached after it is remapped. | |||
| 129 | + | ||||
| 130 | + | This request can be called multiple times but issuing it while a | |||
| 131 | + | toplevel with an active role is attached raises a toplevel_attached | |||
| 132 | + | error. | |||
| 133 | + | </description> | |||
| 134 | + | ||||
| 135 | + | <arg name="toplevel" type="object" interface="xdg_toplevel"/> | |||
| 136 | + | <arg name="x_offset" type="int" summary="dragged surface x offset"/> | |||
| 137 | + | <arg name="y_offset" type="int" summary="dragged surface y offset"/> | |||
| 138 | + | </request> | |||
| 139 | + | ||||
| 140 | + | </interface> | |||
| 141 | + | </protocol> | |||
| 142 | + | ||||
A spec/xml/xdgtoplevelicon.xml +205 -0
| @@ -0,0 +1,205 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="xdg_toplevel_icon_v1"> | |||
| 3 | + | ||||
| 4 | + | <copyright> | |||
| 5 | + | Copyright © 2023-2024 Matthias Klumpp | |||
| 6 | + | Copyright © 2024 David Edmundson | |||
| 7 | + | ||||
| 8 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 9 | + | copy of this software and associated documentation files (the "Software"), | |||
| 10 | + | to deal in the Software without restriction, including without limitation | |||
| 11 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 12 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 13 | + | Software is furnished to do so, subject to the following conditions: | |||
| 14 | + | ||||
| 15 | + | The above copyright notice and this permission notice (including the next | |||
| 16 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 17 | + | Software. | |||
| 18 | + | ||||
| 19 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 20 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 21 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 22 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 23 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 24 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 25 | + | DEALINGS IN THE SOFTWARE. | |||
| 26 | + | </copyright> | |||
| 27 | + | ||||
| 28 | + | <description summary="protocol to assign icons to toplevels"> | |||
| 29 | + | This protocol allows clients to set icons for their toplevel surfaces | |||
| 30 | + | either via the XDG icon stock (using an icon name), or from pixel data. | |||
| 31 | + | ||||
| 32 | + | A toplevel icon represents the individual toplevel (unlike the application | |||
| 33 | + | or launcher icon, which represents the application as a whole), and may be | |||
| 34 | + | shown in window switchers, window overviews and taskbars that list | |||
| 35 | + | individual windows. | |||
| 36 | + | ||||
| 37 | + | This document adheres to RFC 2119 when using words like "must", | |||
| 38 | + | "should", "may", etc. | |||
| 39 | + | ||||
| 40 | + | Warning! The protocol described in this file is currently in the testing | |||
| 41 | + | phase. Backward compatible changes may be added together with the | |||
| 42 | + | corresponding interface version bump. Backward incompatible changes can | |||
| 43 | + | only be done by creating a new major version of the extension. | |||
| 44 | + | </description> | |||
| 45 | + | ||||
| 46 | + | <interface name="xdg_toplevel_icon_manager_v1" version="1"> | |||
| 47 | + | <description summary="interface to manage toplevel icons"> | |||
| 48 | + | This interface allows clients to create toplevel window icons and set | |||
| 49 | + | them on toplevel windows to be displayed to the user. | |||
| 50 | + | </description> | |||
| 51 | + | ||||
| 52 | + | <request name="destroy" type="destructor"> | |||
| 53 | + | <description summary="destroy the toplevel icon manager"> | |||
| 54 | + | Destroy the toplevel icon manager. | |||
| 55 | + | This does not destroy objects created with the manager. | |||
| 56 | + | </description> | |||
| 57 | + | </request> | |||
| 58 | + | ||||
| 59 | + | <request name="create_icon"> | |||
| 60 | + | <description summary="create a new icon instance"> | |||
| 61 | + | Creates a new icon object. This icon can then be attached to a | |||
| 62 | + | xdg_toplevel via the 'set_icon' request. | |||
| 63 | + | </description> | |||
| 64 | + | <arg name="id" type="new_id" interface="xdg_toplevel_icon_v1"/> | |||
| 65 | + | </request> | |||
| 66 | + | ||||
| 67 | + | <request name="set_icon"> | |||
| 68 | + | <description summary="set an icon on a toplevel window"> | |||
| 69 | + | This request assigns the icon 'icon' to 'toplevel', or clears the | |||
| 70 | + | toplevel icon if 'icon' was null. | |||
| 71 | + | This state is double-buffered and is applied on the next | |||
| 72 | + | wl_surface.commit of the toplevel. | |||
| 73 | + | ||||
| 74 | + | After making this call, the xdg_toplevel_icon_v1 provided as 'icon' | |||
| 75 | + | can be destroyed by the client without 'toplevel' losing its icon. | |||
| 76 | + | The xdg_toplevel_icon_v1 is immutable from this point, and any | |||
| 77 | + | future attempts to change it must raise the | |||
| 78 | + | 'xdg_toplevel_icon_v1.immutable' protocol error. | |||
| 79 | + | ||||
| 80 | + | The compositor must set the toplevel icon from either the pixel data | |||
| 81 | + | the icon provides, or by loading a stock icon using the icon name. | |||
| 82 | + | See the description of 'xdg_toplevel_icon_v1' for details. | |||
| 83 | + | ||||
| 84 | + | If 'icon' is set to null, the icon of the respective toplevel is reset | |||
| 85 | + | to its default icon (usually the icon of the application, derived from | |||
| 86 | + | its desktop-entry file, or a placeholder icon). | |||
| 87 | + | If this request is passed an icon with no pixel buffers or icon name | |||
| 88 | + | assigned, the icon must be reset just like if 'icon' was null. | |||
| 89 | + | </description> | |||
| 90 | + | <arg name="toplevel" type="object" interface="xdg_toplevel" summary="the toplevel to act on"/> | |||
| 91 | + | <arg name="icon" type="object" interface="xdg_toplevel_icon_v1" allow-null="true"/> | |||
| 92 | + | </request> | |||
| 93 | + | ||||
| 94 | + | <event name="icon_size"> | |||
| 95 | + | <description summary="describes a supported & preferred icon size"> | |||
| 96 | + | This event indicates an icon size the compositor prefers to be | |||
| 97 | + | available if the client has scalable icons and can render to any size. | |||
| 98 | + | ||||
| 99 | + | When the 'xdg_toplevel_icon_manager_v1' object is created, the | |||
| 100 | + | compositor may send one or more 'icon_size' events to describe the list | |||
| 101 | + | of preferred icon sizes. If the compositor has no size preference, it | |||
| 102 | + | may not send any 'icon_size' event, and it is up to the client to | |||
| 103 | + | decide a suitable icon size. | |||
| 104 | + | ||||
| 105 | + | A sequence of 'icon_size' events must be finished with a 'done' event. | |||
| 106 | + | If the compositor has no size preferences, it must still send the | |||
| 107 | + | 'done' event, without any preceding 'icon_size' events. | |||
| 108 | + | </description> | |||
| 109 | + | <arg name="size" type="int" | |||
| 110 | + | summary="the edge size of the square icon in surface-local coordinates, e.g. 64"/> | |||
| 111 | + | </event> | |||
| 112 | + | ||||
| 113 | + | <event name="done"> | |||
| 114 | + | <description summary="all information has been sent"> | |||
| 115 | + | This event is sent after all 'icon_size' events have been sent. | |||
| 116 | + | </description> | |||
| 117 | + | </event> | |||
| 118 | + | </interface> | |||
| 119 | + | ||||
| 120 | + | <interface name="xdg_toplevel_icon_v1" version="1"> | |||
| 121 | + | <description summary="a toplevel window icon"> | |||
| 122 | + | This interface defines a toplevel icon. | |||
| 123 | + | An icon can have a name, and multiple buffers. | |||
| 124 | + | In order to be applied, the icon must have either a name, or at least | |||
| 125 | + | one buffer assigned. Applying an empty icon (with no buffer or name) to | |||
| 126 | + | a toplevel should reset its icon to the default icon. | |||
| 127 | + | ||||
| 128 | + | It is up to compositor policy whether to prefer using a buffer or loading | |||
| 129 | + | an icon via its name. See 'set_name' and 'add_buffer' for details. | |||
| 130 | + | </description> | |||
| 131 | + | ||||
| 132 | + | <enum name="error"> | |||
| 133 | + | <entry name="invalid_buffer" | |||
| 134 | + | summary="the provided buffer does not satisfy requirements" | |||
| 135 | + | value="1"/> | |||
| 136 | + | <entry name="immutable" | |||
| 137 | + | summary="the icon has already been assigned to a toplevel and must not be changed" | |||
| 138 | + | value="2"/> | |||
| 139 | + | <entry name="no_buffer" | |||
| 140 | + | summary="the provided buffer has been destroyed before the toplevel icon" | |||
| 141 | + | value="3"/> | |||
| 142 | + | </enum> | |||
| 143 | + | ||||
| 144 | + | <request name="destroy" type="destructor"> | |||
| 145 | + | <description summary="destroy the icon object"> | |||
| 146 | + | Destroys the 'xdg_toplevel_icon_v1' object. | |||
| 147 | + | The icon must still remain set on every toplevel it was assigned to, | |||
| 148 | + | until the toplevel icon is reset explicitly. | |||
| 149 | + | </description> | |||
| 150 | + | </request> | |||
| 151 | + | ||||
| 152 | + | <request name="set_name"> | |||
| 153 | + | <description summary="set an icon name"> | |||
| 154 | + | This request assigns an icon name to this icon. | |||
| 155 | + | Any previously set name is overridden. | |||
| 156 | + | ||||
| 157 | + | The compositor must resolve 'icon_name' according to the lookup rules | |||
| 158 | + | described in the XDG icon theme specification[1] using the | |||
| 159 | + | environment's current icon theme. | |||
| 160 | + | ||||
| 161 | + | If the compositor does not support icon names or cannot resolve | |||
| 162 | + | 'icon_name' according to the XDG icon theme specification it must | |||
| 163 | + | fall back to using pixel buffer data instead. | |||
| 164 | + | ||||
| 165 | + | If this request is made after the icon has been assigned to a toplevel | |||
| 166 | + | via 'set_icon', an 'immutable' error must be raised. | |||
| 167 | + | ||||
| 168 | + | [1]: https://specifications.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html | |||
| 169 | + | </description> | |||
| 170 | + | <arg name="icon_name" type="string"/> | |||
| 171 | + | </request> | |||
| 172 | + | ||||
| 173 | + | <request name="add_buffer"> | |||
| 174 | + | <description summary="add icon data from a pixel buffer"> | |||
| 175 | + | This request adds pixel data supplied as wl_buffer to the icon. | |||
| 176 | + | ||||
| 177 | + | The client should add pixel data for all icon sizes and scales that | |||
| 178 | + | it can provide, or which are explicitly requested by the compositor | |||
| 179 | + | via 'icon_size' events on xdg_toplevel_icon_manager_v1. | |||
| 180 | + | ||||
| 181 | + | The wl_buffer supplying pixel data as 'buffer' must be backed by wl_shm | |||
| 182 | + | and must be a square (width and height being equal). | |||
| 183 | + | If any of these buffer requirements are not fulfilled, a 'invalid_buffer' | |||
| 184 | + | error must be raised. | |||
| 185 | + | ||||
| 186 | + | If this icon instance already has a buffer of the same size and scale | |||
| 187 | + | from a previous 'add_buffer' request, data from the last request | |||
| 188 | + | overrides the preexisting pixel data. | |||
| 189 | + | ||||
| 190 | + | The wl_buffer must be kept alive for as long as the xdg_toplevel_icon | |||
| 191 | + | it is associated with is not destroyed, otherwise a 'no_buffer' error | |||
| 192 | + | is raised. The buffer contents must not be modified after it was | |||
| 193 | + | assigned to the icon. As a result, the region of the wl_shm_pool's | |||
| 194 | + | backing storage used for the wl_buffer must not be modified after this | |||
| 195 | + | request is sent. The wl_buffer.release event is unused. | |||
| 196 | + | ||||
| 197 | + | If this request is made after the icon has been assigned to a toplevel | |||
| 198 | + | via 'set_icon', an 'immutable' error must be raised. | |||
| 199 | + | </description> | |||
| 200 | + | <arg name="buffer" type="object" interface="wl_buffer"/> | |||
| 201 | + | <arg name="scale" type="int" | |||
| 202 | + | summary="the scaling factor of the icon, e.g. 1"/> | |||
| 203 | + | </request> | |||
| 204 | + | </interface> | |||
| 205 | + | </protocol> | |||
A spec/xml/xdgtopleveltag.xml +85 -0
| @@ -0,0 +1,85 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="xdg_toplevel_tag_v1"> | |||
| 3 | + | <copyright> | |||
| 4 | + | Copyright © 2024 Xaver Hugl | |||
| 5 | + | ||||
| 6 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 7 | + | copy of this software and associated documentation files (the "Software"), | |||
| 8 | + | to deal in the Software without restriction, including without limitation | |||
| 9 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 10 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 11 | + | Software is furnished to do so, subject to the following conditions: | |||
| 12 | + | ||||
| 13 | + | The above copyright notice and this permission notice (including the next | |||
| 14 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 15 | + | Software. | |||
| 16 | + | ||||
| 17 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 18 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 19 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 20 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 21 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 22 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 23 | + | DEALINGS IN THE SOFTWARE. | |||
| 24 | + | </copyright> | |||
| 25 | + | ||||
| 26 | + | <interface name="xdg_toplevel_tag_manager_v1" version="1"> | |||
| 27 | + | <description summary="protocol for setting toplevel tags"> | |||
| 28 | + | In order to make some window properties like position, size, | |||
| 29 | + | "always on top" or user defined rules for window behavior persistent, the | |||
| 30 | + | compositor needs some way to identify windows even after the application | |||
| 31 | + | has been restarted. | |||
| 32 | + | This protocol allows clients to make this possible by setting a tag for | |||
| 33 | + | toplevels. | |||
| 34 | + | ||||
| 35 | + | Warning! The protocol described in this file is currently in the testing | |||
| 36 | + | phase. Backward compatible changes may be added together with the | |||
| 37 | + | corresponding interface version bump. Backward incompatible changes can | |||
| 38 | + | only be done by creating a new major version of the extension. | |||
| 39 | + | </description> | |||
| 40 | + | ||||
| 41 | + | <request name="destroy" type="destructor"> | |||
| 42 | + | <description summary="destroy toplevel tag object"> | |||
| 43 | + | Destroy this toplevel tag manager object. This request has no other | |||
| 44 | + | effects. | |||
| 45 | + | </description> | |||
| 46 | + | </request> | |||
| 47 | + | ||||
| 48 | + | <request name="set_toplevel_tag"> | |||
| 49 | + | <description summary="set tag"> | |||
| 50 | + | Set a tag for a toplevel. The tag may be shown to the user in UI, so | |||
| 51 | + | it's preferable for it to be human readable, but it must be suitable | |||
| 52 | + | for configuration files and should not be translated. | |||
| 53 | + | Suitable tags would for example be "main window", "settings", | |||
| 54 | + | "e-mail composer" or similar. | |||
| 55 | + | ||||
| 56 | + | The tag does not need to be unique across applications, and the client | |||
| 57 | + | may set the same tag for multiple windows, for example if the user has | |||
| 58 | + | opened the same UI twice. How the potentially resulting conflicts are | |||
| 59 | + | handled is compositor policy. | |||
| 60 | + | ||||
| 61 | + | The client should set the tag as part of the initial commit on the | |||
| 62 | + | associated toplevel, but it may set it at any time afterwards as well, | |||
| 63 | + | for example if the purpose of the toplevel changes. | |||
| 64 | + | </description> | |||
| 65 | + | <arg name="toplevel" type="object" interface="xdg_toplevel"/> | |||
| 66 | + | <arg name="tag" type="string" summary="untranslated tag"/> | |||
| 67 | + | </request> | |||
| 68 | + | ||||
| 69 | + | <request name="set_toplevel_description"> | |||
| 70 | + | <description summary="set description"> | |||
| 71 | + | Set a description for a toplevel. This description may be shown to the | |||
| 72 | + | user in UI or read by a screen reader for accessibility purposes, and | |||
| 73 | + | should be translated. | |||
| 74 | + | It is recommended to make the description the translation of the tag. | |||
| 75 | + | ||||
| 76 | + | The client should set the description as part of the initial commit on | |||
| 77 | + | the associated toplevel, but it may set it at any time afterwards as | |||
| 78 | + | well, for example if the purpose of the toplevel changes. | |||
| 79 | + | </description> | |||
| 80 | + | <arg name="toplevel" type="object" interface="xdg_toplevel"/> | |||
| 81 | + | <arg name="description" type="string" summary="translated description"/> | |||
| 82 | + | </request> | |||
| 83 | + | </interface> | |||
| 84 | + | ||||
| 85 | + | </protocol> | |||
A spec/xml/xwaylandkeyboardgrab.xml +121 -0
| @@ -0,0 +1,121 @@ | |||||
| 1 | + | <?xml version="1.0" encoding="UTF-8"?> | |||
| 2 | + | <protocol name="xwayland_keyboard_grab_unstable_v1"> | |||
| 3 | + | ||||
| 4 | + | <copyright> | |||
| 5 | + | Copyright © 2017 Red Hat Inc. | |||
| 6 | + | ||||
| 7 | + | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 8 | + | copy of this software and associated documentation files (the "Software"), | |||
| 9 | + | to deal in the Software without restriction, including without limitation | |||
| 10 | + | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 11 | + | and/or sell copies of the Software, and to permit persons to whom the | |||
| 12 | + | Software is furnished to do so, subject to the following conditions: | |||
| 13 | + | ||||
| 14 | + | The above copyright notice and this permission notice (including the next | |||
| 15 | + | paragraph) shall be included in all copies or substantial portions of the | |||
| 16 | + | Software. | |||
| 17 | + | ||||
| 18 | + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 19 | + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 20 | + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 21 | + | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 22 | + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 23 | + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 24 | + | DEALINGS IN THE SOFTWARE. | |||
| 25 | + | </copyright> | |||
| 26 | + | ||||
| 27 | + | <description summary="Protocol for grabbing the keyboard from Xwayland"> | |||
| 28 | + | This protocol is application-specific to meet the needs of the X11 | |||
| 29 | + | protocol through Xwayland. It provides a way for Xwayland to request | |||
| 30 | + | all keyboard events to be forwarded to a surface even when the | |||
| 31 | + | surface does not have keyboard focus. | |||
| 32 | + | ||||
| 33 | + | In the X11 protocol, a client may request an "active grab" on the | |||
| 34 | + | keyboard. On success, all key events are reported only to the | |||
| 35 | + | grabbing X11 client. For details, see XGrabKeyboard(3). | |||
| 36 | + | ||||
| 37 | + | The core Wayland protocol does not have a notion of an active | |||
| 38 | + | keyboard grab. When running in Xwayland, X11 applications may | |||
| 39 | + | acquire an active grab inside Xwayland but that cannot be translated | |||
| 40 | + | to the Wayland compositor who may set the input focus to some other | |||
| 41 | + | surface. In doing so, it breaks the X11 client assumption that all | |||
| 42 | + | key events are reported to the grabbing client. | |||
| 43 | + | ||||
| 44 | + | This protocol specifies a way for Xwayland to request all keyboard | |||
| 45 | + | be directed to the given surface. The protocol does not guarantee | |||
| 46 | + | that the compositor will honor this request and it does not | |||
| 47 | + | prescribe user interfaces on how to handle the respond. For example, | |||
| 48 | + | a compositor may inform the user that all key events are now | |||
| 49 | + | forwarded to the given client surface, or it may ask the user for | |||
| 50 | + | permission to do so. | |||
| 51 | + | ||||
| 52 | + | Compositors are required to restrict access to this application | |||
| 53 | + | specific protocol to Xwayland alone. | |||
| 54 | + | ||||
| 55 | + | Warning! The protocol described in this file is experimental and | |||
| 56 | + | backward incompatible changes may be made. Backward compatible | |||
| 57 | + | changes may be added together with the corresponding interface | |||
| 58 | + | version bump. | |||
| 59 | + | Backward incompatible changes are done by bumping the version | |||
| 60 | + | number in the protocol and interface names and resetting the | |||
| 61 | + | interface version. Once the protocol is to be declared stable, | |||
| 62 | + | the 'z' prefix and the version number in the protocol and | |||
| 63 | + | interface names are removed and the interface version number is | |||
| 64 | + | reset. | |||
| 65 | + | </description> | |||
| 66 | + | ||||
| 67 | + | <interface name="zwp_xwayland_keyboard_grab_manager_v1" version="1"> | |||
| 68 | + | <description summary="context object for keyboard grab manager"> | |||
| 69 | + | A global interface used for grabbing the keyboard. | |||
| 70 | + | </description> | |||
| 71 | + | ||||
| 72 | + | <request name="destroy" type="destructor"> | |||
| 73 | + | <description summary="destroy the keyboard grab manager"> | |||
| 74 | + | Destroy the keyboard grab manager. | |||
| 75 | + | </description> | |||
| 76 | + | </request> | |||
| 77 | + | ||||
| 78 | + | <request name="grab_keyboard"> | |||
| 79 | + | <description summary="grab the keyboard to a surface"> | |||
| 80 | + | The grab_keyboard request asks for a grab of the keyboard, forcing | |||
| 81 | + | the keyboard focus for the given seat upon the given surface. | |||
| 82 | + | ||||
| 83 | + | The protocol provides no guarantee that the grab is ever satisfied, | |||
| 84 | + | and does not require the compositor to send an error if the grab | |||
| 85 | + | cannot ever be satisfied. It is thus possible to request a keyboard | |||
| 86 | + | grab that will never be effective. | |||
| 87 | + | ||||
| 88 | + | The protocol: | |||
| 89 | + | ||||
| 90 | + | * does not guarantee that the grab itself is applied for a surface, | |||
| 91 | + | the grab request may be silently ignored by the compositor, | |||
| 92 | + | * does not guarantee that any events are sent to this client even | |||
| 93 | + | if the grab is applied to a surface, | |||
| 94 | + | * does not guarantee that events sent to this client are exhaustive, | |||
| 95 | + | a compositor may filter some events for its own consumption, | |||
| 96 | + | * does not guarantee that events sent to this client are continuous, | |||
| 97 | + | a compositor may change and reroute keyboard events while the grab | |||
| 98 | + | is nominally active. | |||
| 99 | + | </description> | |||
| 100 | + | ||||
| 101 | + | <arg name="id" type="new_id" interface="zwp_xwayland_keyboard_grab_v1"/> | |||
| 102 | + | <arg name="surface" type="object" interface="wl_surface" | |||
| 103 | + | summary="surface to report keyboard events to"/> | |||
| 104 | + | <arg name="seat" type="object" interface="wl_seat" | |||
| 105 | + | summary="the seat for which the keyboard should be grabbed"/> | |||
| 106 | + | </request> | |||
| 107 | + | </interface> | |||
| 108 | + | ||||
| 109 | + | <interface name="zwp_xwayland_keyboard_grab_v1" version="1"> | |||
| 110 | + | <description summary="interface for grabbing the keyboard"> | |||
| 111 | + | A global interface used for grabbing the keyboard. | |||
| 112 | + | </description> | |||
| 113 | + | ||||
| 114 | + | <request name="destroy" type="destructor"> | |||
| 115 | + | <description summary="destroy the grabbed keyboard object"> | |||
| 116 | + | Destroy the grabbed keyboard object. If applicable, the compositor | |||
| 117 | + | will ungrab the keyboard. | |||
| 118 | + | </description> | |||
| 119 | + | </request> | |||
| 120 | + | </interface> | |||
| 121 | + | </protocol> | |||