+144
-69
cmd/blup/main.go
+144
-69
cmd/blup/main.go
···
2
2
3
3
import (
4
4
"context"
5
+
"encoding/json"
5
6
"fmt"
6
7
"io"
8
+
"log/slog"
7
9
"net/http"
8
10
"os"
9
11
"path/filepath"
···
11
13
"time"
12
14
13
15
"github.com/bluesky-social/indigo/api/atproto"
16
+
"github.com/bluesky-social/indigo/atproto/atclient"
14
17
lex_util "github.com/bluesky-social/indigo/lex/util"
15
-
"github.com/bluesky-social/indigo/xrpc"
16
-
oauth "github.com/haileyok/atproto-oauth-golang"
17
18
"github.com/spf13/cobra"
18
19
"tangled.sh/evan.jarrett.net/blup/internal/auth"
20
+
"tangled.sh/evan.jarrett.net/blup/internal/clipboard"
19
21
"tangled.sh/evan.jarrett.net/blup/internal/config"
22
+
"tangled.sh/evan.jarrett.net/blup/internal/screenshot"
20
23
"tangled.sh/evan.jarrett.net/blup/internal/util"
21
24
)
22
25
···
27
30
28
31
var (
29
32
authHandle string
33
+
logLevel string
30
34
)
31
35
32
36
func main() {
33
37
var rootCmd = &cobra.Command{
34
38
Use: Name,
35
39
Short: "AT Protocol image hosting CLI",
40
+
PersistentPreRun: func(cmd *cobra.Command, args []string) {
41
+
setupLogging()
42
+
},
36
43
}
44
+
rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "info", "Log level (debug, info, warn, error)")
37
45
38
-
var authCmd = &cobra.Command{
39
-
Use: "auth",
40
-
Short: "Authenticate with AT Protocol",
46
+
var loginCmd = &cobra.Command{
47
+
Use: "login",
48
+
Short: "Log in with AT Protocol",
41
49
RunE: runAuth,
42
50
}
43
-
authCmd.Flags().StringVar(&authHandle, "handle", "", "Bluesky (ATProto) handle")
51
+
loginCmd.Flags().StringVar(&authHandle, "handle", "", "Bluesky (ATProto) handle")
44
52
45
53
var statusCmd = &cobra.Command{
46
54
Use: "status",
···
61
69
RunE: runUpload,
62
70
}
63
71
64
-
rootCmd.AddCommand(authCmd, statusCmd, logoutCmd, uploadCmd)
72
+
var captureCmd = &cobra.Command{
73
+
Use: "capture",
74
+
Short: "Take a screenshot, upload it, and copy URL to clipboard",
75
+
RunE: runCapture,
76
+
}
77
+
78
+
rootCmd.AddCommand(loginCmd, statusCmd, logoutCmd, uploadCmd, captureCmd)
65
79
66
80
var debugTokensCmd = &cobra.Command{
67
81
Use: "debug-tokens",
68
82
Short: "Debug stored tokens",
69
83
RunE: func(cmd *cobra.Command, args []string) error {
70
-
tokens, err := auth.GetStoredTokens()
84
+
ctx := context.Background()
85
+
store := auth.NewKeyringAuthStore()
86
+
sessData, err := store.GetCurrentSession(ctx)
71
87
if err != nil {
72
-
return fmt.Errorf("no tokens found: %w", err)
88
+
return fmt.Errorf("not authenticated - run 'blup login' first")
73
89
}
74
90
75
-
fmt.Printf("Has Access Token: %v\n", tokens.AccessToken)
76
-
fmt.Printf("Has Refresh Token: %v\n", tokens.RefreshToken)
77
-
fmt.Printf("Expires At: %s\n", time.Unix(tokens.ExpiresAt, 0).Format(time.RFC3339))
78
-
fmt.Printf("Needs Refresh: %v\n", tokens.NeedsRefresh())
79
-
fmt.Printf("Scope: %s\n", tokens.Scope) // Add this line
91
+
fmt.Printf("Account DID: %s\n", sessData.AccountDID)
92
+
fmt.Printf("Session ID: %s\n", sessData.SessionID)
93
+
fmt.Printf("Host URL: %s\n", sessData.HostURL)
94
+
fmt.Printf("Auth Server: %s\n", sessData.AuthServerURL)
95
+
fmt.Printf("Scopes: %v\n", sessData.Scopes)
96
+
fmt.Printf("Has Access Token: %v\n", sessData.AccessToken != "")
97
+
fmt.Printf("Has Refresh Token: %v\n", sessData.RefreshToken != "")
80
98
81
99
return nil
82
100
},
···
115
133
}
116
134
117
135
func runStatus(cmd *cobra.Command, args []string) error {
118
-
tokens, err := auth.GetStoredTokens()
136
+
ctx := context.Background()
137
+
store := auth.NewKeyringAuthStore()
138
+
sessData, err := store.GetCurrentSession(ctx)
119
139
if err != nil {
120
140
fmt.Println("Not authenticated")
121
141
return nil
122
142
}
123
143
124
-
expiresAt := time.Unix(tokens.ExpiresAt, 0)
125
144
fmt.Printf("Authenticated: Yes\n")
126
-
fmt.Printf("Token expires: %s\n", expiresAt.Format("2006-01-02 15:04:05"))
127
-
128
-
if tokens.NeedsRefresh() {
129
-
fmt.Println("Token needs refresh (expires within 7 days)")
130
-
}
145
+
fmt.Printf("Account: %s\n", sessData.AccountDID)
146
+
fmt.Printf("PDS: %s\n", sessData.HostURL)
131
147
132
148
return nil
133
149
}
134
150
135
151
func runLogout(cmd *cobra.Command, args []string) error {
136
-
if err := auth.DeleteStoredTokens(); err != nil {
152
+
cfg, err := config.LoadConfig()
153
+
if err != nil {
154
+
// No config, nothing to logout
155
+
fmt.Println("Not logged in")
156
+
return nil
157
+
}
158
+
159
+
if err := auth.Logout(cfg); err != nil {
137
160
return err
138
161
}
139
162
fmt.Println("Logged out successfully")
···
141
164
}
142
165
143
166
func runUpload(cmd *cobra.Command, args []string) error {
167
+
url, err := uploadImage(args[0])
168
+
if err != nil {
169
+
return err
170
+
}
171
+
fmt.Println(url)
172
+
return nil
173
+
}
174
+
175
+
func runCapture(cmd *cobra.Command, args []string) error {
176
+
// Take screenshot using XDG Desktop Portal
177
+
fmt.Println("Opening screenshot dialog...")
178
+
imagePath, err := screenshot.CaptureScreenshot(true)
179
+
if err != nil {
180
+
return fmt.Errorf("failed to capture screenshot: %w", err)
181
+
}
182
+
defer os.Remove(imagePath) // Clean up temp file after upload
183
+
184
+
// Upload the screenshot
185
+
url, err := uploadImage(imagePath)
186
+
if err != nil {
187
+
return err
188
+
}
189
+
190
+
// Copy to clipboard using wl-copy
191
+
if err := copyToClipboard(url); err != nil {
192
+
fmt.Fprintf(os.Stderr, "Warning: failed to copy to clipboard: %v\n", err)
193
+
}
194
+
195
+
fmt.Println(url)
196
+
return nil
197
+
}
198
+
199
+
// copyToClipboard copies text to the Wayland clipboard using native protocol
200
+
func copyToClipboard(text string) error {
201
+
return clipboard.CopyText(text)
202
+
}
203
+
204
+
// uploadImage handles the core upload logic and returns the CDN URL
205
+
func uploadImage(imagePath string) (string, error) {
144
206
// Load config
145
207
cfg, err := config.LoadConfig()
146
208
if err != nil {
147
-
fmt.Fprintf(os.Stderr, "Error loading config: %v\nTry running '%s auth'\n", err, Name)
148
-
os.Exit(1)
209
+
return "", fmt.Errorf("not authenticated, run '%s auth' first: %w", Name, err)
149
210
}
150
211
151
212
ctx := context.Background()
152
-
imagepath := args[0]
153
213
154
214
// Open file
155
-
file, err := os.Open(imagepath)
215
+
file, err := os.Open(imagePath)
156
216
if err != nil {
157
-
return fmt.Errorf("failed to open file: %w", err)
217
+
return "", fmt.Errorf("failed to open file: %w", err)
158
218
}
159
219
defer file.Close()
160
-
imagename := filepath.Base(imagepath)
220
+
imagename := filepath.Base(imagePath)
161
221
162
222
// Get file info for size
163
223
fileInfo, err := file.Stat()
164
224
if err != nil {
165
-
return fmt.Errorf("Error getting file info: %w", err)
225
+
return "", fmt.Errorf("error getting file info: %w", err)
166
226
}
167
227
168
228
fileSize := fileInfo.Size()
···
171
231
buffer := make([]byte, 512)
172
232
n, err := file.Read(buffer)
173
233
if err != nil && err != io.EOF {
174
-
return fmt.Errorf("Error reading file: %w", err)
234
+
return "", fmt.Errorf("error reading file: %w", err)
175
235
}
176
236
contentType := http.DetectContentType(buffer[:n])
177
237
178
238
// Validate it's an image
179
239
if !strings.HasPrefix(contentType, "image/") {
180
-
return fmt.Errorf("file is not an image: %s", contentType)
240
+
return "", fmt.Errorf("file is not an image: %s", contentType)
181
241
}
182
242
183
243
// Reset file pointer to beginning
184
244
_, err = file.Seek(0, 0)
185
245
if err != nil {
186
-
return fmt.Errorf("Error seeking file: %w", err)
246
+
return "", fmt.Errorf("error seeking file: %w", err)
187
247
}
188
248
189
-
tokens, err := auth.RefreshTokens(cfg)
249
+
// Get authenticated session
250
+
sess, err := auth.RefreshTokens(cfg)
190
251
if err != nil {
191
-
return err
252
+
return "", err
192
253
}
193
254
194
-
jwk, err := auth.GetStoredJWKS()
195
-
if err != nil {
196
-
return err
255
+
// Get API client from session
256
+
apiClient := sess.APIClient()
257
+
258
+
// Upload blob using APIRequest for file upload
259
+
uploadReq := atclient.NewAPIRequest("POST", "com.atproto.repo.uploadBlob", file)
260
+
uploadReq.Headers.Set("Content-Type", contentType)
261
+
// Enable retryability
262
+
uploadReq.GetBody = func() (io.ReadCloser, error) {
263
+
f, err := os.Open(imagePath)
264
+
if err != nil {
265
+
return nil, err
266
+
}
267
+
return f, nil
197
268
}
198
269
199
-
client := &oauth.XrpcClient{
200
-
UserAgent: userAgent(),
201
-
OnDpopPdsNonceChanged: func(did, newNonce string) {
202
-
tokens, _ := auth.GetStoredTokens()
203
-
if tokens != nil {
204
-
tokens.DpopAuthserverNonce = newNonce
205
-
tokens.Sub = did
206
-
auth.StoreTokens(tokens)
207
-
}
208
-
auth.RefreshTokens(cfg)
209
-
},
270
+
resp, err := apiClient.Do(ctx, uploadReq)
271
+
if err != nil {
272
+
return "", fmt.Errorf("failed to upload blob: %w", err)
210
273
}
274
+
defer resp.Body.Close()
211
275
212
-
authArgs := &oauth.XrpcAuthedRequestArgs{
213
-
Did: tokens.Sub,
214
-
AccessToken: tokens.AccessToken,
215
-
PdsUrl: cfg.PDSHost,
216
-
Issuer: cfg.AuthserverIss,
217
-
DpopPdsNonce: tokens.DpopAuthserverNonce,
218
-
DpopPrivateJwk: jwk,
276
+
if resp.StatusCode != http.StatusOK {
277
+
body, _ := io.ReadAll(resp.Body)
278
+
return "", fmt.Errorf("upload failed with status %d: %s", resp.StatusCode, string(body))
219
279
}
220
280
221
281
var out atproto.RepoUploadBlob_Output
222
-
if err := client.Do(ctx, authArgs, xrpc.Procedure, "*/*", "com.atproto.repo.uploadBlob", nil, file, &out); err != nil {
223
-
return err
282
+
if err := json.NewDecoder(resp.Body).Decode(&out); err != nil {
283
+
return "", fmt.Errorf("failed to decode upload response: %w", err)
224
284
}
225
285
286
+
// Create record
226
287
record := map[string]interface{}{
227
288
"$type": fmt.Sprintf("blue.imgs.%s.image", Name),
228
-
"blob": out.Blob, // Use the blob reference from upload
289
+
"blob": out.Blob,
229
290
"createdAt": time.Now().Format(time.RFC3339),
230
291
"expiresAt": time.Now().Add(24 * time.Hour).Format(time.RFC3339),
231
292
"filename": imagename,
···
238
299
}
239
300
240
301
reqBody := map[string]interface{}{
241
-
"repo": tokens.Sub,
302
+
"repo": sess.Data.AccountDID.String(),
242
303
"collection": record["$type"],
243
304
"record": record,
244
305
}
245
306
246
-
var record_out atproto.RepoCreateRecord_Output
247
-
if err := client.Do(ctx, authArgs, xrpc.Procedure, "application/json", "com.atproto.repo.createRecord", nil, reqBody, &record_out); err != nil {
248
-
return err
307
+
var recordOut atproto.RepoCreateRecord_Output
308
+
if err := apiClient.Post(ctx, "com.atproto.repo.createRecord", reqBody, &recordOut); err != nil {
309
+
return "", fmt.Errorf("failed to create record: %w", err)
249
310
}
250
311
251
312
// Extract blob CID for server URL
···
253
314
blobCID := blob.Ref.String()
254
315
converted, err := util.ConvertCIDBase32ToBase62(blobCID)
255
316
if err != nil {
256
-
return err
317
+
return "", err
257
318
}
258
-
compressedUrl := fmt.Sprintf("%s/%s/%s\n", CDN, cfg.Handle, converted)
259
319
260
-
fmt.Println(compressedUrl)
261
-
return nil
320
+
return fmt.Sprintf("%s/%s/%s", CDN, cfg.Handle, converted), nil
262
321
}
263
322
264
-
func userAgent() *string {
265
-
s := fmt.Sprintf("%s/1.0", Name)
266
-
return &s
323
+
func setupLogging() {
324
+
var level slog.Level
325
+
switch strings.ToLower(logLevel) {
326
+
case "debug":
327
+
level = slog.LevelDebug
328
+
case "info":
329
+
level = slog.LevelInfo
330
+
case "warn":
331
+
level = slog.LevelWarn
332
+
case "error":
333
+
level = slog.LevelError
334
+
default:
335
+
level = slog.LevelInfo
336
+
}
337
+
338
+
handler := slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
339
+
Level: level,
340
+
})
341
+
slog.SetDefault(slog.New(handler))
267
342
}
+22
-49
go.mod
+22
-49
go.mod
···
1
1
module tangled.sh/evan.jarrett.net/blup
2
2
3
-
go 1.24.4
3
+
go 1.25
4
4
5
5
require (
6
-
github.com/bluesky-social/indigo v0.0.0-20250621010046-488d1b91889b
6
+
github.com/bluesky-social/indigo v0.0.0-20251223190123-598fbf0e146e
7
7
//github.com/gen2brain/beeep v0.11.1
8
-
github.com/golang-jwt/jwt/v5 v5.2.2
9
-
github.com/haileyok/atproto-oauth-golang v0.0.3-0.20250622200753-e07caa5274a7
8
+
github.com/golang-jwt/jwt/v5 v5.2.2 // indirect
10
9
github.com/ipfs/go-cid v0.5.0
11
-
github.com/lestrrat-go/jwx/v2 v2.1.6
12
10
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
13
11
github.com/spf13/cobra v1.9.1
14
12
github.com/zalando/go-keyring v0.2.6
15
-
//golang.design/x/clipboard v0.7.1
13
+
//golang.design/x/clipboard v0.7.1
16
14
)
15
+
16
+
require github.com/godbus/dbus/v5 v5.1.0
17
17
18
18
require (
19
19
al.essio.dev/pkg/shellescape v1.6.0 // indirect
20
-
github.com/carlmjohnson/versioninfo v0.22.5 // indirect
20
+
github.com/beorn7/perks v1.0.1 // indirect
21
+
github.com/cespare/xxhash/v2 v2.3.0 // indirect
21
22
github.com/danieljoos/wincred v1.2.2 // indirect
22
-
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
23
-
github.com/felixge/httpsnoop v1.0.4 // indirect
24
-
github.com/go-logr/logr v1.4.3 // indirect
25
-
github.com/go-logr/stdr v1.2.2 // indirect
26
-
github.com/goccy/go-json v0.10.5 // indirect
27
-
github.com/godbus/dbus/v5 v5.1.0 // indirect
28
-
github.com/gogo/protobuf v1.3.2 // indirect
29
-
github.com/google/uuid v1.6.0 // indirect
30
-
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
31
-
github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
32
-
github.com/hashicorp/golang-lru v1.0.2 // indirect
23
+
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
24
+
github.com/earthboundkid/versioninfo/v2 v2.24.1 // indirect
25
+
github.com/google/go-querystring v1.1.0 // indirect
26
+
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
33
27
github.com/inconshreveable/mousetrap v1.1.0 // indirect
34
-
github.com/ipfs/bbloom v0.0.4 // indirect
35
-
github.com/ipfs/boxo v0.32.0 // indirect
36
-
github.com/ipfs/go-block-format v0.2.1 // indirect
37
-
github.com/ipfs/go-datastore v0.8.2 // indirect
38
-
github.com/ipfs/go-ipfs-blockstore v1.3.1 // indirect
39
-
github.com/ipfs/go-ipfs-ds-help v1.1.1 // indirect
40
-
github.com/ipfs/go-ipld-cbor v0.2.0 // indirect
41
-
github.com/ipfs/go-ipld-format v0.6.1 // indirect
42
-
github.com/ipfs/go-log v1.0.5 // indirect
43
-
github.com/ipfs/go-log/v2 v2.6.0 // indirect
44
-
github.com/ipfs/go-metrics-interface v0.3.0 // indirect
45
28
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
46
-
github.com/lestrrat-go/blackmagic v1.0.4 // indirect
47
-
github.com/lestrrat-go/httpcc v1.0.1 // indirect
48
-
github.com/lestrrat-go/httprc v1.0.6 // indirect
49
-
github.com/lestrrat-go/iter v1.0.2 // indirect
50
-
github.com/lestrrat-go/option v1.0.1 // indirect
51
-
github.com/mattn/go-isatty v0.0.20 // indirect
52
29
github.com/minio/sha256-simd v1.0.1 // indirect
53
30
github.com/mr-tron/base58 v1.2.0 // indirect
54
31
github.com/multiformats/go-base32 v0.1.0 // indirect
···
56
33
github.com/multiformats/go-multibase v0.2.0 // indirect
57
34
github.com/multiformats/go-multihash v0.2.3 // indirect
58
35
github.com/multiformats/go-varint v0.0.7 // indirect
59
-
github.com/opentracing/opentracing-go v1.2.0 // indirect
60
-
github.com/polydawn/refmt v0.89.1-0.20231129105047-37766d95467a // indirect
61
-
github.com/segmentio/asm v1.2.0 // indirect
36
+
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
37
+
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
38
+
github.com/prometheus/client_golang v1.22.0 // indirect
39
+
github.com/prometheus/client_model v0.6.2 // indirect
40
+
github.com/prometheus/common v0.63.0 // indirect
41
+
github.com/prometheus/procfs v0.16.1 // indirect
62
42
github.com/spaolacci/murmur3 v1.1.0 // indirect
63
43
github.com/spf13/pflag v1.0.6 // indirect
64
44
github.com/whyrusleeping/cbor-gen v0.3.1 // indirect
65
-
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
66
-
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
67
-
go.opentelemetry.io/otel v1.36.0 // indirect
68
-
go.opentelemetry.io/otel/metric v1.36.0 // indirect
69
-
go.opentelemetry.io/otel/trace v1.36.0 // indirect
70
-
go.uber.org/atomic v1.11.0 // indirect
71
-
go.uber.org/multierr v1.11.0 // indirect
72
-
go.uber.org/zap v1.27.0 // indirect
45
+
gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b // indirect
46
+
gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect
73
47
golang.org/x/crypto v0.39.0 // indirect
74
-
golang.org/x/exp/shiny v0.0.0-20250606033433-dcc06ee1d476 // indirect
75
-
golang.org/x/image v0.28.0 // indirect
76
-
golang.org/x/mobile v0.0.0-20250606033058-a2a15c67f36f // indirect
77
48
golang.org/x/sys v0.33.0 // indirect
49
+
golang.org/x/time v0.8.0 // indirect
78
50
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
51
+
google.golang.org/protobuf v1.36.6 // indirect
79
52
lukechampine.com/blake3 v1.4.1 // indirect
80
53
)
+30
-733
go.sum
+30
-733
go.sum
···
1
1
al.essio.dev/pkg/shellescape v1.6.0 h1:NxFcEqzFSEVCGN2yq7Huv/9hyCEGVa/TncnOOBBeXHA=
2
2
al.essio.dev/pkg/shellescape v1.6.0/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890=
3
-
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
4
-
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
5
-
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
6
-
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
7
-
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
8
-
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
9
-
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
10
-
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
11
-
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
12
-
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
13
-
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
14
-
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
15
-
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
16
-
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
17
-
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
18
-
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
19
-
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
20
-
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
21
-
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
22
-
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
23
-
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
24
-
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
25
-
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
26
-
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
27
-
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
28
-
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
29
-
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
30
-
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
31
-
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
32
-
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
33
-
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
34
-
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
35
-
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
36
-
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
37
-
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
38
-
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
39
-
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
40
-
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
41
-
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
42
-
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
43
-
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
44
-
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
45
-
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
46
-
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
47
-
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
48
-
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
49
-
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
50
-
github.com/bluesky-social/indigo v0.0.0-20250621010046-488d1b91889b h1:QniihTdfvYFr8oJZgltN0VyWSWa28v/0DiIVFHy6nfg=
51
-
github.com/bluesky-social/indigo v0.0.0-20250621010046-488d1b91889b/go.mod h1:8FlFpF5cIq3DQG0kEHqyTkPV/5MDQoaWLcVwza5ZPJU=
52
-
github.com/carlmjohnson/versioninfo v0.22.5 h1:O00sjOLUAFxYQjlN/bzYTuZiS0y6fWDQjMRvwtKgwwc=
53
-
github.com/carlmjohnson/versioninfo v0.22.5/go.mod h1:QT9mph3wcVfISUKd0i9sZfVrPviHuSF+cUtLjm2WSf8=
54
-
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
55
-
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
56
-
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
57
-
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
58
-
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
59
-
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
60
-
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
61
-
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
62
-
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
63
-
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
64
-
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
65
-
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
3
+
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
4
+
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
5
+
github.com/bluesky-social/indigo v0.0.0-20251223190123-598fbf0e146e h1:dEM6bfzMfkRI39GLinuhQan47HzdrkqIzJkl/zRvz8s=
6
+
github.com/bluesky-social/indigo v0.0.0-20251223190123-598fbf0e146e/go.mod h1:KIy0FgNQacp4uv2Z7xhNkV3qZiUSGuRky97s7Pa4v+o=
7
+
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
8
+
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
66
9
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
67
10
github.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0=
68
11
github.com/danieljoos/wincred v1.2.2/go.mod h1:w7w4Utbrz8lqeMbDAK0lkNJUv5sAOkFi7nd/ogr0Uh8=
69
-
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
70
-
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
71
12
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
72
13
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
73
-
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
74
-
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
75
-
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
76
-
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
77
-
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
78
-
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
79
-
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
80
-
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
81
-
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
82
-
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
83
-
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
84
-
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
85
-
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
86
-
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
87
-
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
88
-
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
89
-
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
90
-
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
91
-
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
92
-
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
93
-
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
94
-
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
95
-
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
96
-
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
97
-
github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=
98
-
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
99
-
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
100
-
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
14
+
github.com/earthboundkid/versioninfo/v2 v2.24.1 h1:SJTMHaoUx3GzjjnUO1QzP3ZXK6Ee/nbWyCm58eY3oUg=
15
+
github.com/earthboundkid/versioninfo/v2 v2.24.1/go.mod h1:VcWEooDEuyUJnMfbdTh0uFN4cfEIg+kHMuWB2CDCLjw=
101
16
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
102
17
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
103
-
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
104
-
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
105
18
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
106
19
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
107
-
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
108
-
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
109
-
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
110
-
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
111
-
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
112
-
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
113
-
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
114
-
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
115
-
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
116
-
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
117
-
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
118
-
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
119
-
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
120
-
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
121
-
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
122
-
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
123
-
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
124
-
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
125
-
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
126
-
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
127
-
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
128
-
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
129
-
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
130
-
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
131
-
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
132
-
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
133
-
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
134
-
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
135
-
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
136
-
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
137
-
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
138
-
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
139
-
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
140
-
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
141
-
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
142
-
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
143
-
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
144
-
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
145
20
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
146
-
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
147
-
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
148
-
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
149
-
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
150
21
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
151
22
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
152
-
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
153
-
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
154
-
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
155
-
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
156
-
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
157
-
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
158
-
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
159
-
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
160
-
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
161
-
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
162
-
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
163
-
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
164
-
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
165
-
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
166
-
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
167
-
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
23
+
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
24
+
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
168
25
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
169
26
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
170
-
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
171
-
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
172
-
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
173
-
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
174
-
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
175
-
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
176
-
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
177
-
github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
178
-
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
179
-
github.com/haileyok/atproto-oauth-golang v0.0.3-0.20250622200753-e07caa5274a7 h1:P3oEaumqbWobYKGRj1Ku4jdgNxMogNlrLZJ097GkKmc=
180
-
github.com/haileyok/atproto-oauth-golang v0.0.3-0.20250622200753-e07caa5274a7/go.mod h1:vVRo6BPEmWOZnYk9LtXLzBPzfkY63fUaBahA+o4h55Q=
181
-
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
182
-
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
183
-
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
184
-
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
185
-
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
186
-
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
187
-
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
188
-
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
189
-
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
190
-
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
191
-
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
192
-
github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48=
193
-
github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw=
194
-
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
195
-
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
196
-
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
197
-
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
198
-
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
199
-
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
200
-
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
201
-
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
202
-
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
203
-
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
204
-
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
205
-
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
206
-
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
207
-
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
208
-
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
209
-
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
210
-
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
211
-
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
27
+
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
28
+
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
212
29
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
213
30
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
214
-
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
215
-
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
216
-
github.com/ipfs/boxo v0.32.0 h1:rBs3P53Wt9bFW9WJwVdkzLtzYCXAj2bMjM7+1nrazZw=
217
-
github.com/ipfs/boxo v0.32.0/go.mod h1:VEtO3gOmr+sXGodalaTV9Vvsp3qVYegc4Rcu08Iw+wM=
218
-
github.com/ipfs/go-block-format v0.2.1 h1:96kW71XGNNa+mZw/MTzJrCpMhBWCrd9kBLoKm9Iip/Q=
219
-
github.com/ipfs/go-block-format v0.2.1/go.mod h1:frtvXHMQhM6zn7HvEQu+Qz5wSTj+04oEH/I+NjDgEjk=
220
31
github.com/ipfs/go-cid v0.5.0 h1:goEKKhaGm0ul11IHA7I6p1GmKz8kEYniqFopaB5Otwg=
221
32
github.com/ipfs/go-cid v0.5.0/go.mod h1:0L7vmeNXpQpUS9vt+yEARkJ8rOg43DF3iPgn4GIN0mk=
222
-
github.com/ipfs/go-datastore v0.8.2 h1:Jy3wjqQR6sg/LhyY0NIePZC3Vux19nLtg7dx0TVqr6U=
223
-
github.com/ipfs/go-datastore v0.8.2/go.mod h1:W+pI1NsUsz3tcsAACMtfC+IZdnQTnC/7VfPoJBQuts0=
224
-
github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk=
225
-
github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps=
226
-
github.com/ipfs/go-ipfs-blockstore v1.3.1 h1:cEI9ci7V0sRNivqaOr0elDsamxXFxJMMMy7PTTDQNsQ=
227
-
github.com/ipfs/go-ipfs-blockstore v1.3.1/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE=
228
-
github.com/ipfs/go-ipfs-ds-help v1.1.1 h1:B5UJOH52IbcfS56+Ul+sv8jnIV10lbjLF5eOO0C66Nw=
229
-
github.com/ipfs/go-ipfs-ds-help v1.1.1/go.mod h1:75vrVCkSdSFidJscs8n4W+77AtTpCIAdDGAwjitJMIo=
230
-
github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0=
231
-
github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn17xAKWBvs=
232
-
github.com/ipfs/go-ipld-cbor v0.2.0 h1:VHIW3HVIjcMd8m4ZLZbrYpwjzqlVUfjLM7oK4T5/YF0=
233
-
github.com/ipfs/go-ipld-cbor v0.2.0/go.mod h1:Cp8T7w1NKcu4AQJLqK0tWpd1nkgTxEVB5C6kVpLW6/0=
234
-
github.com/ipfs/go-ipld-format v0.6.1 h1:lQLmBM/HHbrXvjIkrydRXkn+gc0DE5xO5fqelsCKYOQ=
235
-
github.com/ipfs/go-ipld-format v0.6.1/go.mod h1:8TOH1Hj+LFyqM2PjSqI2/ZnyO0KlfhHbJLkbxFa61hs=
236
-
github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8=
237
-
github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo=
238
-
github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g=
239
-
github.com/ipfs/go-log/v2 v2.6.0 h1:2Nu1KKQQ2ayonKp4MPo6pXCjqw1ULc9iohRqWV5EYqg=
240
-
github.com/ipfs/go-log/v2 v2.6.0/go.mod h1:p+Efr3qaY5YXpx9TX7MoLCSEZX5boSWj9wh86P5HJa8=
241
-
github.com/ipfs/go-metrics-interface v0.3.0 h1:YwG7/Cy4R94mYDUuwsBfeziJCVm9pBMJ6q/JR9V40TU=
242
-
github.com/ipfs/go-metrics-interface v0.3.0/go.mod h1:OxxQjZDGocXVdyTPocns6cOLwHieqej/jos7H4POwoY=
243
-
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
244
-
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
245
-
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
246
-
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
247
-
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
248
-
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
249
-
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
250
-
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
251
-
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
252
33
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
253
34
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
254
-
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
255
-
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
256
-
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
257
-
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
258
-
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
259
-
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
260
-
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
261
-
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
262
-
github.com/lestrrat-go/blackmagic v1.0.4 h1:IwQibdnf8l2KoO+qC3uT4OaTWsW7tuRQXy9TRN9QanA=
263
-
github.com/lestrrat-go/blackmagic v1.0.4/go.mod h1:6AWFyKNNj0zEXQYfTMPfZrAXUWUfTIZ5ECEUEJaijtw=
264
-
github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=
265
-
github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E=
266
-
github.com/lestrrat-go/httprc v1.0.6 h1:qgmgIRhpvBqexMJjA/PmwSvhNk679oqD1RbovdCGW8k=
267
-
github.com/lestrrat-go/httprc v1.0.6/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo=
268
-
github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI=
269
-
github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4=
270
-
github.com/lestrrat-go/jwx/v2 v2.1.6 h1:hxM1gfDILk/l5ylers6BX/Eq1m/pnxe9NBwW6lVfecA=
271
-
github.com/lestrrat-go/jwx/v2 v2.1.6/go.mod h1:Y722kU5r/8mV7fYDifjug0r8FK8mZdw0K0GpJw/l8pU=
272
-
github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU=
273
-
github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
274
-
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
275
-
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
276
-
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
277
-
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
278
-
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
279
-
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
280
-
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
281
-
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
282
35
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
283
36
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
284
-
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
285
-
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
286
-
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
287
-
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
288
-
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
289
-
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
290
-
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
291
-
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
292
-
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
293
-
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
294
-
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
295
37
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
296
38
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
297
39
github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE=
···
304
46
github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM=
305
47
github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8=
306
48
github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU=
307
-
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
308
-
github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
309
-
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
310
-
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
311
-
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
312
-
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
49
+
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
50
+
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
313
51
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
314
52
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
315
-
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
316
-
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
317
-
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
318
53
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
319
54
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
320
-
github.com/polydawn/refmt v0.89.1-0.20231129105047-37766d95467a h1:cgqrm0F3zwf9IPzca7xN4w+Zy6MC9ZkPvAC8QEWa/iQ=
321
-
github.com/polydawn/refmt v0.89.1-0.20231129105047-37766d95467a/go.mod h1:ocZfO/tLSHqfScRDNTJbAJR1by4D1lewauX9OwTaPuY=
322
-
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
323
-
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
324
-
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
325
-
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
326
-
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
327
-
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
328
-
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
55
+
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
56
+
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
57
+
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
58
+
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
59
+
github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k=
60
+
github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18=
61
+
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
62
+
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
329
63
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
330
-
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
331
-
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
332
-
github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
333
-
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
334
-
github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
335
-
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
336
-
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
337
-
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
338
-
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
339
-
github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY=
340
-
github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec=
341
-
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
342
-
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
343
-
github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY=
344
-
github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60=
345
64
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
346
65
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
347
-
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
348
-
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
349
-
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
350
66
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
351
67
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
352
-
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
353
-
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
354
68
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
355
69
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
356
-
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
357
-
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
358
70
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
359
71
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
360
-
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
361
-
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
362
-
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
363
-
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
364
-
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
365
-
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
366
-
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
367
72
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
368
73
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
369
-
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
370
-
github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
371
-
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ=
372
-
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
373
74
github.com/whyrusleeping/cbor-gen v0.3.1 h1:82ioxmhEYut7LBVGhGq8xoRkXPLElVuh5mV67AFfdv0=
374
75
github.com/whyrusleeping/cbor-gen v0.3.1/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so=
375
-
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
376
-
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
377
-
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
378
-
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
379
-
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
380
-
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
381
76
github.com/zalando/go-keyring v0.2.6 h1:r7Yc3+H+Ux0+M72zacZoItR3UDxeWfKTcabvkI8ua9s=
382
77
github.com/zalando/go-keyring v0.2.6/go.mod h1:2TCrxYrbUNYfNS/Kgy/LSrkSQzZ5UPVH85RwfczwvcI=
383
-
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
384
-
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
385
-
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
386
-
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
387
-
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
388
-
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
389
-
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
390
-
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
391
-
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
392
-
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
393
-
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
394
-
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
395
-
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
396
-
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
397
-
go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
398
-
go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
399
-
go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
400
-
go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
401
-
go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
402
-
go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=
403
-
go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis=
404
-
go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=
405
-
go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
406
-
go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
407
-
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
408
-
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
409
-
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
410
-
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
411
-
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
412
-
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
413
-
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
414
-
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
415
-
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
416
-
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
417
-
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
418
-
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
419
-
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
420
-
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
421
-
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
422
-
golang.design/x/clipboard v0.7.1 h1:OEG3CmcYRBNnRwpDp7+uWLiZi3hrMRJpE9JkkkYtz2c=
423
-
golang.design/x/clipboard v0.7.1/go.mod h1:i5SiIqj0wLFw9P/1D7vfILFK0KHMk7ydE72HRrUIgkg=
424
-
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
425
-
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
426
-
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
427
-
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
428
-
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
429
-
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
430
-
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
431
-
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
432
-
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
78
+
gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b h1:CzigHMRySiX3drau9C6Q5CAbNIApmLdat5jPMqChvDA=
79
+
gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b/go.mod h1:/y/V339mxv2sZmYYR64O07VuCpdNZqCTwO8ZcouTMI8=
80
+
gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 h1:qwDnMxjkyLmAFgcfgTnfJrmYKWhHnci3GjDqcZp1M3Q=
81
+
gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02/go.mod h1:JTnUj0mpYiAsuZLmKjTx/ex3AtMowcCgnE7YNyCEP0I=
433
82
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
434
83
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
435
-
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
436
-
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
437
-
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
438
-
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
439
-
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
440
-
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
441
-
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
442
-
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
443
-
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
444
-
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
445
-
golang.org/x/exp/shiny v0.0.0-20250606033433-dcc06ee1d476 h1:Wdx0vgH5Wgsw+lF//LJKmWOJBLWX6nprsMqnf99rYDE=
446
-
golang.org/x/exp/shiny v0.0.0-20250606033433-dcc06ee1d476/go.mod h1:ygj7T6vSGhhm/9yTpOQQNvuAUFziTH7RUiH74EoE2C8=
447
-
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
448
-
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
449
-
golang.org/x/image v0.28.0 h1:gdem5JW1OLS4FbkWgLO+7ZeFzYtL3xClb97GaUzYMFE=
450
-
golang.org/x/image v0.28.0/go.mod h1:GUJYXtnGKEUgggyzh+Vxt+AviiCcyiwpsl8iQ8MvwGY=
451
-
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
452
-
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
453
-
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
454
-
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
455
-
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
456
-
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
457
-
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
458
-
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
459
-
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
460
-
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
461
-
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
462
-
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
463
-
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
464
-
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
465
-
golang.org/x/mobile v0.0.0-20250606033058-a2a15c67f36f h1:/n+PL2HlfqeSiDCuhdBbRNlGS/g2fM4OHufalHaTVG8=
466
-
golang.org/x/mobile v0.0.0-20250606033058-a2a15c67f36f/go.mod h1:ESkJ836Z6LpG6mTVAhA48LpfW/8fNR0ifStlH2axyfg=
467
-
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
468
-
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
469
-
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
470
-
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
471
-
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
472
-
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
473
-
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
474
-
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
475
-
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
476
-
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
477
-
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
478
-
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
479
-
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
480
-
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
481
-
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
482
-
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
483
-
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
484
-
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
485
-
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
486
-
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
487
-
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
488
-
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
489
-
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
490
-
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
491
-
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
492
-
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
493
-
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
494
-
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
495
-
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
496
-
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
497
-
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
498
-
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
499
-
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
500
-
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
501
-
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
502
-
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
503
-
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
504
-
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
505
-
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
506
-
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
507
-
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
508
-
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
509
-
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
510
-
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
511
-
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
512
-
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
513
-
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
514
-
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
515
-
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
516
-
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
517
-
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
518
-
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
519
-
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
520
-
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
521
-
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
522
-
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
523
-
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
524
-
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
525
-
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
526
-
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
527
-
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
528
-
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
529
-
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
530
-
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
531
-
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
532
-
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
533
-
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
534
-
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
535
-
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
536
-
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
537
-
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
538
-
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
539
-
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
540
-
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
541
-
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
542
-
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
543
-
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
544
-
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
545
-
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
546
-
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
547
-
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
548
-
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
549
-
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
550
-
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
551
-
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
552
-
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
553
-
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
554
-
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
555
-
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
556
-
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
557
-
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
558
-
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
559
-
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
560
-
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
561
-
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
562
-
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
563
-
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
564
-
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
565
-
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
566
-
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
567
-
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
568
-
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
569
-
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
570
-
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
571
-
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
572
-
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
573
-
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
574
-
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
575
-
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
576
-
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
577
-
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
578
-
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
579
-
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
580
-
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
581
-
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
582
-
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
583
-
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
584
-
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
585
-
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
586
-
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
587
-
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
588
-
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
589
84
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
590
-
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
591
-
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
592
85
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
593
86
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
594
-
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
595
-
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
596
-
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
597
-
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
598
-
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
599
-
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
600
-
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
601
-
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
602
-
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
603
-
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
604
-
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
605
-
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
606
-
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
607
-
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
608
-
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
609
-
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
610
-
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
611
-
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
612
-
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
613
-
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
614
-
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
615
-
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
616
-
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
617
-
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
618
-
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
619
-
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
620
-
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
621
-
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
622
-
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
623
-
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
624
-
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
625
-
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
626
-
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
627
-
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
628
-
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
629
-
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
630
-
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
631
-
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
632
-
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
633
-
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
634
-
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
635
-
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
636
-
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
637
-
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
638
-
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
639
-
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
640
-
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
641
-
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
642
-
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
643
-
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
644
-
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
645
-
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
646
-
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
647
-
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
648
-
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
649
-
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
650
-
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
651
-
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
652
-
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
653
-
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
654
-
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
655
-
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
656
-
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
657
-
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
658
-
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
659
-
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
660
-
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
661
-
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
662
-
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
663
-
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
664
-
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
665
-
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
666
-
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
667
-
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
668
-
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
669
-
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
87
+
golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg=
88
+
golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
670
89
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
671
-
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
672
90
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY=
673
91
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
674
-
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
675
-
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
676
-
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
677
-
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
678
-
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
679
-
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
680
-
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
681
-
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
682
-
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
683
-
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
684
-
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
685
-
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
686
-
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
687
-
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
688
-
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
689
-
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
690
-
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
691
-
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
692
-
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
693
-
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
694
-
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
695
-
google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
696
-
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
697
-
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
698
-
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
699
-
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
700
-
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
701
-
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
702
-
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
703
-
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
704
-
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
705
-
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
706
-
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
707
-
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
708
-
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
709
-
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
710
-
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
711
-
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
712
-
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
713
-
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
714
-
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
715
-
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
716
-
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
717
-
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
718
-
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
719
-
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
720
-
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
721
-
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
722
-
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
723
-
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
724
-
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
725
-
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
726
-
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
727
-
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
728
-
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
729
-
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
730
-
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
731
-
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
732
-
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
733
-
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
734
-
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
735
-
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
736
-
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
737
-
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
738
-
google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
739
-
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
740
-
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
741
-
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
742
-
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
743
-
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
744
-
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
745
-
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
746
-
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
747
-
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
748
-
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
749
-
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
750
-
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
751
-
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
752
-
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
753
-
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
754
-
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
755
-
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
756
-
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
757
-
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
758
-
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
759
-
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
760
-
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
761
-
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
762
-
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
763
-
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
764
-
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
765
-
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
766
-
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
767
-
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
768
-
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
769
-
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
770
-
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
771
-
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
772
-
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
773
-
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
774
-
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
775
-
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
92
+
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
93
+
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
776
94
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
777
-
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
778
-
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
779
-
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
780
-
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
781
-
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
782
-
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
783
-
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
784
-
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
785
-
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
786
-
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
787
-
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
788
95
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
789
96
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
790
-
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
791
-
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
792
-
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
793
-
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
794
-
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
795
-
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
796
-
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
797
97
lukechampine.com/blake3 v1.4.1 h1:I3Smz7gso8w4/TunLKec6K2fn+kyKtDxr/xcQEN84Wg=
798
98
lukechampine.com/blake3 v1.4.1/go.mod h1:QFosUxmjB8mnrWFSNwKmvxHpfY72bmD2tQ0kBMM3kwo=
799
-
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
800
-
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
801
-
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
+2
-2
internal/auth/client-metadata.json
+2
-2
internal/auth/client-metadata.json
···
1
1
{
2
-
"client_id": "https://blup.imgs.blue/oauth/client-metadata.json",
2
+
"client_id": "https://blup.imgs.blue/oauth-client-metadata.json",
3
3
"client_name": "Blup",
4
4
"client_uri": "https://blup.imgs.blue",
5
5
"grant_types": [
6
6
"authorization_code",
7
7
"refresh_token"
8
8
],
9
-
"scope": "atproto transition:generic",
9
+
"scope": "atproto repo:blue.imgs.blup.image blob:image/*",
10
10
"response_types": [
11
11
"code"
12
12
],
+20
-2
internal/auth/metadata.go
+20
-2
internal/auth/metadata.go
···
3
3
import (
4
4
_ "embed"
5
5
"encoding/json"
6
+
"strings"
7
+
8
+
"github.com/bluesky-social/indigo/atproto/auth/oauth"
6
9
)
7
10
8
11
// NOTE: if the server-side metadata changes, this file will also need to change.
12
+
//
9
13
//go:embed client-metadata.json
10
14
var metadataJson []byte
15
+
11
16
type ClientMetadata struct {
12
17
ClientID string `json:"client_id"`
13
18
ClientName string `json:"client_name"`
···
23
28
TokenEndpointAuthMethod string `json:"token_endpoint_auth_method"`
24
29
TokenEndpointAuthSigningAlg string `json:"token_endpoint_auth_signing_alg"`
25
30
}
26
-
27
31
28
32
func GetClientMetadata() ClientMetadata {
29
33
var cm ClientMetadata
30
34
json.Unmarshal(metadataJson, &cm)
31
35
return cm
32
-
}
36
+
}
37
+
38
+
// GetClientConfig returns the OAuth client configuration for indigo
39
+
func GetClientConfig() oauth.ClientConfig {
40
+
metadata := GetClientMetadata()
41
+
42
+
// Split space-separated scopes from metadata into slice
43
+
scopes := strings.Fields(metadata.Scope)
44
+
45
+
return oauth.NewPublicConfig(
46
+
metadata.ClientID,
47
+
metadata.RedirectURIs[0],
48
+
scopes,
49
+
)
50
+
}
+183
-310
internal/auth/oauth.go
+183
-310
internal/auth/oauth.go
···
5
5
"context"
6
6
"encoding/json"
7
7
"fmt"
8
-
"io"
9
-
"net"
8
+
"log/slog"
10
9
"net/http"
11
10
"net/url"
12
11
"strings"
13
12
"time"
14
13
15
-
"github.com/bluesky-social/indigo/atproto/syntax"
16
-
"github.com/golang-jwt/jwt/v5"
17
-
oauth "github.com/haileyok/atproto-oauth-golang"
18
-
oauth_helpers "github.com/haileyok/atproto-oauth-golang/helpers"
19
-
"github.com/lestrrat-go/jwx/v2/jwk"
14
+
"github.com/bluesky-social/indigo/atproto/auth/oauth"
20
15
"github.com/pkg/browser"
21
16
"tangled.sh/evan.jarrett.net/blup/internal/config"
22
17
)
23
18
24
19
type OAuthFlow struct {
25
-
client *oauth.Client
20
+
app *oauth.ClientApp
26
21
cfg *config.Config
27
-
jwk jwk.Key
28
-
server *http.Server
29
-
authSuccess chan *StoredTokens
22
+
store *KeyringAuthStore
23
+
authSuccess chan *oauth.ClientSessionData
30
24
authError chan error
31
25
savedState string
32
-
issuer string
33
-
nonce string
34
-
verifier string
35
26
}
36
27
37
28
func NewOAuthFlow(cfg *config.Config) (*OAuthFlow, error) {
38
-
// Get or generate JWKS
39
-
key, err := GetStoredJWKS()
40
-
if err != nil {
41
-
// Generate new key if none exists
42
-
var prefix *string
43
-
key, err = oauth_helpers.GenerateKey(prefix)
44
-
if err != nil {
45
-
return nil, fmt.Errorf("failed to generate key: %w", err)
46
-
}
47
-
48
-
// Store the new key
49
-
if err := StoreJWKS(key); err != nil {
50
-
return nil, fmt.Errorf("failed to store JWKS: %w", err)
51
-
}
52
-
}
29
+
store := NewKeyringAuthStore()
30
+
clientConfig := GetClientConfig()
53
31
54
-
clientMetadata := GetClientMetadata()
32
+
// Debug: show what we're requesting
33
+
metadata := GetClientMetadata()
34
+
slog.Debug("OAuth config",
35
+
"client_id", clientConfig.ClientID,
36
+
"callback_url", clientConfig.CallbackURL,
37
+
"scopes", clientConfig.Scopes,
38
+
"scope_raw", metadata.Scope,
39
+
)
55
40
56
-
// Create OAuth client
57
-
clientConfig := oauth.ClientArgs{
58
-
ClientJwk: key,
59
-
ClientId: clientMetadata.ClientID,
60
-
RedirectUri: clientMetadata.RedirectURIs[0],
61
-
}
62
-
63
-
client, err := oauth.NewClient(clientConfig)
64
-
if err != nil {
65
-
return nil, fmt.Errorf("failed to create OAuth client: %w", err)
66
-
}
41
+
app := oauth.NewClientApp(&clientConfig, store)
67
42
68
43
return &OAuthFlow{
69
-
client: client,
44
+
app: app,
70
45
cfg: cfg,
71
-
jwk: key,
72
-
authSuccess: make(chan *StoredTokens, 1),
46
+
store: store,
47
+
authSuccess: make(chan *oauth.ClientSessionData, 1),
73
48
authError: make(chan error, 1),
74
49
}, nil
75
50
}
76
51
77
-
func (f *OAuthFlow) Authenticate() (*StoredTokens, error) {
52
+
func (f *OAuthFlow) Authenticate() (*oauth.ClientSessionData, error) {
78
53
ctx := context.Background()
79
-
var authServer, did, pdsHost string
80
-
var err error
81
-
82
-
// Initialize authorization
83
54
cfg := f.cfg
84
55
85
-
if cfg.Handle != "" {
86
-
did, err = ResolveHandle(ctx, cfg.Handle)
87
-
if err != nil {
88
-
return nil, err
89
-
}
90
-
pdsHost, err = ResolveService(ctx, did)
91
-
if err != nil {
92
-
return nil, err
93
-
}
94
-
authServer, err = f.client.ResolvePdsAuthServer(ctx, pdsHost)
95
-
if err != nil {
96
-
return nil, err
97
-
}
98
-
cfg.PDSHost = pdsHost
99
-
cfg.AuthserverIss = authServer
100
-
config.SaveConfig(cfg)
101
-
102
-
} else {
103
-
authServer = cfg.AuthserverIss
56
+
if cfg.Handle == "" {
57
+
return nil, fmt.Errorf("handle is required")
104
58
}
105
59
106
-
meta, err := f.client.FetchAuthServerMetadata(ctx, authServer)
60
+
// Start the OAuth flow - this handles handle resolution, PAR, etc.
61
+
// Note: StartAuthFlow internally calls SaveAuthRequestInfo which stores the state
62
+
redirectURL, err := f.app.StartAuthFlow(ctx, cfg.Handle)
107
63
if err != nil {
108
-
return nil, err
64
+
return nil, fmt.Errorf("failed to start auth flow: %w", err)
109
65
}
110
66
111
-
clientMetadata := GetClientMetadata()
112
-
113
-
parResp, err := f.client.SendParAuthRequest(ctx, authServer, meta, cfg.Handle, clientMetadata.Scope, f.jwk)
67
+
// Get the state from our store (saved by SaveAuthRequestInfo during StartAuthFlow)
68
+
f.savedState, err = f.store.GetPendingAuthState()
114
69
if err != nil {
115
-
return nil, err
70
+
return nil, fmt.Errorf("failed to get auth state: %w", err)
116
71
}
117
-
118
-
f.savedState = parResp.State
119
-
f.issuer = meta.Issuer
120
-
f.verifier = parResp.PkceVerifier
121
-
f.nonce = parResp.DpopAuthserverNonce
122
-
123
-
authUrl, _ := url.Parse(meta.AuthorizationEndpoint)
124
-
authUrl.RawQuery = fmt.Sprintf("client_id=%s&request_uri=%s", url.QueryEscape(clientMetadata.ClientID), parResp.RequestUri)
72
+
slog.Debug("OAuth state retrieved", "state", f.savedState)
125
73
126
74
go f.waitForAuthSSE()
127
75
128
76
// Open browser to authorization URL
129
77
fmt.Printf("Opening browser for authentication...\n")
130
-
if err := browser.OpenURL(authUrl.String()); err != nil {
78
+
if err := browser.OpenURL(redirectURL); err != nil {
131
79
fmt.Printf("Failed to open browser automatically.\n")
132
-
fmt.Printf("Please open this URL manually:\n%s\n", authUrl)
80
+
fmt.Printf("Please open this URL manually:\n%s\n", redirectURL)
133
81
}
134
82
135
83
// Wait for callback
136
84
fmt.Println("Waiting for authentication...")
137
85
138
86
select {
139
-
case tokens := <-f.authSuccess:
87
+
case sess := <-f.authSuccess:
140
88
fmt.Println("Authentication successful!")
141
-
return tokens, nil
89
+
90
+
// Save as current session
91
+
if err := f.store.SetCurrentSession(ctx, sess); err != nil {
92
+
return nil, fmt.Errorf("failed to save current session: %w", err)
93
+
}
94
+
95
+
// Update config with PDS host
96
+
cfg.PDSHost = sess.HostURL
97
+
cfg.AuthserverIss = sess.AuthServerURL
98
+
config.SaveConfig(cfg)
99
+
100
+
return sess, nil
142
101
case err := <-f.authError:
143
102
return nil, fmt.Errorf("authentication failed: %w", err)
144
103
case <-time.After(5 * time.Minute):
···
146
105
}
147
106
}
148
107
149
-
func (f *OAuthFlow) waitForAuthSSE() (string, error) {
108
+
func (f *OAuthFlow) waitForAuthSSE() {
150
109
clientMetadata := GetClientMetadata()
151
-
req, err := http.NewRequest("GET",
152
-
fmt.Sprintf("%s/oauth/events?session=%s", clientMetadata.ClientURI, f.savedState),
153
-
nil)
154
-
if err != nil {
155
-
f.authError <- err
156
-
}
110
+
sseURL := fmt.Sprintf("%s/oauth/events?session=%s", clientMetadata.ClientURI, f.savedState)
111
+
slog.Debug("SSE connecting", "url", sseURL)
157
112
158
-
req.Header.Set("Accept", "text/event-stream")
159
-
req.Header.Set("Cache-Control", "no-cache")
113
+
req, err := http.NewRequest("GET", sseURL, nil)
114
+
if err != nil {
115
+
f.authError <- err
116
+
return
117
+
}
160
118
161
-
client := &http.Client{Timeout: 5 * time.Minute}
162
-
resp, err := client.Do(req)
163
-
if err != nil {
164
-
f.authError <- err
165
-
}
166
-
defer resp.Body.Close()
119
+
req.Header.Set("Accept", "text/event-stream")
120
+
req.Header.Set("Cache-Control", "no-cache")
167
121
168
-
reader := bufio.NewReader(resp.Body)
122
+
client := &http.Client{Timeout: 5 * time.Minute}
123
+
resp, err := client.Do(req)
124
+
if err != nil {
125
+
slog.Debug("SSE connection error", "error", err)
126
+
f.authError <- err
127
+
return
128
+
}
129
+
defer resp.Body.Close()
130
+
131
+
slog.Debug("SSE connected", "status", resp.StatusCode)
132
+
reader := bufio.NewReader(resp.Body)
133
+
134
+
for {
135
+
line, err := reader.ReadString('\n')
136
+
if err != nil {
137
+
slog.Debug("SSE read error", "error", err)
138
+
f.authError <- err
139
+
return
140
+
}
169
141
170
-
for {
171
-
line, err := reader.ReadString('\n')
172
-
if err != nil {
173
-
f.authError <- err
174
-
}
142
+
line = strings.TrimSpace(line)
143
+
if line != "" && !strings.HasPrefix(line, ":") {
144
+
slog.Debug("SSE received", "line", line)
145
+
}
175
146
176
-
if strings.HasPrefix(line, "event: auth-complete") {
177
-
// Read data line
178
-
dataLine, _ := reader.ReadString('\n')
179
-
if strings.HasPrefix(dataLine, "data: ") {
180
-
data := strings.TrimPrefix(dataLine, "data: ")
181
-
var authData struct {
182
-
Code string `json:"code"`
183
-
Iss string `json:"iss"`
147
+
if strings.HasPrefix(line, "event: auth-complete") {
148
+
// Read data line
149
+
dataLine, _ := reader.ReadString('\n')
150
+
slog.Debug("SSE auth data", "data", dataLine)
151
+
if after, ok := strings.CutPrefix(dataLine, "data: "); ok {
152
+
data := after
153
+
var authData struct {
154
+
Code string `json:"code"`
155
+
Iss string `json:"iss"`
184
156
State string `json:"state"`
185
-
}
186
-
json.Unmarshal([]byte(data), &authData)
187
-
f.handleCallback(req.Context(), authData.Code, authData.Iss, authData.State)
188
-
}
189
-
}
190
-
}
157
+
}
158
+
if err := json.Unmarshal([]byte(data), &authData); err != nil {
159
+
f.authError <- fmt.Errorf("failed to parse auth data: %w", err)
160
+
return
161
+
}
162
+
slog.Debug("SSE auth complete", "iss", authData.Iss, "state", authData.State)
163
+
f.handleCallback(req.Context(), authData.Code, authData.Iss, authData.State)
164
+
return
165
+
}
166
+
}
167
+
}
191
168
}
192
169
193
170
func (f *OAuthFlow) handleCallback(ctx context.Context, code, iss, state string) {
194
-
// Get authorization code from query params
195
171
if state == "" || iss == "" || code == "" {
196
172
f.authError <- fmt.Errorf("request missing needed parameters")
173
+
return
197
174
}
198
175
199
-
if state != f.savedState {
200
-
f.authError <- fmt.Errorf("session state does not match response state")
201
-
}
202
-
203
-
if iss != f.issuer {
204
-
f.authError <- fmt.Errorf("incoming iss did not match authserver iss")
205
-
}
176
+
// Build URL values for ProcessCallback
177
+
params := url.Values{}
178
+
params.Set("code", code)
179
+
params.Set("iss", iss)
180
+
params.Set("state", state)
206
181
207
-
initialTokenResp, err := f.client.InitialTokenRequest(ctx, code, iss, f.verifier, f.nonce, f.jwk)
182
+
// ProcessCallback handles token exchange and session creation
183
+
sess, err := f.app.ProcessCallback(ctx, params)
208
184
if err != nil {
209
-
f.authError <- err
185
+
f.authError <- fmt.Errorf("failed to process callback: %w", err)
186
+
return
210
187
}
211
188
212
-
if initialTokenResp.Scope != GetClientMetadata().Scope {
213
-
f.authError <- fmt.Errorf("did not receive correct scopes from token request")
214
-
}
215
-
216
-
// Store tokens
217
-
tokens, err := StoreTokensFromLibrary(initialTokenResp)
218
-
if err != nil {
219
-
f.authError <- fmt.Errorf("failed to store tokens: %w", err)
220
-
}
221
-
222
-
// Send code through channel
223
-
f.authSuccess <- tokens
189
+
f.authSuccess <- sess
224
190
}
225
191
226
-
// RefreshTokens refreshes the access token using the stored refresh token
227
-
func RefreshTokens(cfg *config.Config) (*StoredTokens, error) {
228
-
// Check if we have valid tokens
229
-
tokens, _ := GetStoredTokens()
192
+
// GetSession retrieves the current session, refreshing tokens if needed
193
+
func GetSession(cfg *config.Config) (*oauth.ClientSession, error) {
194
+
ctx := context.Background()
195
+
store := NewKeyringAuthStore()
230
196
231
-
flow, err := NewOAuthFlow(cfg)
197
+
// Check for current session
198
+
sessData, err := store.GetCurrentSession(ctx)
232
199
if err != nil {
233
-
return nil, err
234
-
}
235
-
var newTokens *oauth.TokenResponse
236
-
237
-
if tokens == nil {
238
-
return flow.Authenticate()
239
-
}
240
-
if tokens.NeedsRefresh() {
241
-
ctx := context.Background()
242
-
newTokens, err = flow.client.RefreshTokenRequest(ctx, tokens.RefreshToken, cfg.AuthserverIss, tokens.DpopAuthserverNonce, flow.jwk)
243
-
244
-
if err != nil {
245
-
return nil, fmt.Errorf("failed to refresh tokens: %w", err)
246
-
}
247
-
return StoreTokensFromLibrary(newTokens)
200
+
return nil, fmt.Errorf("no active session")
248
201
}
249
202
250
-
return tokens, nil
251
-
}
203
+
clientConfig := GetClientConfig()
204
+
app := oauth.NewClientApp(&clientConfig, store)
252
205
253
-
func GetPDSFromToken(accessToken string) (string, error) {
254
-
// Parse without verification (we just need to read claims)
255
-
token, _, err := new(jwt.Parser).ParseUnverified(accessToken, jwt.MapClaims{})
206
+
// Resume the session
207
+
sess, err := app.ResumeSession(ctx, sessData.AccountDID, sessData.SessionID)
256
208
if err != nil {
257
-
return "", fmt.Errorf("failed to parse JWT: %w", err)
209
+
return nil, fmt.Errorf("failed to resume session: %w", err)
258
210
}
259
211
260
-
claims, ok := token.Claims.(jwt.MapClaims)
261
-
if !ok {
262
-
return "", fmt.Errorf("failed to get claims")
263
-
}
264
-
265
-
// Extract the 'aud' field
266
-
aud, ok := claims["aud"].(string)
267
-
if !ok {
268
-
return "", fmt.Errorf("'aud' field not found or not a string")
269
-
}
270
-
271
-
// Convert did:web:... to https://...
272
-
if after, ok0 :=strings.CutPrefix(aud, "did:web:"); ok0 {
273
-
pdsHost := after
274
-
return "https://" + pdsHost, nil
275
-
}
276
-
277
-
return "", fmt.Errorf("unexpected 'aud' format: %s", aud)
212
+
return sess, nil
278
213
}
279
214
280
-
func ResolveHandle(ctx context.Context, handle string) (string, error) {
281
-
var did string
215
+
// RefreshTokens refreshes the access token if needed and returns the session
216
+
func RefreshTokens(cfg *config.Config) (*oauth.ClientSession, error) {
217
+
ctx := context.Background()
218
+
store := NewKeyringAuthStore()
282
219
283
-
_, err := syntax.ParseHandle(handle)
284
-
if err != nil {
285
-
return "", err
286
-
}
287
-
288
-
recs, err := net.LookupTXT(fmt.Sprintf("_atproto.%s", handle))
289
-
if err == nil {
290
-
for _, rec := range recs {
291
-
if strings.HasPrefix(rec, "did=") {
292
-
did = strings.Split(rec, "did=")[1]
293
-
break
294
-
}
295
-
}
296
-
}
297
-
298
-
// Try external DNS if system DNS failed or returned no DID
299
-
if did == "" {
300
-
externalDNS := []string{"8.8.8.8"}
301
-
for _, dnsServer := range externalDNS {
302
-
externalDID, err := lookupTXTExternal(fmt.Sprintf("_atproto.%s", handle), dnsServer)
303
-
if err == nil && externalDID != "" {
304
-
did = externalDID
305
-
break
306
-
}
307
-
}
308
-
}
309
-
310
-
if did == "" {
311
-
req, err := http.NewRequestWithContext(
312
-
ctx,
313
-
"GET",
314
-
fmt.Sprintf("https://%s/.well-known/atproto-did", handle),
315
-
nil,
316
-
)
220
+
// Check for legacy tokens and migrate
221
+
if HasLegacyTokens() {
222
+
DeleteLegacyTokens()
223
+
fmt.Println("Your stored credentials are from an older version.")
224
+
fmt.Println("Please re-authenticate.")
225
+
// Trigger new auth flow
226
+
flow, err := NewOAuthFlow(cfg)
317
227
if err != nil {
318
-
return "", err
228
+
return nil, err
319
229
}
320
-
321
-
resp, err := http.DefaultClient.Do(req)
230
+
sess, err := flow.Authenticate()
322
231
if err != nil {
323
-
return "", err
232
+
return nil, err
324
233
}
325
-
defer resp.Body.Close()
326
-
327
-
if resp.StatusCode != http.StatusOK {
328
-
io.Copy(io.Discard, resp.Body)
329
-
return "", fmt.Errorf("unable to resolve handle")
330
-
}
234
+
// Resume the session to return a ClientSession
235
+
clientConfig := GetClientConfig()
236
+
app := oauth.NewClientApp(&clientConfig, store)
237
+
return app.ResumeSession(ctx, sess.AccountDID, sess.SessionID)
238
+
}
331
239
332
-
b, err := io.ReadAll(resp.Body)
240
+
// Check for current session
241
+
sessData, err := store.GetCurrentSession(ctx)
242
+
if err != nil {
243
+
// No session, need to authenticate
244
+
flow, err := NewOAuthFlow(cfg)
333
245
if err != nil {
334
-
return "", err
246
+
return nil, err
335
247
}
336
-
337
-
maybeDid := string(b)
338
-
339
-
if _, err := syntax.ParseDID(maybeDid); err != nil {
340
-
return "", fmt.Errorf("unable to resolve handle")
248
+
sess, err := flow.Authenticate()
249
+
if err != nil {
250
+
return nil, err
341
251
}
342
-
343
-
did = maybeDid
344
-
}
345
-
346
-
return did, nil
347
-
}
348
-
349
-
func lookupTXTExternal(domain, dnsServer string) (string, error) {
350
-
resolver := &net.Resolver{
351
-
PreferGo: true,
352
-
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
353
-
d := net.Dialer{
354
-
Timeout: 5 * time.Second,
355
-
}
356
-
return d.DialContext(ctx, network, dnsServer+":53")
357
-
},
252
+
// Resume the session to return a ClientSession
253
+
clientConfig := GetClientConfig()
254
+
app := oauth.NewClientApp(&clientConfig, store)
255
+
return app.ResumeSession(ctx, sess.AccountDID, sess.SessionID)
358
256
}
359
257
360
-
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
361
-
defer cancel()
258
+
clientConfig := GetClientConfig()
259
+
app := oauth.NewClientApp(&clientConfig, store)
362
260
363
-
recs, err := resolver.LookupTXT(ctx, domain)
261
+
// Resume the session - this will auto-refresh tokens on 401
262
+
sess, err := app.ResumeSession(ctx, sessData.AccountDID, sessData.SessionID)
364
263
if err != nil {
365
-
return "", err
366
-
}
367
-
368
-
for _, rec := range recs {
369
-
if strings.HasPrefix(rec, "did=") {
370
-
return strings.Split(rec, "did=")[1], nil
264
+
// Session invalid, need to re-authenticate
265
+
flow, err := NewOAuthFlow(cfg)
266
+
if err != nil {
267
+
return nil, err
268
+
}
269
+
newSess, err := flow.Authenticate()
270
+
if err != nil {
271
+
return nil, err
371
272
}
273
+
return app.ResumeSession(ctx, newSess.AccountDID, newSess.SessionID)
372
274
}
373
275
374
-
return "", nil
276
+
return sess, nil
375
277
}
376
278
377
-
func ResolveService(ctx context.Context, did string) (string, error) {
378
-
type Identity struct {
379
-
Service []struct {
380
-
ID string `json:"id"`
381
-
Type string `json:"type"`
382
-
ServiceEndpoint string `json:"serviceEndpoint"`
383
-
} `json:"service"`
384
-
}
279
+
// Logout revokes tokens and clears the session
280
+
func Logout(cfg *config.Config) error {
281
+
ctx := context.Background()
282
+
store := NewKeyringAuthStore()
385
283
386
-
var ustr string
387
-
if strings.HasPrefix(did, "did:plc:") {
388
-
ustr = fmt.Sprintf("https://plc.directory/%s", did)
389
-
} else if strings.HasPrefix(did, "did:web:") {
390
-
ustr = fmt.Sprintf("https://%s/.well-known/did.json", strings.TrimPrefix(did, "did:web:"))
391
-
} else {
392
-
return "", fmt.Errorf("did was not a supported did type")
393
-
}
394
-
395
-
req, err := http.NewRequestWithContext(ctx, "GET", ustr, nil)
284
+
sessData, err := store.GetCurrentSession(ctx)
396
285
if err != nil {
397
-
return "", err
286
+
// No session to logout
287
+
return nil
398
288
}
399
289
400
-
resp, err := http.DefaultClient.Do(req)
401
-
if err != nil {
402
-
return "", err
403
-
}
404
-
defer resp.Body.Close()
290
+
clientConfig := GetClientConfig()
291
+
app := oauth.NewClientApp(&clientConfig, store)
405
292
406
-
if resp.StatusCode != 200 {
407
-
io.Copy(io.Discard, resp.Body)
408
-
return "", fmt.Errorf("could not find identity in plc registry")
409
-
}
410
-
411
-
var identity Identity
412
-
if err := json.NewDecoder(resp.Body).Decode(&identity); err != nil {
413
-
return "", err
414
-
}
415
-
416
-
var service string
417
-
for _, svc := range identity.Service {
418
-
if svc.ID == "#atproto_pds" {
419
-
service = svc.ServiceEndpoint
420
-
}
293
+
// Logout revokes tokens and deletes session
294
+
if err := app.Logout(ctx, sessData.AccountDID, sessData.SessionID); err != nil {
295
+
// Log but don't fail - just clear local state
296
+
fmt.Printf("Warning: failed to revoke tokens: %v\n", err)
421
297
}
422
298
423
-
if service == "" {
424
-
return "", fmt.Errorf("could not find atproto_pds service in identity services")
425
-
}
426
-
427
-
return service, nil
299
+
// Clear current session reference
300
+
return store.ClearCurrentSession()
428
301
}
+116
-67
internal/auth/storage.go
+116
-67
internal/auth/storage.go
···
1
1
package auth
2
2
3
3
import (
4
+
"context"
4
5
"encoding/json"
5
-
"time"
6
+
"fmt"
6
7
7
-
oauth "github.com/haileyok/atproto-oauth-golang"
8
-
"github.com/lestrrat-go/jwx/v2/jwk"
8
+
"github.com/bluesky-social/indigo/atproto/auth/oauth"
9
+
"github.com/bluesky-social/indigo/atproto/syntax"
9
10
"github.com/zalando/go-keyring"
10
11
)
11
12
12
13
const (
13
-
keyringService = "blup"
14
-
keyringUser = "oauth-tokens"
15
-
keyringJWKS = "oauth-jwks" // Separate key for JWKS
14
+
keyringService = "blup"
15
+
currentSessionKey = "current-session"
16
+
sessionKeyPrefix = "session:"
17
+
authRequestPrefix = "auth-request:"
18
+
pendingAuthStateKey = "pending-auth-state"
19
+
legacyTokensKey = "oauth-tokens"
20
+
legacyJWKSKey = "oauth-jwks"
16
21
)
17
22
18
-
type StoredTokens struct {
19
-
DpopAuthserverNonce string `json:"nonce"`
20
-
AccessToken string `json:"access_token"`
21
-
RefreshToken string `json:"refresh_token"`
22
-
ExpiresAt int64 `json:"expires_at"`
23
-
Scope string `json:"scope"`
24
-
Sub string `json:"sub"`
25
-
TokenType string `json:"token_type"`
23
+
// KeyringAuthStore implements oauth.ClientAuthStore using the system keyring
24
+
type KeyringAuthStore struct{}
25
+
26
+
func NewKeyringAuthStore() *KeyringAuthStore {
27
+
return &KeyringAuthStore{}
26
28
}
27
29
28
-
// StoreJWKS stores the private key separately
29
-
func StoreJWKS(key jwk.Key) error {
30
-
// Convert the key to JSON
31
-
data, err := json.Marshal(key)
32
-
if err != nil {
33
-
return err
34
-
}
35
-
36
-
return keyring.Set(keyringService, keyringJWKS, string(data))
30
+
// sessionKey creates the keyring key for a session
31
+
func sessionKey(did syntax.DID, sessionID string) string {
32
+
return fmt.Sprintf("%s%s:%s", sessionKeyPrefix, did.String(), sessionID)
37
33
}
38
34
39
-
// GetStoredJWKS retrieves the stored private key
40
-
func GetStoredJWKS() (jwk.Key, error) {
41
-
data, err := keyring.Get(keyringService, keyringJWKS)
35
+
// GetSession retrieves a session from the keyring
36
+
func (s *KeyringAuthStore) GetSession(ctx context.Context, did syntax.DID, sessionID string) (*oauth.ClientSessionData, error) {
37
+
data, err := keyring.Get(keyringService, sessionKey(did, sessionID))
42
38
if err != nil {
43
39
return nil, err
44
40
}
45
41
46
-
// Parse the key from JSON
47
-
key, err := jwk.ParseKey([]byte(data))
48
-
if err != nil {
42
+
var sess oauth.ClientSessionData
43
+
if err := json.Unmarshal([]byte(data), &sess); err != nil {
49
44
return nil, err
50
45
}
51
46
52
-
return key, nil
47
+
return &sess, nil
53
48
}
54
49
55
-
func StoreTokensFromLibrary(tokens *oauth.TokenResponse) (*StoredTokens, error) {
56
-
stored := &StoredTokens{
57
-
DpopAuthserverNonce: tokens.DpopAuthserverNonce,
58
-
AccessToken: tokens.AccessToken,
59
-
RefreshToken: tokens.RefreshToken,
60
-
ExpiresAt: time.Now().Unix() + int64(tokens.ExpiresIn),
61
-
Scope: tokens.Scope,
62
-
Sub: tokens.Sub,
63
-
TokenType: tokens.TokenType,
50
+
// SaveSession stores a session in the keyring
51
+
func (s *KeyringAuthStore) SaveSession(ctx context.Context, sess oauth.ClientSessionData) error {
52
+
data, err := json.Marshal(sess)
53
+
if err != nil {
54
+
return err
64
55
}
65
56
66
-
data, err := json.Marshal(stored)
57
+
return keyring.Set(keyringService, sessionKey(sess.AccountDID, sess.SessionID), string(data))
58
+
}
59
+
60
+
// DeleteSession removes a session from the keyring
61
+
func (s *KeyringAuthStore) DeleteSession(ctx context.Context, did syntax.DID, sessionID string) error {
62
+
return keyring.Delete(keyringService, sessionKey(did, sessionID))
63
+
}
64
+
65
+
// authRequestKey creates the keyring key for an auth request
66
+
func authRequestKey(state string) string {
67
+
return fmt.Sprintf("%s%s", authRequestPrefix, state)
68
+
}
69
+
70
+
// GetAuthRequestInfo retrieves pending auth request info
71
+
func (s *KeyringAuthStore) GetAuthRequestInfo(ctx context.Context, state string) (*oauth.AuthRequestData, error) {
72
+
data, err := keyring.Get(keyringService, authRequestKey(state))
67
73
if err != nil {
68
74
return nil, err
69
75
}
70
76
71
-
if keyring.Set(keyringService, keyringUser, string(data)) != nil {
77
+
var info oauth.AuthRequestData
78
+
if err := json.Unmarshal([]byte(data), &info); err != nil {
72
79
return nil, err
73
80
}
74
81
75
-
return stored, nil
82
+
return &info, nil
76
83
}
77
84
78
-
func StoreTokens(tokens *StoredTokens) (*StoredTokens, error) {
79
-
80
-
data, err := json.Marshal(tokens)
85
+
// SaveAuthRequestInfo stores pending auth request info
86
+
func (s *KeyringAuthStore) SaveAuthRequestInfo(ctx context.Context, info oauth.AuthRequestData) error {
87
+
data, err := json.Marshal(info)
81
88
if err != nil {
82
-
return nil, err
89
+
return err
83
90
}
84
91
85
-
if keyring.Set(keyringService, keyringUser, string(data)) != nil {
86
-
return nil, err
92
+
// Save the auth request data
93
+
if err := keyring.Set(keyringService, authRequestKey(info.State), string(data)); err != nil {
94
+
return err
87
95
}
88
96
89
-
return tokens, nil
97
+
// Also save the state as the current pending auth (for SSE correlation)
98
+
return keyring.Set(keyringService, pendingAuthStateKey, info.State)
99
+
}
100
+
101
+
// GetPendingAuthState returns the state of the current pending auth request
102
+
func (s *KeyringAuthStore) GetPendingAuthState() (string, error) {
103
+
return keyring.Get(keyringService, pendingAuthStateKey)
90
104
}
91
105
92
-
func GetStoredTokens() (*StoredTokens, error) {
93
-
data, err := keyring.Get(keyringService, keyringUser)
106
+
// ClearPendingAuthState removes the pending auth state
107
+
func (s *KeyringAuthStore) ClearPendingAuthState() error {
108
+
return keyring.Delete(keyringService, pendingAuthStateKey)
109
+
}
110
+
111
+
// DeleteAuthRequestInfo removes pending auth request info
112
+
func (s *KeyringAuthStore) DeleteAuthRequestInfo(ctx context.Context, state string) error {
113
+
return keyring.Delete(keyringService, authRequestKey(state))
114
+
}
115
+
116
+
// CurrentSessionRef stores reference to the current active session
117
+
type CurrentSessionRef struct {
118
+
DID string `json:"did"`
119
+
SessionID string `json:"session_id"`
120
+
}
121
+
122
+
// GetCurrentSession retrieves the current active session for the CLI
123
+
func (s *KeyringAuthStore) GetCurrentSession(ctx context.Context) (*oauth.ClientSessionData, error) {
124
+
refData, err := keyring.Get(keyringService, currentSessionKey)
94
125
if err != nil {
95
126
return nil, err
96
127
}
97
128
98
-
var tokens StoredTokens
99
-
if err := json.Unmarshal([]byte(data), &tokens); err != nil {
129
+
var ref CurrentSessionRef
130
+
if err := json.Unmarshal([]byte(refData), &ref); err != nil {
131
+
return nil, err
132
+
}
133
+
134
+
did, err := syntax.ParseDID(ref.DID)
135
+
if err != nil {
100
136
return nil, err
101
137
}
102
138
103
-
return &tokens, nil
139
+
return s.GetSession(ctx, did, ref.SessionID)
104
140
}
105
141
106
-
func DeleteStoredTokens() error {
107
-
return keyring.Delete(keyringService, keyringUser)
142
+
// SetCurrentSession sets the current active session reference
143
+
func (s *KeyringAuthStore) SetCurrentSession(ctx context.Context, sess *oauth.ClientSessionData) error {
144
+
ref := CurrentSessionRef{
145
+
DID: sess.AccountDID.String(),
146
+
SessionID: sess.SessionID,
147
+
}
148
+
149
+
data, err := json.Marshal(ref)
150
+
if err != nil {
151
+
return err
152
+
}
153
+
154
+
return keyring.Set(keyringService, currentSessionKey, string(data))
108
155
}
109
156
110
-
func DeleteStoredJWKS() error {
111
-
return keyring.Delete(keyringService, keyringJWKS)
157
+
// ClearCurrentSession removes the current session reference
158
+
func (s *KeyringAuthStore) ClearCurrentSession() error {
159
+
return keyring.Delete(keyringService, currentSessionKey)
112
160
}
113
161
114
-
// DeleteAll removes both tokens and JWKS
115
-
func DeleteAll() error {
116
-
if err := DeleteStoredTokens(); err != nil {
117
-
return err
118
-
}
119
-
return DeleteStoredJWKS()
162
+
// HasLegacyTokens checks if old-format tokens exist (for migration)
163
+
func HasLegacyTokens() bool {
164
+
_, err := keyring.Get(keyringService, legacyTokensKey)
165
+
return err == nil
120
166
}
121
167
122
-
func (t *StoredTokens) NeedsRefresh() bool {
123
-
sevenDaysFromNow := time.Now().Unix() + (7 * 24 * 60 * 60)
124
-
return t.ExpiresAt <= sevenDaysFromNow
168
+
// DeleteLegacyTokens removes old-format tokens and JWKS
169
+
func DeleteLegacyTokens() error {
170
+
// Ignore errors - keys might not exist
171
+
keyring.Delete(keyringService, legacyTokensKey)
172
+
keyring.Delete(keyringService, legacyJWKSKey)
173
+
return nil
125
174
}
+12
internal/clipboard/clipboard.go
+12
internal/clipboard/clipboard.go
···
1
+
// Package clipboard provides native clipboard access for Wayland.
2
+
package clipboard
3
+
4
+
// CopyText copies the given text to the system clipboard.
5
+
// On Wayland, this uses the wlr-data-control protocol directly,
6
+
// without requiring external tools like wl-copy.
7
+
//
8
+
// The implementation forks a background process to serve paste
9
+
// requests until another application takes clipboard ownership.
10
+
func CopyText(text string) error {
11
+
return copyTextPlatform(text)
12
+
}
+688
internal/clipboard/clipboard_wayland.c
+688
internal/clipboard/clipboard_wayland.c
···
1
+
/*
2
+
* Native Wayland clipboard implementation
3
+
* Supports both wlr-data-control (preferred) and popup surface hack (fallback)
4
+
*/
5
+
6
+
#define _GNU_SOURCE
7
+
#include <wayland-client.h>
8
+
#include <string.h>
9
+
#include <stdlib.h>
10
+
#include <unistd.h>
11
+
#include <fcntl.h>
12
+
#include <signal.h>
13
+
#include <errno.h>
14
+
#include <sys/mman.h>
15
+
16
+
#include "wlr-data-control.h"
17
+
#include "xdg-shell.h"
18
+
#include "clipboard_wayland.h"
19
+
20
+
/* State structure for clipboard operations */
21
+
struct clipboard_state {
22
+
/* Display connection */
23
+
struct wl_display *display;
24
+
struct wl_registry *registry;
25
+
26
+
/* Core globals */
27
+
struct wl_compositor *compositor;
28
+
struct wl_shm *shm;
29
+
struct wl_seat *seat;
30
+
struct wl_data_device_manager *data_device_manager;
31
+
32
+
/* Shell (for popup surface) */
33
+
struct xdg_wm_base *xdg_wm_base;
34
+
35
+
/* Preferred protocol (if available) */
36
+
struct zwlr_data_control_manager_v1 *data_control_manager;
37
+
38
+
/* Keyboard tracking */
39
+
struct wl_keyboard *keyboard;
40
+
uint32_t keyboard_serial;
41
+
int have_keyboard_focus;
42
+
43
+
/* Surface (for popup hack) */
44
+
struct wl_surface *surface;
45
+
struct xdg_surface *xdg_surface;
46
+
struct xdg_toplevel *xdg_toplevel;
47
+
struct wl_buffer *buffer;
48
+
struct wl_shm_pool *shm_pool;
49
+
int surface_configured;
50
+
51
+
/* wlr-data-control objects */
52
+
struct zwlr_data_control_source_v1 *wlr_source;
53
+
struct zwlr_data_control_device_v1 *wlr_device;
54
+
55
+
/* Core wayland data objects */
56
+
struct wl_data_source *data_source;
57
+
struct wl_data_device *data_device;
58
+
59
+
/* Clipboard content */
60
+
char *text;
61
+
size_t text_len;
62
+
63
+
/* State flags */
64
+
int selection_set;
65
+
int cancelled;
66
+
};
67
+
68
+
/* Forward declarations */
69
+
static int copy_via_data_control(struct clipboard_state *state);
70
+
static int copy_via_popup_surface(struct clipboard_state *state);
71
+
static void cleanup(struct clipboard_state *state);
72
+
73
+
/*
74
+
* wlr-data-control source listener
75
+
*/
76
+
static void wlr_source_send(void *data,
77
+
struct zwlr_data_control_source_v1 *source,
78
+
const char *mime_type, int32_t fd) {
79
+
struct clipboard_state *state = data;
80
+
if (state->text && state->text_len > 0) {
81
+
size_t written = 0;
82
+
while (written < state->text_len) {
83
+
ssize_t ret = write(fd, state->text + written, state->text_len - written);
84
+
if (ret < 0) {
85
+
if (errno == EINTR) continue;
86
+
break;
87
+
}
88
+
written += ret;
89
+
}
90
+
}
91
+
close(fd);
92
+
}
93
+
94
+
static void wlr_source_cancelled(void *data,
95
+
struct zwlr_data_control_source_v1 *source) {
96
+
struct clipboard_state *state = data;
97
+
state->cancelled = 1;
98
+
}
99
+
100
+
static const struct zwlr_data_control_source_v1_listener wlr_source_listener = {
101
+
.send = wlr_source_send,
102
+
.cancelled = wlr_source_cancelled,
103
+
};
104
+
105
+
/*
106
+
* wlr-data-control device listener (for offer/selection events we ignore)
107
+
*/
108
+
static void wlr_device_data_offer(void *data,
109
+
struct zwlr_data_control_device_v1 *device,
110
+
struct zwlr_data_control_offer_v1 *offer) {
111
+
if (offer) zwlr_data_control_offer_v1_destroy(offer);
112
+
}
113
+
114
+
static void wlr_device_selection(void *data,
115
+
struct zwlr_data_control_device_v1 *device,
116
+
struct zwlr_data_control_offer_v1 *offer) {
117
+
if (offer) zwlr_data_control_offer_v1_destroy(offer);
118
+
}
119
+
120
+
static void wlr_device_finished(void *data,
121
+
struct zwlr_data_control_device_v1 *device) {
122
+
struct clipboard_state *state = data;
123
+
state->cancelled = 1;
124
+
}
125
+
126
+
static void wlr_device_primary_selection(void *data,
127
+
struct zwlr_data_control_device_v1 *device,
128
+
struct zwlr_data_control_offer_v1 *offer) {
129
+
if (offer) zwlr_data_control_offer_v1_destroy(offer);
130
+
}
131
+
132
+
static const struct zwlr_data_control_device_v1_listener wlr_device_listener = {
133
+
.data_offer = wlr_device_data_offer,
134
+
.selection = wlr_device_selection,
135
+
.finished = wlr_device_finished,
136
+
.primary_selection = wlr_device_primary_selection,
137
+
};
138
+
139
+
/*
140
+
* Core wl_data_source listener (for popup surface path)
141
+
*/
142
+
static void data_source_target(void *data, struct wl_data_source *source,
143
+
const char *mime_type) {
144
+
/* Ignore */
145
+
}
146
+
147
+
static void data_source_send(void *data, struct wl_data_source *source,
148
+
const char *mime_type, int32_t fd) {
149
+
struct clipboard_state *state = data;
150
+
if (state->text && state->text_len > 0) {
151
+
size_t written = 0;
152
+
while (written < state->text_len) {
153
+
ssize_t ret = write(fd, state->text + written, state->text_len - written);
154
+
if (ret < 0) {
155
+
if (errno == EINTR) continue;
156
+
break;
157
+
}
158
+
written += ret;
159
+
}
160
+
}
161
+
close(fd);
162
+
}
163
+
164
+
static void data_source_cancelled(void *data, struct wl_data_source *source) {
165
+
struct clipboard_state *state = data;
166
+
state->cancelled = 1;
167
+
}
168
+
169
+
static void data_source_dnd_drop_performed(void *data, struct wl_data_source *source) {}
170
+
static void data_source_dnd_finished(void *data, struct wl_data_source *source) {}
171
+
static void data_source_action(void *data, struct wl_data_source *source, uint32_t action) {}
172
+
173
+
static const struct wl_data_source_listener data_source_listener = {
174
+
.target = data_source_target,
175
+
.send = data_source_send,
176
+
.cancelled = data_source_cancelled,
177
+
.dnd_drop_performed = data_source_dnd_drop_performed,
178
+
.dnd_finished = data_source_dnd_finished,
179
+
.action = data_source_action,
180
+
};
181
+
182
+
/*
183
+
* Keyboard listener - captures focus serial
184
+
*/
185
+
static void keyboard_keymap(void *data, struct wl_keyboard *keyboard,
186
+
uint32_t format, int32_t fd, uint32_t size) {
187
+
close(fd);
188
+
}
189
+
190
+
static void keyboard_enter(void *data, struct wl_keyboard *keyboard,
191
+
uint32_t serial, struct wl_surface *surface,
192
+
struct wl_array *keys) {
193
+
struct clipboard_state *state = data;
194
+
state->keyboard_serial = serial;
195
+
state->have_keyboard_focus = 1;
196
+
}
197
+
198
+
static void keyboard_leave(void *data, struct wl_keyboard *keyboard,
199
+
uint32_t serial, struct wl_surface *surface) {
200
+
/* Ignore */
201
+
}
202
+
203
+
static void keyboard_key(void *data, struct wl_keyboard *keyboard,
204
+
uint32_t serial, uint32_t time, uint32_t key, uint32_t state_w) {
205
+
/* Ignore */
206
+
}
207
+
208
+
static void keyboard_modifiers(void *data, struct wl_keyboard *keyboard,
209
+
uint32_t serial, uint32_t mods_depressed,
210
+
uint32_t mods_latched, uint32_t mods_locked,
211
+
uint32_t group) {
212
+
/* Ignore */
213
+
}
214
+
215
+
static void keyboard_repeat_info(void *data, struct wl_keyboard *keyboard,
216
+
int32_t rate, int32_t delay) {
217
+
/* Ignore */
218
+
}
219
+
220
+
static const struct wl_keyboard_listener keyboard_listener = {
221
+
.keymap = keyboard_keymap,
222
+
.enter = keyboard_enter,
223
+
.leave = keyboard_leave,
224
+
.key = keyboard_key,
225
+
.modifiers = keyboard_modifiers,
226
+
.repeat_info = keyboard_repeat_info,
227
+
};
228
+
229
+
/*
230
+
* xdg_wm_base listener - handle ping/pong
231
+
*/
232
+
static void xdg_wm_base_ping(void *data, struct xdg_wm_base *xdg_wm_base,
233
+
uint32_t serial) {
234
+
xdg_wm_base_pong(xdg_wm_base, serial);
235
+
}
236
+
237
+
static const struct xdg_wm_base_listener xdg_wm_base_listener = {
238
+
.ping = xdg_wm_base_ping,
239
+
};
240
+
241
+
/*
242
+
* xdg_surface listener - handle configure
243
+
*/
244
+
static void xdg_surface_configure(void *data, struct xdg_surface *xdg_surface,
245
+
uint32_t serial) {
246
+
struct clipboard_state *state = data;
247
+
xdg_surface_ack_configure(xdg_surface, serial);
248
+
state->surface_configured = 1;
249
+
}
250
+
251
+
static const struct xdg_surface_listener xdg_surface_listener = {
252
+
.configure = xdg_surface_configure,
253
+
};
254
+
255
+
/*
256
+
* xdg_toplevel listener - handle configure/close
257
+
*/
258
+
static void xdg_toplevel_configure(void *data, struct xdg_toplevel *toplevel,
259
+
int32_t width, int32_t height,
260
+
struct wl_array *states) {
261
+
/* Ignore size hints */
262
+
}
263
+
264
+
static void xdg_toplevel_close(void *data, struct xdg_toplevel *toplevel) {
265
+
struct clipboard_state *state = data;
266
+
state->cancelled = 1;
267
+
}
268
+
269
+
static void xdg_toplevel_configure_bounds(void *data, struct xdg_toplevel *toplevel,
270
+
int32_t width, int32_t height) {
271
+
/* Ignore */
272
+
}
273
+
274
+
static void xdg_toplevel_wm_capabilities(void *data, struct xdg_toplevel *toplevel,
275
+
struct wl_array *capabilities) {
276
+
/* Ignore */
277
+
}
278
+
279
+
static const struct xdg_toplevel_listener xdg_toplevel_listener = {
280
+
.configure = xdg_toplevel_configure,
281
+
.close = xdg_toplevel_close,
282
+
.configure_bounds = xdg_toplevel_configure_bounds,
283
+
.wm_capabilities = xdg_toplevel_wm_capabilities,
284
+
};
285
+
286
+
/*
287
+
* wl_seat listener - get capabilities
288
+
*/
289
+
static void seat_capabilities(void *data, struct wl_seat *seat, uint32_t caps) {
290
+
struct clipboard_state *state = data;
291
+
if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !state->keyboard) {
292
+
state->keyboard = wl_seat_get_keyboard(seat);
293
+
wl_keyboard_add_listener(state->keyboard, &keyboard_listener, state);
294
+
}
295
+
}
296
+
297
+
static void seat_name(void *data, struct wl_seat *seat, const char *name) {
298
+
/* Ignore */
299
+
}
300
+
301
+
static const struct wl_seat_listener seat_listener = {
302
+
.capabilities = seat_capabilities,
303
+
.name = seat_name,
304
+
};
305
+
306
+
/*
307
+
* Registry listener - discover globals
308
+
*/
309
+
static void registry_global(void *data, struct wl_registry *registry,
310
+
uint32_t name, const char *interface, uint32_t version) {
311
+
struct clipboard_state *state = data;
312
+
313
+
if (strcmp(interface, "wl_compositor") == 0) {
314
+
state->compositor = wl_registry_bind(registry, name,
315
+
&wl_compositor_interface, version < 4 ? version : 4);
316
+
}
317
+
else if (strcmp(interface, "wl_shm") == 0) {
318
+
state->shm = wl_registry_bind(registry, name,
319
+
&wl_shm_interface, 1);
320
+
}
321
+
else if (strcmp(interface, "wl_seat") == 0) {
322
+
state->seat = wl_registry_bind(registry, name,
323
+
&wl_seat_interface, version < 2 ? version : 2);
324
+
wl_seat_add_listener(state->seat, &seat_listener, state);
325
+
}
326
+
else if (strcmp(interface, "wl_data_device_manager") == 0) {
327
+
state->data_device_manager = wl_registry_bind(registry, name,
328
+
&wl_data_device_manager_interface, version < 3 ? version : 3);
329
+
}
330
+
else if (strcmp(interface, "xdg_wm_base") == 0) {
331
+
state->xdg_wm_base = wl_registry_bind(registry, name,
332
+
&xdg_wm_base_interface, 1);
333
+
xdg_wm_base_add_listener(state->xdg_wm_base, &xdg_wm_base_listener, state);
334
+
}
335
+
else if (strcmp(interface, "zwlr_data_control_manager_v1") == 0) {
336
+
state->data_control_manager = wl_registry_bind(registry, name,
337
+
&zwlr_data_control_manager_v1_interface, version < 2 ? version : 2);
338
+
}
339
+
}
340
+
341
+
static void registry_global_remove(void *data, struct wl_registry *registry,
342
+
uint32_t name) {
343
+
/* Ignore */
344
+
}
345
+
346
+
static const struct wl_registry_listener registry_listener = {
347
+
.global = registry_global,
348
+
.global_remove = registry_global_remove,
349
+
};
350
+
351
+
/*
352
+
* Create 1x1 transparent buffer via wl_shm
353
+
*/
354
+
static int create_buffer(struct clipboard_state *state) {
355
+
int width = 1, height = 1;
356
+
int stride = width * 4;
357
+
int size = stride * height;
358
+
359
+
/* Create anonymous file */
360
+
int fd = memfd_create("clipboard-buffer", MFD_CLOEXEC);
361
+
if (fd < 0) return -1;
362
+
363
+
if (ftruncate(fd, size) < 0) {
364
+
close(fd);
365
+
return -1;
366
+
}
367
+
368
+
/* Create shm pool */
369
+
state->shm_pool = wl_shm_create_pool(state->shm, fd, size);
370
+
close(fd);
371
+
372
+
if (!state->shm_pool) return -1;
373
+
374
+
/* Create buffer (zero bytes = transparent ARGB) */
375
+
state->buffer = wl_shm_pool_create_buffer(state->shm_pool, 0,
376
+
width, height, stride, WL_SHM_FORMAT_ARGB8888);
377
+
378
+
return state->buffer ? 0 : -1;
379
+
}
380
+
381
+
/*
382
+
* Create popup surface to get keyboard focus
383
+
*/
384
+
static int create_popup_surface(struct clipboard_state *state) {
385
+
/* Create wl_surface */
386
+
state->surface = wl_compositor_create_surface(state->compositor);
387
+
if (!state->surface) return -1;
388
+
389
+
/* Create xdg_surface */
390
+
state->xdg_surface = xdg_wm_base_get_xdg_surface(state->xdg_wm_base, state->surface);
391
+
if (!state->xdg_surface) return -1;
392
+
xdg_surface_add_listener(state->xdg_surface, &xdg_surface_listener, state);
393
+
394
+
/* Create xdg_toplevel */
395
+
state->xdg_toplevel = xdg_surface_get_toplevel(state->xdg_surface);
396
+
if (!state->xdg_toplevel) return -1;
397
+
xdg_toplevel_add_listener(state->xdg_toplevel, &xdg_toplevel_listener, state);
398
+
xdg_toplevel_set_title(state->xdg_toplevel, "clipboard");
399
+
400
+
/* Commit to trigger configure */
401
+
wl_surface_commit(state->surface);
402
+
403
+
/* Wait for configure event */
404
+
int timeout = 100;
405
+
while (!state->surface_configured && timeout-- > 0) {
406
+
if (wl_display_dispatch(state->display) < 0) return -1;
407
+
}
408
+
if (!state->surface_configured) return -1;
409
+
410
+
/* Create and attach buffer */
411
+
if (create_buffer(state) < 0) return -1;
412
+
413
+
wl_surface_attach(state->surface, state->buffer, 0, 0);
414
+
wl_surface_damage(state->surface, 0, 0, 1, 1);
415
+
wl_surface_commit(state->surface);
416
+
417
+
return 0;
418
+
}
419
+
420
+
/*
421
+
* Destroy popup surface
422
+
*/
423
+
static void destroy_popup_surface(struct clipboard_state *state) {
424
+
if (state->xdg_toplevel) {
425
+
xdg_toplevel_destroy(state->xdg_toplevel);
426
+
state->xdg_toplevel = NULL;
427
+
}
428
+
if (state->xdg_surface) {
429
+
xdg_surface_destroy(state->xdg_surface);
430
+
state->xdg_surface = NULL;
431
+
}
432
+
if (state->buffer) {
433
+
wl_buffer_destroy(state->buffer);
434
+
state->buffer = NULL;
435
+
}
436
+
if (state->shm_pool) {
437
+
wl_shm_pool_destroy(state->shm_pool);
438
+
state->shm_pool = NULL;
439
+
}
440
+
if (state->surface) {
441
+
wl_surface_destroy(state->surface);
442
+
state->surface = NULL;
443
+
}
444
+
}
445
+
446
+
/*
447
+
* Fork to background and serve clipboard
448
+
*/
449
+
static int fork_and_serve(struct clipboard_state *state) {
450
+
pid_t pid = fork();
451
+
if (pid < 0) return -5;
452
+
453
+
if (pid > 0) {
454
+
/* Parent: detach from display (child owns it now) and return success */
455
+
state->display = NULL;
456
+
state->text = NULL;
457
+
return 0;
458
+
}
459
+
460
+
/* Child: detach from terminal */
461
+
int devnull = open("/dev/null", O_RDWR);
462
+
if (devnull >= 0) {
463
+
dup2(devnull, STDIN_FILENO);
464
+
dup2(devnull, STDOUT_FILENO);
465
+
dup2(devnull, STDERR_FILENO);
466
+
if (devnull > STDERR_FILENO) close(devnull);
467
+
}
468
+
469
+
signal(SIGHUP, SIG_IGN);
470
+
signal(SIGPIPE, SIG_IGN);
471
+
if (chdir("/") < 0) { /* Ignore error */ }
472
+
473
+
/* Event loop until cancelled */
474
+
while (!state->cancelled && wl_display_dispatch(state->display) >= 0);
475
+
476
+
cleanup(state);
477
+
_exit(0);
478
+
}
479
+
480
+
/*
481
+
* Copy via wlr-data-control (simple path, no popup needed)
482
+
*/
483
+
static int copy_via_data_control(struct clipboard_state *state) {
484
+
/* Create source */
485
+
state->wlr_source = zwlr_data_control_manager_v1_create_data_source(
486
+
state->data_control_manager);
487
+
if (!state->wlr_source) return -4;
488
+
489
+
zwlr_data_control_source_v1_add_listener(state->wlr_source,
490
+
&wlr_source_listener, state);
491
+
492
+
/* Offer MIME types */
493
+
zwlr_data_control_source_v1_offer(state->wlr_source, "text/plain");
494
+
zwlr_data_control_source_v1_offer(state->wlr_source, "text/plain;charset=utf-8");
495
+
zwlr_data_control_source_v1_offer(state->wlr_source, "TEXT");
496
+
zwlr_data_control_source_v1_offer(state->wlr_source, "STRING");
497
+
zwlr_data_control_source_v1_offer(state->wlr_source, "UTF8_STRING");
498
+
499
+
/* Get device */
500
+
state->wlr_device = zwlr_data_control_manager_v1_get_data_device(
501
+
state->data_control_manager, state->seat);
502
+
if (!state->wlr_device) return -4;
503
+
504
+
zwlr_data_control_device_v1_add_listener(state->wlr_device,
505
+
&wlr_device_listener, state);
506
+
507
+
/* Set selection */
508
+
zwlr_data_control_device_v1_set_selection(state->wlr_device, state->wlr_source);
509
+
wl_display_roundtrip(state->display);
510
+
511
+
state->selection_set = 1;
512
+
513
+
/* Fork to background */
514
+
return fork_and_serve(state);
515
+
}
516
+
517
+
/*
518
+
* Copy via popup surface hack (fallback for GNOME)
519
+
*/
520
+
static int copy_via_popup_surface(struct clipboard_state *state) {
521
+
/* Create data source */
522
+
state->data_source = wl_data_device_manager_create_data_source(
523
+
state->data_device_manager);
524
+
if (!state->data_source) return -4;
525
+
526
+
wl_data_source_add_listener(state->data_source, &data_source_listener, state);
527
+
528
+
/* Offer MIME types */
529
+
wl_data_source_offer(state->data_source, "text/plain");
530
+
wl_data_source_offer(state->data_source, "text/plain;charset=utf-8");
531
+
wl_data_source_offer(state->data_source, "TEXT");
532
+
wl_data_source_offer(state->data_source, "STRING");
533
+
wl_data_source_offer(state->data_source, "UTF8_STRING");
534
+
535
+
/* Get data device */
536
+
state->data_device = wl_data_device_manager_get_data_device(
537
+
state->data_device_manager, state->seat);
538
+
if (!state->data_device) return -4;
539
+
540
+
/* Create popup surface to get keyboard focus */
541
+
if (create_popup_surface(state) < 0) return -4;
542
+
543
+
/* Wait for keyboard focus (with timeout) */
544
+
int timeout = 100;
545
+
while (!state->have_keyboard_focus && timeout-- > 0) {
546
+
if (wl_display_dispatch(state->display) < 0) {
547
+
destroy_popup_surface(state);
548
+
return -3;
549
+
}
550
+
}
551
+
552
+
if (!state->have_keyboard_focus) {
553
+
destroy_popup_surface(state);
554
+
return -6; /* Focus timeout */
555
+
}
556
+
557
+
/* Set selection with the serial from keyboard focus */
558
+
wl_data_device_set_selection(state->data_device,
559
+
state->data_source, state->keyboard_serial);
560
+
wl_display_roundtrip(state->display);
561
+
562
+
state->selection_set = 1;
563
+
564
+
/* Destroy popup surface */
565
+
destroy_popup_surface(state);
566
+
567
+
/* Fork to background */
568
+
return fork_and_serve(state);
569
+
}
570
+
571
+
/*
572
+
* Cleanup all resources
573
+
*/
574
+
static void cleanup(struct clipboard_state *state) {
575
+
destroy_popup_surface(state);
576
+
577
+
if (state->wlr_source) {
578
+
zwlr_data_control_source_v1_destroy(state->wlr_source);
579
+
state->wlr_source = NULL;
580
+
}
581
+
if (state->wlr_device) {
582
+
zwlr_data_control_device_v1_destroy(state->wlr_device);
583
+
state->wlr_device = NULL;
584
+
}
585
+
if (state->data_source) {
586
+
wl_data_source_destroy(state->data_source);
587
+
state->data_source = NULL;
588
+
}
589
+
if (state->data_device) {
590
+
wl_data_device_destroy(state->data_device);
591
+
state->data_device = NULL;
592
+
}
593
+
if (state->keyboard) {
594
+
wl_keyboard_destroy(state->keyboard);
595
+
state->keyboard = NULL;
596
+
}
597
+
if (state->data_control_manager) {
598
+
zwlr_data_control_manager_v1_destroy(state->data_control_manager);
599
+
state->data_control_manager = NULL;
600
+
}
601
+
if (state->xdg_wm_base) {
602
+
xdg_wm_base_destroy(state->xdg_wm_base);
603
+
state->xdg_wm_base = NULL;
604
+
}
605
+
if (state->data_device_manager) {
606
+
wl_data_device_manager_destroy(state->data_device_manager);
607
+
state->data_device_manager = NULL;
608
+
}
609
+
if (state->seat) {
610
+
wl_seat_destroy(state->seat);
611
+
state->seat = NULL;
612
+
}
613
+
if (state->shm) {
614
+
wl_shm_destroy(state->shm);
615
+
state->shm = NULL;
616
+
}
617
+
if (state->compositor) {
618
+
wl_compositor_destroy(state->compositor);
619
+
state->compositor = NULL;
620
+
}
621
+
if (state->registry) {
622
+
wl_registry_destroy(state->registry);
623
+
state->registry = NULL;
624
+
}
625
+
if (state->display) {
626
+
wl_display_disconnect(state->display);
627
+
state->display = NULL;
628
+
}
629
+
if (state->text) {
630
+
free(state->text);
631
+
state->text = NULL;
632
+
}
633
+
}
634
+
635
+
/*
636
+
* Main entry point: copy text to clipboard
637
+
*/
638
+
int clipboard_copy_text(const char *text, size_t len) {
639
+
struct clipboard_state state = {0};
640
+
int result = 0;
641
+
642
+
/* Store text to copy */
643
+
state.text = malloc(len);
644
+
if (!state.text) return -4;
645
+
memcpy(state.text, text, len);
646
+
state.text_len = len;
647
+
648
+
/* Ignore SIGPIPE */
649
+
signal(SIGPIPE, SIG_IGN);
650
+
651
+
/* Connect to display */
652
+
state.display = wl_display_connect(NULL);
653
+
if (!state.display) {
654
+
result = -1;
655
+
goto error;
656
+
}
657
+
658
+
/* Get registry */
659
+
state.registry = wl_display_get_registry(state.display);
660
+
wl_registry_add_listener(state.registry, ®istry_listener, &state);
661
+
662
+
/* Roundtrip to get globals */
663
+
wl_display_roundtrip(state.display);
664
+
665
+
/* Second roundtrip to ensure seat capabilities are processed */
666
+
wl_display_roundtrip(state.display);
667
+
668
+
/* Choose path based on available protocols */
669
+
if (state.data_control_manager && state.seat) {
670
+
/* Preferred: wlr-data-control (no popup needed) */
671
+
result = copy_via_data_control(&state);
672
+
} else if (state.data_device_manager && state.compositor &&
673
+
state.shm && state.seat && state.xdg_wm_base) {
674
+
/* Fallback: popup surface hack */
675
+
result = copy_via_popup_surface(&state);
676
+
} else {
677
+
result = -2; /* Missing required protocols */
678
+
}
679
+
680
+
if (result == 0) {
681
+
/* Success - parent process, cleanup done by fork */
682
+
return 0;
683
+
}
684
+
685
+
error:
686
+
cleanup(&state);
687
+
return result;
688
+
}
+54
internal/clipboard/clipboard_wayland.go
+54
internal/clipboard/clipboard_wayland.go
···
1
+
//go:build linux
2
+
3
+
package clipboard
4
+
5
+
/*
6
+
#cgo pkg-config: wayland-client
7
+
#cgo CFLAGS: -I${SRCDIR}
8
+
#include <stdlib.h>
9
+
#include "clipboard_wayland.h"
10
+
*/
11
+
import "C"
12
+
import (
13
+
"errors"
14
+
"unsafe"
15
+
)
16
+
17
+
var (
18
+
ErrNoDisplay = errors.New("cannot connect to Wayland display")
19
+
ErrMissingProtocols = errors.New("missing required Wayland protocols")
20
+
ErrDisplayError = errors.New("Wayland display error")
21
+
ErrAllocation = errors.New("resource allocation failed")
22
+
ErrFork = errors.New("fork failed")
23
+
ErrFocusTimeout = errors.New("keyboard focus timeout")
24
+
)
25
+
26
+
func copyTextPlatform(text string) error {
27
+
if len(text) == 0 {
28
+
return nil
29
+
}
30
+
31
+
cText := C.CString(text)
32
+
defer C.free(unsafe.Pointer(cText))
33
+
34
+
result := C.clipboard_copy_text(cText, C.size_t(len(text)))
35
+
36
+
switch result {
37
+
case 0:
38
+
return nil
39
+
case -1:
40
+
return ErrNoDisplay
41
+
case -2:
42
+
return ErrMissingProtocols
43
+
case -3:
44
+
return ErrDisplayError
45
+
case -4:
46
+
return ErrAllocation
47
+
case -5:
48
+
return ErrFork
49
+
case -6:
50
+
return ErrFocusTimeout
51
+
default:
52
+
return errors.New("unknown clipboard error")
53
+
}
54
+
}
+26
internal/clipboard/clipboard_wayland.h
+26
internal/clipboard/clipboard_wayland.h
···
1
+
#ifndef CLIPBOARD_WAYLAND_H
2
+
#define CLIPBOARD_WAYLAND_H
3
+
4
+
#include <stddef.h>
5
+
6
+
/*
7
+
* Copy text to the Wayland clipboard.
8
+
* Uses wlr-data-control if available (Sway, KDE), otherwise falls back to
9
+
* popup surface hack with wl_data_device (GNOME).
10
+
*
11
+
* Parameters:
12
+
* text - The text to copy
13
+
* len - Length of text in bytes
14
+
*
15
+
* Returns:
16
+
* 0 on success
17
+
* -1: Cannot connect to Wayland display
18
+
* -2: Missing required Wayland protocols
19
+
* -3: Display error during operation
20
+
* -4: Resource allocation failed
21
+
* -5: Fork failed
22
+
* -6: Keyboard focus timeout (popup surface hack)
23
+
*/
24
+
int clipboard_copy_text(const char *text, size_t len);
25
+
26
+
#endif /* CLIPBOARD_WAYLAND_H */
+10
internal/clipboard/generate.go
+10
internal/clipboard/generate.go
···
1
+
//go:build linux
2
+
3
+
package clipboard
4
+
5
+
//go:generate sh -c "wayland-scanner client-header $(pkg-config --variable=pkgdatadir wayland-protocols)/stable/xdg-shell/xdg-shell.xml xdg-shell.h"
6
+
//go:generate sh -c "wayland-scanner private-code $(pkg-config --variable=pkgdatadir wayland-protocols)/stable/xdg-shell/xdg-shell.xml xdg-shell.c"
7
+
//go:generate curl -sfo wlr-data-control-unstable-v1.xml https://gitlab.freedesktop.org/wlroots/wlr-protocols/-/raw/master/unstable/wlr-data-control-unstable-v1.xml
8
+
//go:generate wayland-scanner client-header wlr-data-control-unstable-v1.xml wlr-data-control.h
9
+
//go:generate wayland-scanner private-code wlr-data-control-unstable-v1.xml wlr-data-control.c
10
+
//go:generate rm wlr-data-control-unstable-v1.xml
+123
internal/clipboard/wlr-data-control.c
+123
internal/clipboard/wlr-data-control.c
···
1
+
/* Generated by wayland-scanner 1.24.0 */
2
+
3
+
/*
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
+
*/
28
+
29
+
#include <stdbool.h>
30
+
#include <stdlib.h>
31
+
#include <stdint.h>
32
+
#include "wayland-util.h"
33
+
34
+
#ifndef __has_attribute
35
+
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
36
+
#endif
37
+
38
+
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
39
+
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
40
+
#else
41
+
#define WL_PRIVATE
42
+
#endif
43
+
44
+
extern const struct wl_interface wl_seat_interface;
45
+
extern const struct wl_interface zwlr_data_control_device_v1_interface;
46
+
extern const struct wl_interface zwlr_data_control_offer_v1_interface;
47
+
extern const struct wl_interface zwlr_data_control_source_v1_interface;
48
+
49
+
static const struct wl_interface *wlr_data_control_unstable_v1_types[] = {
50
+
NULL,
51
+
NULL,
52
+
&zwlr_data_control_source_v1_interface,
53
+
&zwlr_data_control_device_v1_interface,
54
+
&wl_seat_interface,
55
+
&zwlr_data_control_source_v1_interface,
56
+
&zwlr_data_control_source_v1_interface,
57
+
&zwlr_data_control_offer_v1_interface,
58
+
&zwlr_data_control_offer_v1_interface,
59
+
&zwlr_data_control_offer_v1_interface,
60
+
};
61
+
62
+
static const struct wl_message zwlr_data_control_manager_v1_requests[] = {
63
+
{ "create_data_source", "n", wlr_data_control_unstable_v1_types + 2 },
64
+
{ "get_data_device", "no", wlr_data_control_unstable_v1_types + 3 },
65
+
{ "destroy", "", wlr_data_control_unstable_v1_types + 0 },
66
+
};
67
+
68
+
WL_PRIVATE const struct wl_interface zwlr_data_control_manager_v1_interface = {
69
+
"zwlr_data_control_manager_v1", 2,
70
+
3, zwlr_data_control_manager_v1_requests,
71
+
0, NULL,
72
+
};
73
+
74
+
static const struct wl_message zwlr_data_control_device_v1_requests[] = {
75
+
{ "set_selection", "?o", wlr_data_control_unstable_v1_types + 5 },
76
+
{ "destroy", "", wlr_data_control_unstable_v1_types + 0 },
77
+
{ "set_primary_selection", "2?o", wlr_data_control_unstable_v1_types + 6 },
78
+
};
79
+
80
+
static const struct wl_message zwlr_data_control_device_v1_events[] = {
81
+
{ "data_offer", "n", wlr_data_control_unstable_v1_types + 7 },
82
+
{ "selection", "?o", wlr_data_control_unstable_v1_types + 8 },
83
+
{ "finished", "", wlr_data_control_unstable_v1_types + 0 },
84
+
{ "primary_selection", "2?o", wlr_data_control_unstable_v1_types + 9 },
85
+
};
86
+
87
+
WL_PRIVATE const struct wl_interface zwlr_data_control_device_v1_interface = {
88
+
"zwlr_data_control_device_v1", 2,
89
+
3, zwlr_data_control_device_v1_requests,
90
+
4, zwlr_data_control_device_v1_events,
91
+
};
92
+
93
+
static const struct wl_message zwlr_data_control_source_v1_requests[] = {
94
+
{ "offer", "s", wlr_data_control_unstable_v1_types + 0 },
95
+
{ "destroy", "", wlr_data_control_unstable_v1_types + 0 },
96
+
};
97
+
98
+
static const struct wl_message zwlr_data_control_source_v1_events[] = {
99
+
{ "send", "sh", wlr_data_control_unstable_v1_types + 0 },
100
+
{ "cancelled", "", wlr_data_control_unstable_v1_types + 0 },
101
+
};
102
+
103
+
WL_PRIVATE const struct wl_interface zwlr_data_control_source_v1_interface = {
104
+
"zwlr_data_control_source_v1", 1,
105
+
2, zwlr_data_control_source_v1_requests,
106
+
2, zwlr_data_control_source_v1_events,
107
+
};
108
+
109
+
static const struct wl_message zwlr_data_control_offer_v1_requests[] = {
110
+
{ "receive", "sh", wlr_data_control_unstable_v1_types + 0 },
111
+
{ "destroy", "", wlr_data_control_unstable_v1_types + 0 },
112
+
};
113
+
114
+
static const struct wl_message zwlr_data_control_offer_v1_events[] = {
115
+
{ "offer", "s", wlr_data_control_unstable_v1_types + 0 },
116
+
};
117
+
118
+
WL_PRIVATE const struct wl_interface zwlr_data_control_offer_v1_interface = {
119
+
"zwlr_data_control_offer_v1", 1,
120
+
2, zwlr_data_control_offer_v1_requests,
121
+
1, zwlr_data_control_offer_v1_events,
122
+
};
123
+
+668
internal/clipboard/wlr-data-control.h
+668
internal/clipboard/wlr-data-control.h
···
1
+
/* Generated by wayland-scanner 1.24.0 */
2
+
3
+
#ifndef WLR_DATA_CONTROL_UNSTABLE_V1_CLIENT_PROTOCOL_H
4
+
#define WLR_DATA_CONTROL_UNSTABLE_V1_CLIENT_PROTOCOL_H
5
+
6
+
#include <stdint.h>
7
+
#include <stddef.h>
8
+
#include "wayland-client.h"
9
+
10
+
#ifdef __cplusplus
11
+
extern "C" {
12
+
#endif
13
+
14
+
/**
15
+
* @page page_wlr_data_control_unstable_v1 The wlr_data_control_unstable_v1 protocol
16
+
* control data devices
17
+
*
18
+
* @section page_desc_wlr_data_control_unstable_v1 Description
19
+
*
20
+
* This protocol allows a privileged client to control data devices. In
21
+
* particular, the client will be able to manage the current selection and take
22
+
* the role of a clipboard manager.
23
+
*
24
+
* Warning! The protocol described in this file is experimental and
25
+
* backward incompatible changes may be made. Backward compatible changes
26
+
* may be added together with the corresponding interface version bump.
27
+
* Backward incompatible changes are done by bumping the version number in
28
+
* the protocol and interface names and resetting the interface version.
29
+
* Once the protocol is to be declared stable, the 'z' prefix and the
30
+
* version number in the protocol and interface names are removed and the
31
+
* interface version number is reset.
32
+
*
33
+
* Note! This protocol is deprecated and not intended for production use.
34
+
* For clipboard management, use the ext-data-control-v1 protocol.
35
+
*
36
+
* @section page_ifaces_wlr_data_control_unstable_v1 Interfaces
37
+
* - @subpage page_iface_zwlr_data_control_manager_v1 - manager to control data devices
38
+
* - @subpage page_iface_zwlr_data_control_device_v1 - manage a data device for a seat
39
+
* - @subpage page_iface_zwlr_data_control_source_v1 - offer to transfer data
40
+
* - @subpage page_iface_zwlr_data_control_offer_v1 - offer to transfer data
41
+
* @section page_copyright_wlr_data_control_unstable_v1 Copyright
42
+
* <pre>
43
+
*
44
+
* Copyright © 2018 Simon Ser
45
+
* Copyright © 2019 Ivan Molodetskikh
46
+
*
47
+
* Permission to use, copy, modify, distribute, and sell this
48
+
* software and its documentation for any purpose is hereby granted
49
+
* without fee, provided that the above copyright notice appear in
50
+
* all copies and that both that copyright notice and this permission
51
+
* notice appear in supporting documentation, and that the name of
52
+
* the copyright holders not be used in advertising or publicity
53
+
* pertaining to distribution of the software without specific,
54
+
* written prior permission. The copyright holders make no
55
+
* representations about the suitability of this software for any
56
+
* purpose. It is provided "as is" without express or implied
57
+
* warranty.
58
+
*
59
+
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
60
+
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
61
+
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
62
+
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
63
+
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
64
+
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
65
+
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
66
+
* THIS SOFTWARE.
67
+
* </pre>
68
+
*/
69
+
struct wl_seat;
70
+
struct zwlr_data_control_device_v1;
71
+
struct zwlr_data_control_manager_v1;
72
+
struct zwlr_data_control_offer_v1;
73
+
struct zwlr_data_control_source_v1;
74
+
75
+
#ifndef ZWLR_DATA_CONTROL_MANAGER_V1_INTERFACE
76
+
#define ZWLR_DATA_CONTROL_MANAGER_V1_INTERFACE
77
+
/**
78
+
* @page page_iface_zwlr_data_control_manager_v1 zwlr_data_control_manager_v1
79
+
* @section page_iface_zwlr_data_control_manager_v1_desc Description
80
+
*
81
+
* This interface is a manager that allows creating per-seat data device
82
+
* controls.
83
+
* @section page_iface_zwlr_data_control_manager_v1_api API
84
+
* See @ref iface_zwlr_data_control_manager_v1.
85
+
*/
86
+
/**
87
+
* @defgroup iface_zwlr_data_control_manager_v1 The zwlr_data_control_manager_v1 interface
88
+
*
89
+
* This interface is a manager that allows creating per-seat data device
90
+
* controls.
91
+
*/
92
+
extern const struct wl_interface zwlr_data_control_manager_v1_interface;
93
+
#endif
94
+
#ifndef ZWLR_DATA_CONTROL_DEVICE_V1_INTERFACE
95
+
#define ZWLR_DATA_CONTROL_DEVICE_V1_INTERFACE
96
+
/**
97
+
* @page page_iface_zwlr_data_control_device_v1 zwlr_data_control_device_v1
98
+
* @section page_iface_zwlr_data_control_device_v1_desc Description
99
+
*
100
+
* This interface allows a client to manage a seat's selection.
101
+
*
102
+
* When the seat is destroyed, this object becomes inert.
103
+
* @section page_iface_zwlr_data_control_device_v1_api API
104
+
* See @ref iface_zwlr_data_control_device_v1.
105
+
*/
106
+
/**
107
+
* @defgroup iface_zwlr_data_control_device_v1 The zwlr_data_control_device_v1 interface
108
+
*
109
+
* This interface allows a client to manage a seat's selection.
110
+
*
111
+
* When the seat is destroyed, this object becomes inert.
112
+
*/
113
+
extern const struct wl_interface zwlr_data_control_device_v1_interface;
114
+
#endif
115
+
#ifndef ZWLR_DATA_CONTROL_SOURCE_V1_INTERFACE
116
+
#define ZWLR_DATA_CONTROL_SOURCE_V1_INTERFACE
117
+
/**
118
+
* @page page_iface_zwlr_data_control_source_v1 zwlr_data_control_source_v1
119
+
* @section page_iface_zwlr_data_control_source_v1_desc Description
120
+
*
121
+
* The wlr_data_control_source object is the source side of a
122
+
* wlr_data_control_offer. It is created by the source client in a data
123
+
* transfer and provides a way to describe the offered data and a way to
124
+
* respond to requests to transfer the data.
125
+
* @section page_iface_zwlr_data_control_source_v1_api API
126
+
* See @ref iface_zwlr_data_control_source_v1.
127
+
*/
128
+
/**
129
+
* @defgroup iface_zwlr_data_control_source_v1 The zwlr_data_control_source_v1 interface
130
+
*
131
+
* The wlr_data_control_source object is the source side of a
132
+
* wlr_data_control_offer. It is created by the source client in a data
133
+
* transfer and provides a way to describe the offered data and a way to
134
+
* respond to requests to transfer the data.
135
+
*/
136
+
extern const struct wl_interface zwlr_data_control_source_v1_interface;
137
+
#endif
138
+
#ifndef ZWLR_DATA_CONTROL_OFFER_V1_INTERFACE
139
+
#define ZWLR_DATA_CONTROL_OFFER_V1_INTERFACE
140
+
/**
141
+
* @page page_iface_zwlr_data_control_offer_v1 zwlr_data_control_offer_v1
142
+
* @section page_iface_zwlr_data_control_offer_v1_desc Description
143
+
*
144
+
* A wlr_data_control_offer represents a piece of data offered for transfer
145
+
* by another client (the source client). The offer describes the different
146
+
* MIME types that the data can be converted to and provides the mechanism
147
+
* for transferring the data directly from the source client.
148
+
* @section page_iface_zwlr_data_control_offer_v1_api API
149
+
* See @ref iface_zwlr_data_control_offer_v1.
150
+
*/
151
+
/**
152
+
* @defgroup iface_zwlr_data_control_offer_v1 The zwlr_data_control_offer_v1 interface
153
+
*
154
+
* A wlr_data_control_offer represents a piece of data offered for transfer
155
+
* by another client (the source client). The offer describes the different
156
+
* MIME types that the data can be converted to and provides the mechanism
157
+
* for transferring the data directly from the source client.
158
+
*/
159
+
extern const struct wl_interface zwlr_data_control_offer_v1_interface;
160
+
#endif
161
+
162
+
#define ZWLR_DATA_CONTROL_MANAGER_V1_CREATE_DATA_SOURCE 0
163
+
#define ZWLR_DATA_CONTROL_MANAGER_V1_GET_DATA_DEVICE 1
164
+
#define ZWLR_DATA_CONTROL_MANAGER_V1_DESTROY 2
165
+
166
+
167
+
/**
168
+
* @ingroup iface_zwlr_data_control_manager_v1
169
+
*/
170
+
#define ZWLR_DATA_CONTROL_MANAGER_V1_CREATE_DATA_SOURCE_SINCE_VERSION 1
171
+
/**
172
+
* @ingroup iface_zwlr_data_control_manager_v1
173
+
*/
174
+
#define ZWLR_DATA_CONTROL_MANAGER_V1_GET_DATA_DEVICE_SINCE_VERSION 1
175
+
/**
176
+
* @ingroup iface_zwlr_data_control_manager_v1
177
+
*/
178
+
#define ZWLR_DATA_CONTROL_MANAGER_V1_DESTROY_SINCE_VERSION 1
179
+
180
+
/** @ingroup iface_zwlr_data_control_manager_v1 */
181
+
static inline void
182
+
zwlr_data_control_manager_v1_set_user_data(struct zwlr_data_control_manager_v1 *zwlr_data_control_manager_v1, void *user_data)
183
+
{
184
+
wl_proxy_set_user_data((struct wl_proxy *) zwlr_data_control_manager_v1, user_data);
185
+
}
186
+
187
+
/** @ingroup iface_zwlr_data_control_manager_v1 */
188
+
static inline void *
189
+
zwlr_data_control_manager_v1_get_user_data(struct zwlr_data_control_manager_v1 *zwlr_data_control_manager_v1)
190
+
{
191
+
return wl_proxy_get_user_data((struct wl_proxy *) zwlr_data_control_manager_v1);
192
+
}
193
+
194
+
static inline uint32_t
195
+
zwlr_data_control_manager_v1_get_version(struct zwlr_data_control_manager_v1 *zwlr_data_control_manager_v1)
196
+
{
197
+
return wl_proxy_get_version((struct wl_proxy *) zwlr_data_control_manager_v1);
198
+
}
199
+
200
+
/**
201
+
* @ingroup iface_zwlr_data_control_manager_v1
202
+
*
203
+
* Create a new data source.
204
+
*/
205
+
static inline struct zwlr_data_control_source_v1 *
206
+
zwlr_data_control_manager_v1_create_data_source(struct zwlr_data_control_manager_v1 *zwlr_data_control_manager_v1)
207
+
{
208
+
struct wl_proxy *id;
209
+
210
+
id = wl_proxy_marshal_flags((struct wl_proxy *) zwlr_data_control_manager_v1,
211
+
ZWLR_DATA_CONTROL_MANAGER_V1_CREATE_DATA_SOURCE, &zwlr_data_control_source_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwlr_data_control_manager_v1), 0, NULL);
212
+
213
+
return (struct zwlr_data_control_source_v1 *) id;
214
+
}
215
+
216
+
/**
217
+
* @ingroup iface_zwlr_data_control_manager_v1
218
+
*
219
+
* Create a data device that can be used to manage a seat's selection.
220
+
*/
221
+
static inline struct zwlr_data_control_device_v1 *
222
+
zwlr_data_control_manager_v1_get_data_device(struct zwlr_data_control_manager_v1 *zwlr_data_control_manager_v1, struct wl_seat *seat)
223
+
{
224
+
struct wl_proxy *id;
225
+
226
+
id = wl_proxy_marshal_flags((struct wl_proxy *) zwlr_data_control_manager_v1,
227
+
ZWLR_DATA_CONTROL_MANAGER_V1_GET_DATA_DEVICE, &zwlr_data_control_device_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwlr_data_control_manager_v1), 0, NULL, seat);
228
+
229
+
return (struct zwlr_data_control_device_v1 *) id;
230
+
}
231
+
232
+
/**
233
+
* @ingroup iface_zwlr_data_control_manager_v1
234
+
*
235
+
* All objects created by the manager will still remain valid, until their
236
+
* appropriate destroy request has been called.
237
+
*/
238
+
static inline void
239
+
zwlr_data_control_manager_v1_destroy(struct zwlr_data_control_manager_v1 *zwlr_data_control_manager_v1)
240
+
{
241
+
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_data_control_manager_v1,
242
+
ZWLR_DATA_CONTROL_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_data_control_manager_v1), WL_MARSHAL_FLAG_DESTROY);
243
+
}
244
+
245
+
#ifndef ZWLR_DATA_CONTROL_DEVICE_V1_ERROR_ENUM
246
+
#define ZWLR_DATA_CONTROL_DEVICE_V1_ERROR_ENUM
247
+
enum zwlr_data_control_device_v1_error {
248
+
/**
249
+
* source given to set_selection or set_primary_selection was already used before
250
+
*/
251
+
ZWLR_DATA_CONTROL_DEVICE_V1_ERROR_USED_SOURCE = 1,
252
+
};
253
+
#endif /* ZWLR_DATA_CONTROL_DEVICE_V1_ERROR_ENUM */
254
+
255
+
/**
256
+
* @ingroup iface_zwlr_data_control_device_v1
257
+
* @struct zwlr_data_control_device_v1_listener
258
+
*/
259
+
struct zwlr_data_control_device_v1_listener {
260
+
/**
261
+
* introduce a new wlr_data_control_offer
262
+
*
263
+
* The data_offer event introduces a new wlr_data_control_offer
264
+
* object, which will subsequently be used in either the
265
+
* wlr_data_control_device.selection event (for the regular
266
+
* clipboard selections) or the
267
+
* wlr_data_control_device.primary_selection event (for the primary
268
+
* clipboard selections). Immediately following the
269
+
* wlr_data_control_device.data_offer event, the new data_offer
270
+
* object will send out wlr_data_control_offer.offer events to
271
+
* describe the MIME types it offers.
272
+
*/
273
+
void (*data_offer)(void *data,
274
+
struct zwlr_data_control_device_v1 *zwlr_data_control_device_v1,
275
+
struct zwlr_data_control_offer_v1 *id);
276
+
/**
277
+
* advertise new selection
278
+
*
279
+
* The selection event is sent out to notify the client of a new
280
+
* wlr_data_control_offer for the selection for this device. The
281
+
* wlr_data_control_device.data_offer and the
282
+
* wlr_data_control_offer.offer events are sent out immediately
283
+
* before this event to introduce the data offer object. The
284
+
* selection event is sent to a client when a new selection is set.
285
+
* The wlr_data_control_offer is valid until a new
286
+
* wlr_data_control_offer or NULL is received. The client must
287
+
* destroy the previous selection wlr_data_control_offer, if any,
288
+
* upon receiving this event.
289
+
*
290
+
* The first selection event is sent upon binding the
291
+
* wlr_data_control_device object.
292
+
*/
293
+
void (*selection)(void *data,
294
+
struct zwlr_data_control_device_v1 *zwlr_data_control_device_v1,
295
+
struct zwlr_data_control_offer_v1 *id);
296
+
/**
297
+
* this data control is no longer valid
298
+
*
299
+
* This data control object is no longer valid and should be
300
+
* destroyed by the client.
301
+
*/
302
+
void (*finished)(void *data,
303
+
struct zwlr_data_control_device_v1 *zwlr_data_control_device_v1);
304
+
/**
305
+
* advertise new primary selection
306
+
*
307
+
* The primary_selection event is sent out to notify the client
308
+
* of a new wlr_data_control_offer for the primary selection for
309
+
* this device. The wlr_data_control_device.data_offer and the
310
+
* wlr_data_control_offer.offer events are sent out immediately
311
+
* before this event to introduce the data offer object. The
312
+
* primary_selection event is sent to a client when a new primary
313
+
* selection is set. The wlr_data_control_offer is valid until a
314
+
* new wlr_data_control_offer or NULL is received. The client must
315
+
* destroy the previous primary selection wlr_data_control_offer,
316
+
* if any, upon receiving this event.
317
+
*
318
+
* If the compositor supports primary selection, the first
319
+
* primary_selection event is sent upon binding the
320
+
* wlr_data_control_device object.
321
+
* @since 2
322
+
*/
323
+
void (*primary_selection)(void *data,
324
+
struct zwlr_data_control_device_v1 *zwlr_data_control_device_v1,
325
+
struct zwlr_data_control_offer_v1 *id);
326
+
};
327
+
328
+
/**
329
+
* @ingroup iface_zwlr_data_control_device_v1
330
+
*/
331
+
static inline int
332
+
zwlr_data_control_device_v1_add_listener(struct zwlr_data_control_device_v1 *zwlr_data_control_device_v1,
333
+
const struct zwlr_data_control_device_v1_listener *listener, void *data)
334
+
{
335
+
return wl_proxy_add_listener((struct wl_proxy *) zwlr_data_control_device_v1,
336
+
(void (**)(void)) listener, data);
337
+
}
338
+
339
+
#define ZWLR_DATA_CONTROL_DEVICE_V1_SET_SELECTION 0
340
+
#define ZWLR_DATA_CONTROL_DEVICE_V1_DESTROY 1
341
+
#define ZWLR_DATA_CONTROL_DEVICE_V1_SET_PRIMARY_SELECTION 2
342
+
343
+
/**
344
+
* @ingroup iface_zwlr_data_control_device_v1
345
+
*/
346
+
#define ZWLR_DATA_CONTROL_DEVICE_V1_DATA_OFFER_SINCE_VERSION 1
347
+
/**
348
+
* @ingroup iface_zwlr_data_control_device_v1
349
+
*/
350
+
#define ZWLR_DATA_CONTROL_DEVICE_V1_SELECTION_SINCE_VERSION 1
351
+
/**
352
+
* @ingroup iface_zwlr_data_control_device_v1
353
+
*/
354
+
#define ZWLR_DATA_CONTROL_DEVICE_V1_FINISHED_SINCE_VERSION 1
355
+
/**
356
+
* @ingroup iface_zwlr_data_control_device_v1
357
+
*/
358
+
#define ZWLR_DATA_CONTROL_DEVICE_V1_PRIMARY_SELECTION_SINCE_VERSION 2
359
+
360
+
/**
361
+
* @ingroup iface_zwlr_data_control_device_v1
362
+
*/
363
+
#define ZWLR_DATA_CONTROL_DEVICE_V1_SET_SELECTION_SINCE_VERSION 1
364
+
/**
365
+
* @ingroup iface_zwlr_data_control_device_v1
366
+
*/
367
+
#define ZWLR_DATA_CONTROL_DEVICE_V1_DESTROY_SINCE_VERSION 1
368
+
/**
369
+
* @ingroup iface_zwlr_data_control_device_v1
370
+
*/
371
+
#define ZWLR_DATA_CONTROL_DEVICE_V1_SET_PRIMARY_SELECTION_SINCE_VERSION 2
372
+
373
+
/** @ingroup iface_zwlr_data_control_device_v1 */
374
+
static inline void
375
+
zwlr_data_control_device_v1_set_user_data(struct zwlr_data_control_device_v1 *zwlr_data_control_device_v1, void *user_data)
376
+
{
377
+
wl_proxy_set_user_data((struct wl_proxy *) zwlr_data_control_device_v1, user_data);
378
+
}
379
+
380
+
/** @ingroup iface_zwlr_data_control_device_v1 */
381
+
static inline void *
382
+
zwlr_data_control_device_v1_get_user_data(struct zwlr_data_control_device_v1 *zwlr_data_control_device_v1)
383
+
{
384
+
return wl_proxy_get_user_data((struct wl_proxy *) zwlr_data_control_device_v1);
385
+
}
386
+
387
+
static inline uint32_t
388
+
zwlr_data_control_device_v1_get_version(struct zwlr_data_control_device_v1 *zwlr_data_control_device_v1)
389
+
{
390
+
return wl_proxy_get_version((struct wl_proxy *) zwlr_data_control_device_v1);
391
+
}
392
+
393
+
/**
394
+
* @ingroup iface_zwlr_data_control_device_v1
395
+
*
396
+
* This request asks the compositor to set the selection to the data from
397
+
* the source on behalf of the client.
398
+
*
399
+
* The given source may not be used in any further set_selection or
400
+
* set_primary_selection requests. Attempting to use a previously used
401
+
* source is a protocol error.
402
+
*
403
+
* To unset the selection, set the source to NULL.
404
+
*/
405
+
static inline void
406
+
zwlr_data_control_device_v1_set_selection(struct zwlr_data_control_device_v1 *zwlr_data_control_device_v1, struct zwlr_data_control_source_v1 *source)
407
+
{
408
+
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_data_control_device_v1,
409
+
ZWLR_DATA_CONTROL_DEVICE_V1_SET_SELECTION, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_data_control_device_v1), 0, source);
410
+
}
411
+
412
+
/**
413
+
* @ingroup iface_zwlr_data_control_device_v1
414
+
*
415
+
* Destroys the data device object.
416
+
*/
417
+
static inline void
418
+
zwlr_data_control_device_v1_destroy(struct zwlr_data_control_device_v1 *zwlr_data_control_device_v1)
419
+
{
420
+
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_data_control_device_v1,
421
+
ZWLR_DATA_CONTROL_DEVICE_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_data_control_device_v1), WL_MARSHAL_FLAG_DESTROY);
422
+
}
423
+
424
+
/**
425
+
* @ingroup iface_zwlr_data_control_device_v1
426
+
*
427
+
* This request asks the compositor to set the primary selection to the
428
+
* data from the source on behalf of the client.
429
+
*
430
+
* The given source may not be used in any further set_selection or
431
+
* set_primary_selection requests. Attempting to use a previously used
432
+
* source is a protocol error.
433
+
*
434
+
* To unset the primary selection, set the source to NULL.
435
+
*
436
+
* The compositor will ignore this request if it does not support primary
437
+
* selection.
438
+
*/
439
+
static inline void
440
+
zwlr_data_control_device_v1_set_primary_selection(struct zwlr_data_control_device_v1 *zwlr_data_control_device_v1, struct zwlr_data_control_source_v1 *source)
441
+
{
442
+
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_data_control_device_v1,
443
+
ZWLR_DATA_CONTROL_DEVICE_V1_SET_PRIMARY_SELECTION, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_data_control_device_v1), 0, source);
444
+
}
445
+
446
+
#ifndef ZWLR_DATA_CONTROL_SOURCE_V1_ERROR_ENUM
447
+
#define ZWLR_DATA_CONTROL_SOURCE_V1_ERROR_ENUM
448
+
enum zwlr_data_control_source_v1_error {
449
+
/**
450
+
* offer sent after wlr_data_control_device.set_selection
451
+
*/
452
+
ZWLR_DATA_CONTROL_SOURCE_V1_ERROR_INVALID_OFFER = 1,
453
+
};
454
+
#endif /* ZWLR_DATA_CONTROL_SOURCE_V1_ERROR_ENUM */
455
+
456
+
/**
457
+
* @ingroup iface_zwlr_data_control_source_v1
458
+
* @struct zwlr_data_control_source_v1_listener
459
+
*/
460
+
struct zwlr_data_control_source_v1_listener {
461
+
/**
462
+
* send the data
463
+
*
464
+
* Request for data from the client. Send the data as the
465
+
* specified MIME type over the passed file descriptor, then close
466
+
* it.
467
+
* @param mime_type MIME type for the data
468
+
* @param fd file descriptor for the data
469
+
*/
470
+
void (*send)(void *data,
471
+
struct zwlr_data_control_source_v1 *zwlr_data_control_source_v1,
472
+
const char *mime_type,
473
+
int32_t fd);
474
+
/**
475
+
* selection was cancelled
476
+
*
477
+
* This data source is no longer valid. The data source has been
478
+
* replaced by another data source.
479
+
*
480
+
* The client should clean up and destroy this data source.
481
+
*/
482
+
void (*cancelled)(void *data,
483
+
struct zwlr_data_control_source_v1 *zwlr_data_control_source_v1);
484
+
};
485
+
486
+
/**
487
+
* @ingroup iface_zwlr_data_control_source_v1
488
+
*/
489
+
static inline int
490
+
zwlr_data_control_source_v1_add_listener(struct zwlr_data_control_source_v1 *zwlr_data_control_source_v1,
491
+
const struct zwlr_data_control_source_v1_listener *listener, void *data)
492
+
{
493
+
return wl_proxy_add_listener((struct wl_proxy *) zwlr_data_control_source_v1,
494
+
(void (**)(void)) listener, data);
495
+
}
496
+
497
+
#define ZWLR_DATA_CONTROL_SOURCE_V1_OFFER 0
498
+
#define ZWLR_DATA_CONTROL_SOURCE_V1_DESTROY 1
499
+
500
+
/**
501
+
* @ingroup iface_zwlr_data_control_source_v1
502
+
*/
503
+
#define ZWLR_DATA_CONTROL_SOURCE_V1_SEND_SINCE_VERSION 1
504
+
/**
505
+
* @ingroup iface_zwlr_data_control_source_v1
506
+
*/
507
+
#define ZWLR_DATA_CONTROL_SOURCE_V1_CANCELLED_SINCE_VERSION 1
508
+
509
+
/**
510
+
* @ingroup iface_zwlr_data_control_source_v1
511
+
*/
512
+
#define ZWLR_DATA_CONTROL_SOURCE_V1_OFFER_SINCE_VERSION 1
513
+
/**
514
+
* @ingroup iface_zwlr_data_control_source_v1
515
+
*/
516
+
#define ZWLR_DATA_CONTROL_SOURCE_V1_DESTROY_SINCE_VERSION 1
517
+
518
+
/** @ingroup iface_zwlr_data_control_source_v1 */
519
+
static inline void
520
+
zwlr_data_control_source_v1_set_user_data(struct zwlr_data_control_source_v1 *zwlr_data_control_source_v1, void *user_data)
521
+
{
522
+
wl_proxy_set_user_data((struct wl_proxy *) zwlr_data_control_source_v1, user_data);
523
+
}
524
+
525
+
/** @ingroup iface_zwlr_data_control_source_v1 */
526
+
static inline void *
527
+
zwlr_data_control_source_v1_get_user_data(struct zwlr_data_control_source_v1 *zwlr_data_control_source_v1)
528
+
{
529
+
return wl_proxy_get_user_data((struct wl_proxy *) zwlr_data_control_source_v1);
530
+
}
531
+
532
+
static inline uint32_t
533
+
zwlr_data_control_source_v1_get_version(struct zwlr_data_control_source_v1 *zwlr_data_control_source_v1)
534
+
{
535
+
return wl_proxy_get_version((struct wl_proxy *) zwlr_data_control_source_v1);
536
+
}
537
+
538
+
/**
539
+
* @ingroup iface_zwlr_data_control_source_v1
540
+
*
541
+
* This request adds a MIME type to the set of MIME types advertised to
542
+
* targets. Can be called several times to offer multiple types.
543
+
*
544
+
* Calling this after wlr_data_control_device.set_selection is a protocol
545
+
* error.
546
+
*/
547
+
static inline void
548
+
zwlr_data_control_source_v1_offer(struct zwlr_data_control_source_v1 *zwlr_data_control_source_v1, const char *mime_type)
549
+
{
550
+
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_data_control_source_v1,
551
+
ZWLR_DATA_CONTROL_SOURCE_V1_OFFER, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_data_control_source_v1), 0, mime_type);
552
+
}
553
+
554
+
/**
555
+
* @ingroup iface_zwlr_data_control_source_v1
556
+
*
557
+
* Destroys the data source object.
558
+
*/
559
+
static inline void
560
+
zwlr_data_control_source_v1_destroy(struct zwlr_data_control_source_v1 *zwlr_data_control_source_v1)
561
+
{
562
+
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_data_control_source_v1,
563
+
ZWLR_DATA_CONTROL_SOURCE_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_data_control_source_v1), WL_MARSHAL_FLAG_DESTROY);
564
+
}
565
+
566
+
/**
567
+
* @ingroup iface_zwlr_data_control_offer_v1
568
+
* @struct zwlr_data_control_offer_v1_listener
569
+
*/
570
+
struct zwlr_data_control_offer_v1_listener {
571
+
/**
572
+
* advertise offered MIME type
573
+
*
574
+
* Sent immediately after creating the wlr_data_control_offer
575
+
* object. One event per offered MIME type.
576
+
* @param mime_type offered MIME type
577
+
*/
578
+
void (*offer)(void *data,
579
+
struct zwlr_data_control_offer_v1 *zwlr_data_control_offer_v1,
580
+
const char *mime_type);
581
+
};
582
+
583
+
/**
584
+
* @ingroup iface_zwlr_data_control_offer_v1
585
+
*/
586
+
static inline int
587
+
zwlr_data_control_offer_v1_add_listener(struct zwlr_data_control_offer_v1 *zwlr_data_control_offer_v1,
588
+
const struct zwlr_data_control_offer_v1_listener *listener, void *data)
589
+
{
590
+
return wl_proxy_add_listener((struct wl_proxy *) zwlr_data_control_offer_v1,
591
+
(void (**)(void)) listener, data);
592
+
}
593
+
594
+
#define ZWLR_DATA_CONTROL_OFFER_V1_RECEIVE 0
595
+
#define ZWLR_DATA_CONTROL_OFFER_V1_DESTROY 1
596
+
597
+
/**
598
+
* @ingroup iface_zwlr_data_control_offer_v1
599
+
*/
600
+
#define ZWLR_DATA_CONTROL_OFFER_V1_OFFER_SINCE_VERSION 1
601
+
602
+
/**
603
+
* @ingroup iface_zwlr_data_control_offer_v1
604
+
*/
605
+
#define ZWLR_DATA_CONTROL_OFFER_V1_RECEIVE_SINCE_VERSION 1
606
+
/**
607
+
* @ingroup iface_zwlr_data_control_offer_v1
608
+
*/
609
+
#define ZWLR_DATA_CONTROL_OFFER_V1_DESTROY_SINCE_VERSION 1
610
+
611
+
/** @ingroup iface_zwlr_data_control_offer_v1 */
612
+
static inline void
613
+
zwlr_data_control_offer_v1_set_user_data(struct zwlr_data_control_offer_v1 *zwlr_data_control_offer_v1, void *user_data)
614
+
{
615
+
wl_proxy_set_user_data((struct wl_proxy *) zwlr_data_control_offer_v1, user_data);
616
+
}
617
+
618
+
/** @ingroup iface_zwlr_data_control_offer_v1 */
619
+
static inline void *
620
+
zwlr_data_control_offer_v1_get_user_data(struct zwlr_data_control_offer_v1 *zwlr_data_control_offer_v1)
621
+
{
622
+
return wl_proxy_get_user_data((struct wl_proxy *) zwlr_data_control_offer_v1);
623
+
}
624
+
625
+
static inline uint32_t
626
+
zwlr_data_control_offer_v1_get_version(struct zwlr_data_control_offer_v1 *zwlr_data_control_offer_v1)
627
+
{
628
+
return wl_proxy_get_version((struct wl_proxy *) zwlr_data_control_offer_v1);
629
+
}
630
+
631
+
/**
632
+
* @ingroup iface_zwlr_data_control_offer_v1
633
+
*
634
+
* To transfer the offered data, the client issues this request and
635
+
* indicates the MIME type it wants to receive. The transfer happens
636
+
* through the passed file descriptor (typically created with the pipe
637
+
* system call). The source client writes the data in the MIME type
638
+
* representation requested and then closes the file descriptor.
639
+
*
640
+
* The receiving client reads from the read end of the pipe until EOF and
641
+
* then closes its end, at which point the transfer is complete.
642
+
*
643
+
* This request may happen multiple times for different MIME types.
644
+
*/
645
+
static inline void
646
+
zwlr_data_control_offer_v1_receive(struct zwlr_data_control_offer_v1 *zwlr_data_control_offer_v1, const char *mime_type, int32_t fd)
647
+
{
648
+
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_data_control_offer_v1,
649
+
ZWLR_DATA_CONTROL_OFFER_V1_RECEIVE, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_data_control_offer_v1), 0, mime_type, fd);
650
+
}
651
+
652
+
/**
653
+
* @ingroup iface_zwlr_data_control_offer_v1
654
+
*
655
+
* Destroys the data offer object.
656
+
*/
657
+
static inline void
658
+
zwlr_data_control_offer_v1_destroy(struct zwlr_data_control_offer_v1 *zwlr_data_control_offer_v1)
659
+
{
660
+
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_data_control_offer_v1,
661
+
ZWLR_DATA_CONTROL_OFFER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_data_control_offer_v1), WL_MARSHAL_FLAG_DESTROY);
662
+
}
663
+
664
+
#ifdef __cplusplus
665
+
}
666
+
#endif
667
+
668
+
#endif
+184
internal/clipboard/xdg-shell.c
+184
internal/clipboard/xdg-shell.c
···
1
+
/* Generated by wayland-scanner 1.24.0 */
2
+
3
+
/*
4
+
* Copyright © 2008-2013 Kristian Høgsberg
5
+
* Copyright © 2013 Rafael Antognolli
6
+
* Copyright © 2013 Jasper St. Pierre
7
+
* Copyright © 2010-2013 Intel Corporation
8
+
* Copyright © 2015-2017 Samsung Electronics Co., Ltd
9
+
* Copyright © 2015-2017 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
+
*/
30
+
31
+
#include <stdbool.h>
32
+
#include <stdlib.h>
33
+
#include <stdint.h>
34
+
#include "wayland-util.h"
35
+
36
+
#ifndef __has_attribute
37
+
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
38
+
#endif
39
+
40
+
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
41
+
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
42
+
#else
43
+
#define WL_PRIVATE
44
+
#endif
45
+
46
+
extern const struct wl_interface wl_output_interface;
47
+
extern const struct wl_interface wl_seat_interface;
48
+
extern const struct wl_interface wl_surface_interface;
49
+
extern const struct wl_interface xdg_popup_interface;
50
+
extern const struct wl_interface xdg_positioner_interface;
51
+
extern const struct wl_interface xdg_surface_interface;
52
+
extern const struct wl_interface xdg_toplevel_interface;
53
+
54
+
static const struct wl_interface *xdg_shell_types[] = {
55
+
NULL,
56
+
NULL,
57
+
NULL,
58
+
NULL,
59
+
&xdg_positioner_interface,
60
+
&xdg_surface_interface,
61
+
&wl_surface_interface,
62
+
&xdg_toplevel_interface,
63
+
&xdg_popup_interface,
64
+
&xdg_surface_interface,
65
+
&xdg_positioner_interface,
66
+
&xdg_toplevel_interface,
67
+
&wl_seat_interface,
68
+
NULL,
69
+
NULL,
70
+
NULL,
71
+
&wl_seat_interface,
72
+
NULL,
73
+
&wl_seat_interface,
74
+
NULL,
75
+
NULL,
76
+
&wl_output_interface,
77
+
&wl_seat_interface,
78
+
NULL,
79
+
&xdg_positioner_interface,
80
+
NULL,
81
+
};
82
+
83
+
static const struct wl_message xdg_wm_base_requests[] = {
84
+
{ "destroy", "", xdg_shell_types + 0 },
85
+
{ "create_positioner", "n", xdg_shell_types + 4 },
86
+
{ "get_xdg_surface", "no", xdg_shell_types + 5 },
87
+
{ "pong", "u", xdg_shell_types + 0 },
88
+
};
89
+
90
+
static const struct wl_message xdg_wm_base_events[] = {
91
+
{ "ping", "u", xdg_shell_types + 0 },
92
+
};
93
+
94
+
WL_PRIVATE const struct wl_interface xdg_wm_base_interface = {
95
+
"xdg_wm_base", 7,
96
+
4, xdg_wm_base_requests,
97
+
1, xdg_wm_base_events,
98
+
};
99
+
100
+
static const struct wl_message xdg_positioner_requests[] = {
101
+
{ "destroy", "", xdg_shell_types + 0 },
102
+
{ "set_size", "ii", xdg_shell_types + 0 },
103
+
{ "set_anchor_rect", "iiii", xdg_shell_types + 0 },
104
+
{ "set_anchor", "u", xdg_shell_types + 0 },
105
+
{ "set_gravity", "u", xdg_shell_types + 0 },
106
+
{ "set_constraint_adjustment", "u", xdg_shell_types + 0 },
107
+
{ "set_offset", "ii", xdg_shell_types + 0 },
108
+
{ "set_reactive", "3", xdg_shell_types + 0 },
109
+
{ "set_parent_size", "3ii", xdg_shell_types + 0 },
110
+
{ "set_parent_configure", "3u", xdg_shell_types + 0 },
111
+
};
112
+
113
+
WL_PRIVATE const struct wl_interface xdg_positioner_interface = {
114
+
"xdg_positioner", 7,
115
+
10, xdg_positioner_requests,
116
+
0, NULL,
117
+
};
118
+
119
+
static const struct wl_message xdg_surface_requests[] = {
120
+
{ "destroy", "", xdg_shell_types + 0 },
121
+
{ "get_toplevel", "n", xdg_shell_types + 7 },
122
+
{ "get_popup", "n?oo", xdg_shell_types + 8 },
123
+
{ "set_window_geometry", "iiii", xdg_shell_types + 0 },
124
+
{ "ack_configure", "u", xdg_shell_types + 0 },
125
+
};
126
+
127
+
static const struct wl_message xdg_surface_events[] = {
128
+
{ "configure", "u", xdg_shell_types + 0 },
129
+
};
130
+
131
+
WL_PRIVATE const struct wl_interface xdg_surface_interface = {
132
+
"xdg_surface", 7,
133
+
5, xdg_surface_requests,
134
+
1, xdg_surface_events,
135
+
};
136
+
137
+
static const struct wl_message xdg_toplevel_requests[] = {
138
+
{ "destroy", "", xdg_shell_types + 0 },
139
+
{ "set_parent", "?o", xdg_shell_types + 11 },
140
+
{ "set_title", "s", xdg_shell_types + 0 },
141
+
{ "set_app_id", "s", xdg_shell_types + 0 },
142
+
{ "show_window_menu", "ouii", xdg_shell_types + 12 },
143
+
{ "move", "ou", xdg_shell_types + 16 },
144
+
{ "resize", "ouu", xdg_shell_types + 18 },
145
+
{ "set_max_size", "ii", xdg_shell_types + 0 },
146
+
{ "set_min_size", "ii", xdg_shell_types + 0 },
147
+
{ "set_maximized", "", xdg_shell_types + 0 },
148
+
{ "unset_maximized", "", xdg_shell_types + 0 },
149
+
{ "set_fullscreen", "?o", xdg_shell_types + 21 },
150
+
{ "unset_fullscreen", "", xdg_shell_types + 0 },
151
+
{ "set_minimized", "", xdg_shell_types + 0 },
152
+
};
153
+
154
+
static const struct wl_message xdg_toplevel_events[] = {
155
+
{ "configure", "iia", xdg_shell_types + 0 },
156
+
{ "close", "", xdg_shell_types + 0 },
157
+
{ "configure_bounds", "4ii", xdg_shell_types + 0 },
158
+
{ "wm_capabilities", "5a", xdg_shell_types + 0 },
159
+
};
160
+
161
+
WL_PRIVATE const struct wl_interface xdg_toplevel_interface = {
162
+
"xdg_toplevel", 7,
163
+
14, xdg_toplevel_requests,
164
+
4, xdg_toplevel_events,
165
+
};
166
+
167
+
static const struct wl_message xdg_popup_requests[] = {
168
+
{ "destroy", "", xdg_shell_types + 0 },
169
+
{ "grab", "ou", xdg_shell_types + 22 },
170
+
{ "reposition", "3ou", xdg_shell_types + 24 },
171
+
};
172
+
173
+
static const struct wl_message xdg_popup_events[] = {
174
+
{ "configure", "iiii", xdg_shell_types + 0 },
175
+
{ "popup_done", "", xdg_shell_types + 0 },
176
+
{ "repositioned", "3u", xdg_shell_types + 0 },
177
+
};
178
+
179
+
WL_PRIVATE const struct wl_interface xdg_popup_interface = {
180
+
"xdg_popup", 7,
181
+
3, xdg_popup_requests,
182
+
3, xdg_popup_events,
183
+
};
184
+
+2384
internal/clipboard/xdg-shell.h
+2384
internal/clipboard/xdg-shell.h
···
1
+
/* Generated by wayland-scanner 1.24.0 */
2
+
3
+
#ifndef XDG_SHELL_CLIENT_PROTOCOL_H
4
+
#define XDG_SHELL_CLIENT_PROTOCOL_H
5
+
6
+
#include <stdint.h>
7
+
#include <stddef.h>
8
+
#include "wayland-client.h"
9
+
10
+
#ifdef __cplusplus
11
+
extern "C" {
12
+
#endif
13
+
14
+
/**
15
+
* @page page_xdg_shell The xdg_shell protocol
16
+
* @section page_ifaces_xdg_shell Interfaces
17
+
* - @subpage page_iface_xdg_wm_base - create desktop-style surfaces
18
+
* - @subpage page_iface_xdg_positioner - child surface positioner
19
+
* - @subpage page_iface_xdg_surface - desktop user interface surface base interface
20
+
* - @subpage page_iface_xdg_toplevel - toplevel surface
21
+
* - @subpage page_iface_xdg_popup - short-lived, popup surfaces for menus
22
+
* @section page_copyright_xdg_shell Copyright
23
+
* <pre>
24
+
*
25
+
* Copyright © 2008-2013 Kristian Høgsberg
26
+
* Copyright © 2013 Rafael Antognolli
27
+
* Copyright © 2013 Jasper St. Pierre
28
+
* Copyright © 2010-2013 Intel Corporation
29
+
* Copyright © 2015-2017 Samsung Electronics Co., Ltd
30
+
* Copyright © 2015-2017 Red Hat Inc.
31
+
*
32
+
* Permission is hereby granted, free of charge, to any person obtaining a
33
+
* copy of this software and associated documentation files (the "Software"),
34
+
* to deal in the Software without restriction, including without limitation
35
+
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
36
+
* and/or sell copies of the Software, and to permit persons to whom the
37
+
* Software is furnished to do so, subject to the following conditions:
38
+
*
39
+
* The above copyright notice and this permission notice (including the next
40
+
* paragraph) shall be included in all copies or substantial portions of the
41
+
* Software.
42
+
*
43
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
44
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
45
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
46
+
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
47
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
48
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
49
+
* DEALINGS IN THE SOFTWARE.
50
+
* </pre>
51
+
*/
52
+
struct wl_output;
53
+
struct wl_seat;
54
+
struct wl_surface;
55
+
struct xdg_popup;
56
+
struct xdg_positioner;
57
+
struct xdg_surface;
58
+
struct xdg_toplevel;
59
+
struct xdg_wm_base;
60
+
61
+
#ifndef XDG_WM_BASE_INTERFACE
62
+
#define XDG_WM_BASE_INTERFACE
63
+
/**
64
+
* @page page_iface_xdg_wm_base xdg_wm_base
65
+
* @section page_iface_xdg_wm_base_desc Description
66
+
*
67
+
* The xdg_wm_base interface is exposed as a global object enabling clients
68
+
* to turn their wl_surfaces into windows in a desktop environment. It
69
+
* defines the basic functionality needed for clients and the compositor to
70
+
* create windows that can be dragged, resized, maximized, etc, as well as
71
+
* creating transient windows such as popup menus.
72
+
* @section page_iface_xdg_wm_base_api API
73
+
* See @ref iface_xdg_wm_base.
74
+
*/
75
+
/**
76
+
* @defgroup iface_xdg_wm_base The xdg_wm_base interface
77
+
*
78
+
* The xdg_wm_base interface is exposed as a global object enabling clients
79
+
* to turn their wl_surfaces into windows in a desktop environment. It
80
+
* defines the basic functionality needed for clients and the compositor to
81
+
* create windows that can be dragged, resized, maximized, etc, as well as
82
+
* creating transient windows such as popup menus.
83
+
*/
84
+
extern const struct wl_interface xdg_wm_base_interface;
85
+
#endif
86
+
#ifndef XDG_POSITIONER_INTERFACE
87
+
#define XDG_POSITIONER_INTERFACE
88
+
/**
89
+
* @page page_iface_xdg_positioner xdg_positioner
90
+
* @section page_iface_xdg_positioner_desc Description
91
+
*
92
+
* The xdg_positioner provides a collection of rules for the placement of a
93
+
* child surface relative to a parent surface. Rules can be defined to ensure
94
+
* the child surface remains within the visible area's borders, and to
95
+
* specify how the child surface changes its position, such as sliding along
96
+
* an axis, or flipping around a rectangle. These positioner-created rules are
97
+
* constrained by the requirement that a child surface must intersect with or
98
+
* be at least partially adjacent to its parent surface.
99
+
*
100
+
* See the various requests for details about possible rules.
101
+
*
102
+
* At the time of the request, the compositor makes a copy of the rules
103
+
* specified by the xdg_positioner. Thus, after the request is complete the
104
+
* xdg_positioner object can be destroyed or reused; further changes to the
105
+
* object will have no effect on previous usages.
106
+
*
107
+
* For an xdg_positioner object to be considered complete, it must have a
108
+
* non-zero size set by set_size, and a non-zero anchor rectangle set by
109
+
* set_anchor_rect. Passing an incomplete xdg_positioner object when
110
+
* positioning a surface raises an invalid_positioner error.
111
+
* @section page_iface_xdg_positioner_api API
112
+
* See @ref iface_xdg_positioner.
113
+
*/
114
+
/**
115
+
* @defgroup iface_xdg_positioner The xdg_positioner interface
116
+
*
117
+
* The xdg_positioner provides a collection of rules for the placement of a
118
+
* child surface relative to a parent surface. Rules can be defined to ensure
119
+
* the child surface remains within the visible area's borders, and to
120
+
* specify how the child surface changes its position, such as sliding along
121
+
* an axis, or flipping around a rectangle. These positioner-created rules are
122
+
* constrained by the requirement that a child surface must intersect with or
123
+
* be at least partially adjacent to its parent surface.
124
+
*
125
+
* See the various requests for details about possible rules.
126
+
*
127
+
* At the time of the request, the compositor makes a copy of the rules
128
+
* specified by the xdg_positioner. Thus, after the request is complete the
129
+
* xdg_positioner object can be destroyed or reused; further changes to the
130
+
* object will have no effect on previous usages.
131
+
*
132
+
* For an xdg_positioner object to be considered complete, it must have a
133
+
* non-zero size set by set_size, and a non-zero anchor rectangle set by
134
+
* set_anchor_rect. Passing an incomplete xdg_positioner object when
135
+
* positioning a surface raises an invalid_positioner error.
136
+
*/
137
+
extern const struct wl_interface xdg_positioner_interface;
138
+
#endif
139
+
#ifndef XDG_SURFACE_INTERFACE
140
+
#define XDG_SURFACE_INTERFACE
141
+
/**
142
+
* @page page_iface_xdg_surface xdg_surface
143
+
* @section page_iface_xdg_surface_desc Description
144
+
*
145
+
* An interface that may be implemented by a wl_surface, for
146
+
* implementations that provide a desktop-style user interface.
147
+
*
148
+
* It provides a base set of functionality required to construct user
149
+
* interface elements requiring management by the compositor, such as
150
+
* toplevel windows, menus, etc. The types of functionality are split into
151
+
* xdg_surface roles.
152
+
*
153
+
* Creating an xdg_surface does not set the role for a wl_surface. In order
154
+
* to map an xdg_surface, the client must create a role-specific object
155
+
* using, e.g., get_toplevel, get_popup. The wl_surface for any given
156
+
* xdg_surface can have at most one role, and may not be assigned any role
157
+
* not based on xdg_surface.
158
+
*
159
+
* A role must be assigned before any other requests are made to the
160
+
* xdg_surface object.
161
+
*
162
+
* The client must call wl_surface.commit on the corresponding wl_surface
163
+
* for the xdg_surface state to take effect.
164
+
*
165
+
* Creating an xdg_surface from a wl_surface which has a buffer attached or
166
+
* committed is a client error, and any attempts by a client to attach or
167
+
* manipulate a buffer prior to the first xdg_surface.configure call must
168
+
* also be treated as errors.
169
+
*
170
+
* After creating a role-specific object and setting it up (e.g. by sending
171
+
* the title, app ID, size constraints, parent, etc), the client must
172
+
* perform an initial commit without any buffer attached. The compositor
173
+
* will reply with initial wl_surface state such as
174
+
* wl_surface.preferred_buffer_scale followed by an xdg_surface.configure
175
+
* event. The client must acknowledge it and is then allowed to attach a
176
+
* buffer to map the surface.
177
+
*
178
+
* Mapping an xdg_surface-based role surface is defined as making it
179
+
* possible for the surface to be shown by the compositor. Note that
180
+
* a mapped surface is not guaranteed to be visible once it is mapped.
181
+
*
182
+
* For an xdg_surface to be mapped by the compositor, the following
183
+
* conditions must be met:
184
+
* (1) the client has assigned an xdg_surface-based role to the surface
185
+
* (2) the client has set and committed the xdg_surface state and the
186
+
* role-dependent state to the surface
187
+
* (3) the client has committed a buffer to the surface
188
+
*
189
+
* A newly-unmapped surface is considered to have met condition (1) out
190
+
* of the 3 required conditions for mapping a surface if its role surface
191
+
* has not been destroyed, i.e. the client must perform the initial commit
192
+
* again before attaching a buffer.
193
+
* @section page_iface_xdg_surface_api API
194
+
* See @ref iface_xdg_surface.
195
+
*/
196
+
/**
197
+
* @defgroup iface_xdg_surface The xdg_surface interface
198
+
*
199
+
* An interface that may be implemented by a wl_surface, for
200
+
* implementations that provide a desktop-style user interface.
201
+
*
202
+
* It provides a base set of functionality required to construct user
203
+
* interface elements requiring management by the compositor, such as
204
+
* toplevel windows, menus, etc. The types of functionality are split into
205
+
* xdg_surface roles.
206
+
*
207
+
* Creating an xdg_surface does not set the role for a wl_surface. In order
208
+
* to map an xdg_surface, the client must create a role-specific object
209
+
* using, e.g., get_toplevel, get_popup. The wl_surface for any given
210
+
* xdg_surface can have at most one role, and may not be assigned any role
211
+
* not based on xdg_surface.
212
+
*
213
+
* A role must be assigned before any other requests are made to the
214
+
* xdg_surface object.
215
+
*
216
+
* The client must call wl_surface.commit on the corresponding wl_surface
217
+
* for the xdg_surface state to take effect.
218
+
*
219
+
* Creating an xdg_surface from a wl_surface which has a buffer attached or
220
+
* committed is a client error, and any attempts by a client to attach or
221
+
* manipulate a buffer prior to the first xdg_surface.configure call must
222
+
* also be treated as errors.
223
+
*
224
+
* After creating a role-specific object and setting it up (e.g. by sending
225
+
* the title, app ID, size constraints, parent, etc), the client must
226
+
* perform an initial commit without any buffer attached. The compositor
227
+
* will reply with initial wl_surface state such as
228
+
* wl_surface.preferred_buffer_scale followed by an xdg_surface.configure
229
+
* event. The client must acknowledge it and is then allowed to attach a
230
+
* buffer to map the surface.
231
+
*
232
+
* Mapping an xdg_surface-based role surface is defined as making it
233
+
* possible for the surface to be shown by the compositor. Note that
234
+
* a mapped surface is not guaranteed to be visible once it is mapped.
235
+
*
236
+
* For an xdg_surface to be mapped by the compositor, the following
237
+
* conditions must be met:
238
+
* (1) the client has assigned an xdg_surface-based role to the surface
239
+
* (2) the client has set and committed the xdg_surface state and the
240
+
* role-dependent state to the surface
241
+
* (3) the client has committed a buffer to the surface
242
+
*
243
+
* A newly-unmapped surface is considered to have met condition (1) out
244
+
* of the 3 required conditions for mapping a surface if its role surface
245
+
* has not been destroyed, i.e. the client must perform the initial commit
246
+
* again before attaching a buffer.
247
+
*/
248
+
extern const struct wl_interface xdg_surface_interface;
249
+
#endif
250
+
#ifndef XDG_TOPLEVEL_INTERFACE
251
+
#define XDG_TOPLEVEL_INTERFACE
252
+
/**
253
+
* @page page_iface_xdg_toplevel xdg_toplevel
254
+
* @section page_iface_xdg_toplevel_desc Description
255
+
*
256
+
* This interface defines an xdg_surface role which allows a surface to,
257
+
* among other things, set window-like properties such as maximize,
258
+
* fullscreen, and minimize, set application-specific metadata like title and
259
+
* id, and well as trigger user interactive operations such as interactive
260
+
* resize and move.
261
+
*
262
+
* A xdg_toplevel by default is responsible for providing the full intended
263
+
* visual representation of the toplevel, which depending on the window
264
+
* state, may mean things like a title bar, window controls and drop shadow.
265
+
*
266
+
* Unmapping an xdg_toplevel means that the surface cannot be shown
267
+
* by the compositor until it is explicitly mapped again.
268
+
* All active operations (e.g., move, resize) are canceled and all
269
+
* attributes (e.g. title, state, stacking, ...) are discarded for
270
+
* an xdg_toplevel surface when it is unmapped. The xdg_toplevel returns to
271
+
* the state it had right after xdg_surface.get_toplevel. The client
272
+
* can re-map the toplevel by performing a commit without any buffer
273
+
* attached, waiting for a configure event and handling it as usual (see
274
+
* xdg_surface description).
275
+
*
276
+
* Attaching a null buffer to a toplevel unmaps the surface.
277
+
* @section page_iface_xdg_toplevel_api API
278
+
* See @ref iface_xdg_toplevel.
279
+
*/
280
+
/**
281
+
* @defgroup iface_xdg_toplevel The xdg_toplevel interface
282
+
*
283
+
* This interface defines an xdg_surface role which allows a surface to,
284
+
* among other things, set window-like properties such as maximize,
285
+
* fullscreen, and minimize, set application-specific metadata like title and
286
+
* id, and well as trigger user interactive operations such as interactive
287
+
* resize and move.
288
+
*
289
+
* A xdg_toplevel by default is responsible for providing the full intended
290
+
* visual representation of the toplevel, which depending on the window
291
+
* state, may mean things like a title bar, window controls and drop shadow.
292
+
*
293
+
* Unmapping an xdg_toplevel means that the surface cannot be shown
294
+
* by the compositor until it is explicitly mapped again.
295
+
* All active operations (e.g., move, resize) are canceled and all
296
+
* attributes (e.g. title, state, stacking, ...) are discarded for
297
+
* an xdg_toplevel surface when it is unmapped. The xdg_toplevel returns to
298
+
* the state it had right after xdg_surface.get_toplevel. The client
299
+
* can re-map the toplevel by performing a commit without any buffer
300
+
* attached, waiting for a configure event and handling it as usual (see
301
+
* xdg_surface description).
302
+
*
303
+
* Attaching a null buffer to a toplevel unmaps the surface.
304
+
*/
305
+
extern const struct wl_interface xdg_toplevel_interface;
306
+
#endif
307
+
#ifndef XDG_POPUP_INTERFACE
308
+
#define XDG_POPUP_INTERFACE
309
+
/**
310
+
* @page page_iface_xdg_popup xdg_popup
311
+
* @section page_iface_xdg_popup_desc Description
312
+
*
313
+
* A popup surface is a short-lived, temporary surface. It can be used to
314
+
* implement for example menus, popovers, tooltips and other similar user
315
+
* interface concepts.
316
+
*
317
+
* A popup can be made to take an explicit grab. See xdg_popup.grab for
318
+
* details.
319
+
*
320
+
* When the popup is dismissed, a popup_done event will be sent out, and at
321
+
* the same time the surface will be unmapped. See the xdg_popup.popup_done
322
+
* event for details.
323
+
*
324
+
* Explicitly destroying the xdg_popup object will also dismiss the popup and
325
+
* unmap the surface. Clients that want to dismiss the popup when another
326
+
* surface of their own is clicked should dismiss the popup using the destroy
327
+
* request.
328
+
*
329
+
* A newly created xdg_popup will be stacked on top of all previously created
330
+
* xdg_popup surfaces associated with the same xdg_toplevel.
331
+
*
332
+
* The parent of an xdg_popup must be mapped (see the xdg_surface
333
+
* description) before the xdg_popup itself.
334
+
*
335
+
* The client must call wl_surface.commit on the corresponding wl_surface
336
+
* for the xdg_popup state to take effect.
337
+
* @section page_iface_xdg_popup_api API
338
+
* See @ref iface_xdg_popup.
339
+
*/
340
+
/**
341
+
* @defgroup iface_xdg_popup The xdg_popup interface
342
+
*
343
+
* A popup surface is a short-lived, temporary surface. It can be used to
344
+
* implement for example menus, popovers, tooltips and other similar user
345
+
* interface concepts.
346
+
*
347
+
* A popup can be made to take an explicit grab. See xdg_popup.grab for
348
+
* details.
349
+
*
350
+
* When the popup is dismissed, a popup_done event will be sent out, and at
351
+
* the same time the surface will be unmapped. See the xdg_popup.popup_done
352
+
* event for details.
353
+
*
354
+
* Explicitly destroying the xdg_popup object will also dismiss the popup and
355
+
* unmap the surface. Clients that want to dismiss the popup when another
356
+
* surface of their own is clicked should dismiss the popup using the destroy
357
+
* request.
358
+
*
359
+
* A newly created xdg_popup will be stacked on top of all previously created
360
+
* xdg_popup surfaces associated with the same xdg_toplevel.
361
+
*
362
+
* The parent of an xdg_popup must be mapped (see the xdg_surface
363
+
* description) before the xdg_popup itself.
364
+
*
365
+
* The client must call wl_surface.commit on the corresponding wl_surface
366
+
* for the xdg_popup state to take effect.
367
+
*/
368
+
extern const struct wl_interface xdg_popup_interface;
369
+
#endif
370
+
371
+
#ifndef XDG_WM_BASE_ERROR_ENUM
372
+
#define XDG_WM_BASE_ERROR_ENUM
373
+
enum xdg_wm_base_error {
374
+
/**
375
+
* given wl_surface has another role
376
+
*/
377
+
XDG_WM_BASE_ERROR_ROLE = 0,
378
+
/**
379
+
* xdg_wm_base was destroyed before children
380
+
*/
381
+
XDG_WM_BASE_ERROR_DEFUNCT_SURFACES = 1,
382
+
/**
383
+
* the client tried to map or destroy a non-topmost popup
384
+
*/
385
+
XDG_WM_BASE_ERROR_NOT_THE_TOPMOST_POPUP = 2,
386
+
/**
387
+
* the client specified an invalid popup parent surface
388
+
*/
389
+
XDG_WM_BASE_ERROR_INVALID_POPUP_PARENT = 3,
390
+
/**
391
+
* the client provided an invalid surface state
392
+
*/
393
+
XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE = 4,
394
+
/**
395
+
* the client provided an invalid positioner
396
+
*/
397
+
XDG_WM_BASE_ERROR_INVALID_POSITIONER = 5,
398
+
/**
399
+
* the client didn’t respond to a ping event in time
400
+
*/
401
+
XDG_WM_BASE_ERROR_UNRESPONSIVE = 6,
402
+
};
403
+
#endif /* XDG_WM_BASE_ERROR_ENUM */
404
+
405
+
/**
406
+
* @ingroup iface_xdg_wm_base
407
+
* @struct xdg_wm_base_listener
408
+
*/
409
+
struct xdg_wm_base_listener {
410
+
/**
411
+
* check if the client is alive
412
+
*
413
+
* The ping event asks the client if it's still alive. Pass the
414
+
* serial specified in the event back to the compositor by sending
415
+
* a "pong" request back with the specified serial. See
416
+
* xdg_wm_base.pong.
417
+
*
418
+
* Compositors can use this to determine if the client is still
419
+
* alive. It's unspecified what will happen if the client doesn't
420
+
* respond to the ping request, or in what timeframe. Clients
421
+
* should try to respond in a reasonable amount of time. The
422
+
* “unresponsive” error is provided for compositors that wish
423
+
* to disconnect unresponsive clients.
424
+
*
425
+
* A compositor is free to ping in any way it wants, but a client
426
+
* must always respond to any xdg_wm_base object it created.
427
+
* @param serial pass this to the pong request
428
+
*/
429
+
void (*ping)(void *data,
430
+
struct xdg_wm_base *xdg_wm_base,
431
+
uint32_t serial);
432
+
};
433
+
434
+
/**
435
+
* @ingroup iface_xdg_wm_base
436
+
*/
437
+
static inline int
438
+
xdg_wm_base_add_listener(struct xdg_wm_base *xdg_wm_base,
439
+
const struct xdg_wm_base_listener *listener, void *data)
440
+
{
441
+
return wl_proxy_add_listener((struct wl_proxy *) xdg_wm_base,
442
+
(void (**)(void)) listener, data);
443
+
}
444
+
445
+
#define XDG_WM_BASE_DESTROY 0
446
+
#define XDG_WM_BASE_CREATE_POSITIONER 1
447
+
#define XDG_WM_BASE_GET_XDG_SURFACE 2
448
+
#define XDG_WM_BASE_PONG 3
449
+
450
+
/**
451
+
* @ingroup iface_xdg_wm_base
452
+
*/
453
+
#define XDG_WM_BASE_PING_SINCE_VERSION 1
454
+
455
+
/**
456
+
* @ingroup iface_xdg_wm_base
457
+
*/
458
+
#define XDG_WM_BASE_DESTROY_SINCE_VERSION 1
459
+
/**
460
+
* @ingroup iface_xdg_wm_base
461
+
*/
462
+
#define XDG_WM_BASE_CREATE_POSITIONER_SINCE_VERSION 1
463
+
/**
464
+
* @ingroup iface_xdg_wm_base
465
+
*/
466
+
#define XDG_WM_BASE_GET_XDG_SURFACE_SINCE_VERSION 1
467
+
/**
468
+
* @ingroup iface_xdg_wm_base
469
+
*/
470
+
#define XDG_WM_BASE_PONG_SINCE_VERSION 1
471
+
472
+
/** @ingroup iface_xdg_wm_base */
473
+
static inline void
474
+
xdg_wm_base_set_user_data(struct xdg_wm_base *xdg_wm_base, void *user_data)
475
+
{
476
+
wl_proxy_set_user_data((struct wl_proxy *) xdg_wm_base, user_data);
477
+
}
478
+
479
+
/** @ingroup iface_xdg_wm_base */
480
+
static inline void *
481
+
xdg_wm_base_get_user_data(struct xdg_wm_base *xdg_wm_base)
482
+
{
483
+
return wl_proxy_get_user_data((struct wl_proxy *) xdg_wm_base);
484
+
}
485
+
486
+
static inline uint32_t
487
+
xdg_wm_base_get_version(struct xdg_wm_base *xdg_wm_base)
488
+
{
489
+
return wl_proxy_get_version((struct wl_proxy *) xdg_wm_base);
490
+
}
491
+
492
+
/**
493
+
* @ingroup iface_xdg_wm_base
494
+
*
495
+
* Destroy this xdg_wm_base object.
496
+
*
497
+
* Destroying a bound xdg_wm_base object while there are surfaces
498
+
* still alive created by this xdg_wm_base object instance is illegal
499
+
* and will result in a defunct_surfaces error.
500
+
*/
501
+
static inline void
502
+
xdg_wm_base_destroy(struct xdg_wm_base *xdg_wm_base)
503
+
{
504
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_wm_base,
505
+
XDG_WM_BASE_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_wm_base), WL_MARSHAL_FLAG_DESTROY);
506
+
}
507
+
508
+
/**
509
+
* @ingroup iface_xdg_wm_base
510
+
*
511
+
* Create a positioner object. A positioner object is used to position
512
+
* surfaces relative to some parent surface. See the interface description
513
+
* and xdg_surface.get_popup for details.
514
+
*/
515
+
static inline struct xdg_positioner *
516
+
xdg_wm_base_create_positioner(struct xdg_wm_base *xdg_wm_base)
517
+
{
518
+
struct wl_proxy *id;
519
+
520
+
id = wl_proxy_marshal_flags((struct wl_proxy *) xdg_wm_base,
521
+
XDG_WM_BASE_CREATE_POSITIONER, &xdg_positioner_interface, wl_proxy_get_version((struct wl_proxy *) xdg_wm_base), 0, NULL);
522
+
523
+
return (struct xdg_positioner *) id;
524
+
}
525
+
526
+
/**
527
+
* @ingroup iface_xdg_wm_base
528
+
*
529
+
* This creates an xdg_surface for the given surface. While xdg_surface
530
+
* itself is not a role, the corresponding surface may only be assigned
531
+
* a role extending xdg_surface, such as xdg_toplevel or xdg_popup. It is
532
+
* illegal to create an xdg_surface for a wl_surface which already has an
533
+
* assigned role and this will result in a role error.
534
+
*
535
+
* This creates an xdg_surface for the given surface. An xdg_surface is
536
+
* used as basis to define a role to a given surface, such as xdg_toplevel
537
+
* or xdg_popup. It also manages functionality shared between xdg_surface
538
+
* based surface roles.
539
+
*
540
+
* See the documentation of xdg_surface for more details about what an
541
+
* xdg_surface is and how it is used.
542
+
*/
543
+
static inline struct xdg_surface *
544
+
xdg_wm_base_get_xdg_surface(struct xdg_wm_base *xdg_wm_base, struct wl_surface *surface)
545
+
{
546
+
struct wl_proxy *id;
547
+
548
+
id = wl_proxy_marshal_flags((struct wl_proxy *) xdg_wm_base,
549
+
XDG_WM_BASE_GET_XDG_SURFACE, &xdg_surface_interface, wl_proxy_get_version((struct wl_proxy *) xdg_wm_base), 0, NULL, surface);
550
+
551
+
return (struct xdg_surface *) id;
552
+
}
553
+
554
+
/**
555
+
* @ingroup iface_xdg_wm_base
556
+
*
557
+
* A client must respond to a ping event with a pong request or
558
+
* the client may be deemed unresponsive. See xdg_wm_base.ping
559
+
* and xdg_wm_base.error.unresponsive.
560
+
*/
561
+
static inline void
562
+
xdg_wm_base_pong(struct xdg_wm_base *xdg_wm_base, uint32_t serial)
563
+
{
564
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_wm_base,
565
+
XDG_WM_BASE_PONG, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_wm_base), 0, serial);
566
+
}
567
+
568
+
#ifndef XDG_POSITIONER_ERROR_ENUM
569
+
#define XDG_POSITIONER_ERROR_ENUM
570
+
enum xdg_positioner_error {
571
+
/**
572
+
* invalid input provided
573
+
*/
574
+
XDG_POSITIONER_ERROR_INVALID_INPUT = 0,
575
+
};
576
+
#endif /* XDG_POSITIONER_ERROR_ENUM */
577
+
578
+
#ifndef XDG_POSITIONER_ANCHOR_ENUM
579
+
#define XDG_POSITIONER_ANCHOR_ENUM
580
+
enum xdg_positioner_anchor {
581
+
XDG_POSITIONER_ANCHOR_NONE = 0,
582
+
XDG_POSITIONER_ANCHOR_TOP = 1,
583
+
XDG_POSITIONER_ANCHOR_BOTTOM = 2,
584
+
XDG_POSITIONER_ANCHOR_LEFT = 3,
585
+
XDG_POSITIONER_ANCHOR_RIGHT = 4,
586
+
XDG_POSITIONER_ANCHOR_TOP_LEFT = 5,
587
+
XDG_POSITIONER_ANCHOR_BOTTOM_LEFT = 6,
588
+
XDG_POSITIONER_ANCHOR_TOP_RIGHT = 7,
589
+
XDG_POSITIONER_ANCHOR_BOTTOM_RIGHT = 8,
590
+
};
591
+
#endif /* XDG_POSITIONER_ANCHOR_ENUM */
592
+
593
+
#ifndef XDG_POSITIONER_GRAVITY_ENUM
594
+
#define XDG_POSITIONER_GRAVITY_ENUM
595
+
enum xdg_positioner_gravity {
596
+
XDG_POSITIONER_GRAVITY_NONE = 0,
597
+
XDG_POSITIONER_GRAVITY_TOP = 1,
598
+
XDG_POSITIONER_GRAVITY_BOTTOM = 2,
599
+
XDG_POSITIONER_GRAVITY_LEFT = 3,
600
+
XDG_POSITIONER_GRAVITY_RIGHT = 4,
601
+
XDG_POSITIONER_GRAVITY_TOP_LEFT = 5,
602
+
XDG_POSITIONER_GRAVITY_BOTTOM_LEFT = 6,
603
+
XDG_POSITIONER_GRAVITY_TOP_RIGHT = 7,
604
+
XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT = 8,
605
+
};
606
+
#endif /* XDG_POSITIONER_GRAVITY_ENUM */
607
+
608
+
#ifndef XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_ENUM
609
+
#define XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_ENUM
610
+
/**
611
+
* @ingroup iface_xdg_positioner
612
+
* constraint adjustments
613
+
*
614
+
* The constraint adjustment value define ways the compositor will adjust
615
+
* the position of the surface, if the unadjusted position would result
616
+
* in the surface being partly constrained.
617
+
*
618
+
* Whether a surface is considered 'constrained' is left to the compositor
619
+
* to determine. For example, the surface may be partly outside the
620
+
* compositor's defined 'work area', thus necessitating the child surface's
621
+
* position be adjusted until it is entirely inside the work area.
622
+
*
623
+
* The adjustments can be combined, according to a defined precedence: 1)
624
+
* Flip, 2) Slide, 3) Resize.
625
+
*/
626
+
enum xdg_positioner_constraint_adjustment {
627
+
/**
628
+
* don't move the child surface when constrained
629
+
*
630
+
* Don't alter the surface position even if it is constrained on
631
+
* some axis, for example partially outside the edge of an output.
632
+
*/
633
+
XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_NONE = 0,
634
+
/**
635
+
* move along the x axis until unconstrained
636
+
*
637
+
* Slide the surface along the x axis until it is no longer
638
+
* constrained.
639
+
*
640
+
* First try to slide towards the direction of the gravity on the x
641
+
* axis until either the edge in the opposite direction of the
642
+
* gravity is unconstrained or the edge in the direction of the
643
+
* gravity is constrained.
644
+
*
645
+
* Then try to slide towards the opposite direction of the gravity
646
+
* on the x axis until either the edge in the direction of the
647
+
* gravity is unconstrained or the edge in the opposite direction
648
+
* of the gravity is constrained.
649
+
*/
650
+
XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X = 1,
651
+
/**
652
+
* move along the y axis until unconstrained
653
+
*
654
+
* Slide the surface along the y axis until it is no longer
655
+
* constrained.
656
+
*
657
+
* First try to slide towards the direction of the gravity on the y
658
+
* axis until either the edge in the opposite direction of the
659
+
* gravity is unconstrained or the edge in the direction of the
660
+
* gravity is constrained.
661
+
*
662
+
* Then try to slide towards the opposite direction of the gravity
663
+
* on the y axis until either the edge in the direction of the
664
+
* gravity is unconstrained or the edge in the opposite direction
665
+
* of the gravity is constrained.
666
+
*/
667
+
XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y = 2,
668
+
/**
669
+
* invert the anchor and gravity on the x axis
670
+
*
671
+
* Invert the anchor and gravity on the x axis if the surface is
672
+
* constrained on the x axis. For example, if the left edge of the
673
+
* surface is constrained, the gravity is 'left' and the anchor is
674
+
* 'left', change the gravity to 'right' and the anchor to 'right'.
675
+
*
676
+
* If the adjusted position also ends up being constrained, the
677
+
* resulting position of the flip_x adjustment will be the one
678
+
* before the adjustment.
679
+
*/
680
+
XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_X = 4,
681
+
/**
682
+
* invert the anchor and gravity on the y axis
683
+
*
684
+
* Invert the anchor and gravity on the y axis if the surface is
685
+
* constrained on the y axis. For example, if the bottom edge of
686
+
* the surface is constrained, the gravity is 'bottom' and the
687
+
* anchor is 'bottom', change the gravity to 'top' and the anchor
688
+
* to 'top'.
689
+
*
690
+
* The adjusted position is calculated given the original anchor
691
+
* rectangle and offset, but with the new flipped anchor and
692
+
* gravity values.
693
+
*
694
+
* If the adjusted position also ends up being constrained, the
695
+
* resulting position of the flip_y adjustment will be the one
696
+
* before the adjustment.
697
+
*/
698
+
XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y = 8,
699
+
/**
700
+
* horizontally resize the surface
701
+
*
702
+
* Resize the surface horizontally so that it is completely
703
+
* unconstrained.
704
+
*/
705
+
XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_X = 16,
706
+
/**
707
+
* vertically resize the surface
708
+
*
709
+
* Resize the surface vertically so that it is completely
710
+
* unconstrained.
711
+
*/
712
+
XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_Y = 32,
713
+
};
714
+
#endif /* XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_ENUM */
715
+
716
+
#define XDG_POSITIONER_DESTROY 0
717
+
#define XDG_POSITIONER_SET_SIZE 1
718
+
#define XDG_POSITIONER_SET_ANCHOR_RECT 2
719
+
#define XDG_POSITIONER_SET_ANCHOR 3
720
+
#define XDG_POSITIONER_SET_GRAVITY 4
721
+
#define XDG_POSITIONER_SET_CONSTRAINT_ADJUSTMENT 5
722
+
#define XDG_POSITIONER_SET_OFFSET 6
723
+
#define XDG_POSITIONER_SET_REACTIVE 7
724
+
#define XDG_POSITIONER_SET_PARENT_SIZE 8
725
+
#define XDG_POSITIONER_SET_PARENT_CONFIGURE 9
726
+
727
+
728
+
/**
729
+
* @ingroup iface_xdg_positioner
730
+
*/
731
+
#define XDG_POSITIONER_DESTROY_SINCE_VERSION 1
732
+
/**
733
+
* @ingroup iface_xdg_positioner
734
+
*/
735
+
#define XDG_POSITIONER_SET_SIZE_SINCE_VERSION 1
736
+
/**
737
+
* @ingroup iface_xdg_positioner
738
+
*/
739
+
#define XDG_POSITIONER_SET_ANCHOR_RECT_SINCE_VERSION 1
740
+
/**
741
+
* @ingroup iface_xdg_positioner
742
+
*/
743
+
#define XDG_POSITIONER_SET_ANCHOR_SINCE_VERSION 1
744
+
/**
745
+
* @ingroup iface_xdg_positioner
746
+
*/
747
+
#define XDG_POSITIONER_SET_GRAVITY_SINCE_VERSION 1
748
+
/**
749
+
* @ingroup iface_xdg_positioner
750
+
*/
751
+
#define XDG_POSITIONER_SET_CONSTRAINT_ADJUSTMENT_SINCE_VERSION 1
752
+
/**
753
+
* @ingroup iface_xdg_positioner
754
+
*/
755
+
#define XDG_POSITIONER_SET_OFFSET_SINCE_VERSION 1
756
+
/**
757
+
* @ingroup iface_xdg_positioner
758
+
*/
759
+
#define XDG_POSITIONER_SET_REACTIVE_SINCE_VERSION 3
760
+
/**
761
+
* @ingroup iface_xdg_positioner
762
+
*/
763
+
#define XDG_POSITIONER_SET_PARENT_SIZE_SINCE_VERSION 3
764
+
/**
765
+
* @ingroup iface_xdg_positioner
766
+
*/
767
+
#define XDG_POSITIONER_SET_PARENT_CONFIGURE_SINCE_VERSION 3
768
+
769
+
/** @ingroup iface_xdg_positioner */
770
+
static inline void
771
+
xdg_positioner_set_user_data(struct xdg_positioner *xdg_positioner, void *user_data)
772
+
{
773
+
wl_proxy_set_user_data((struct wl_proxy *) xdg_positioner, user_data);
774
+
}
775
+
776
+
/** @ingroup iface_xdg_positioner */
777
+
static inline void *
778
+
xdg_positioner_get_user_data(struct xdg_positioner *xdg_positioner)
779
+
{
780
+
return wl_proxy_get_user_data((struct wl_proxy *) xdg_positioner);
781
+
}
782
+
783
+
static inline uint32_t
784
+
xdg_positioner_get_version(struct xdg_positioner *xdg_positioner)
785
+
{
786
+
return wl_proxy_get_version((struct wl_proxy *) xdg_positioner);
787
+
}
788
+
789
+
/**
790
+
* @ingroup iface_xdg_positioner
791
+
*
792
+
* Notify the compositor that the xdg_positioner will no longer be used.
793
+
*/
794
+
static inline void
795
+
xdg_positioner_destroy(struct xdg_positioner *xdg_positioner)
796
+
{
797
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner,
798
+
XDG_POSITIONER_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), WL_MARSHAL_FLAG_DESTROY);
799
+
}
800
+
801
+
/**
802
+
* @ingroup iface_xdg_positioner
803
+
*
804
+
* Set the size of the surface that is to be positioned with the positioner
805
+
* object. The size is in surface-local coordinates and corresponds to the
806
+
* window geometry. See xdg_surface.set_window_geometry.
807
+
*
808
+
* If a zero or negative size is set the invalid_input error is raised.
809
+
*/
810
+
static inline void
811
+
xdg_positioner_set_size(struct xdg_positioner *xdg_positioner, int32_t width, int32_t height)
812
+
{
813
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner,
814
+
XDG_POSITIONER_SET_SIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, width, height);
815
+
}
816
+
817
+
/**
818
+
* @ingroup iface_xdg_positioner
819
+
*
820
+
* Specify the anchor rectangle within the parent surface that the child
821
+
* surface will be placed relative to. The rectangle is relative to the
822
+
* window geometry as defined by xdg_surface.set_window_geometry of the
823
+
* parent surface.
824
+
*
825
+
* When the xdg_positioner object is used to position a child surface, the
826
+
* anchor rectangle may not extend outside the window geometry of the
827
+
* positioned child's parent surface.
828
+
*
829
+
* If a negative size is set the invalid_input error is raised.
830
+
*/
831
+
static inline void
832
+
xdg_positioner_set_anchor_rect(struct xdg_positioner *xdg_positioner, int32_t x, int32_t y, int32_t width, int32_t height)
833
+
{
834
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner,
835
+
XDG_POSITIONER_SET_ANCHOR_RECT, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, x, y, width, height);
836
+
}
837
+
838
+
/**
839
+
* @ingroup iface_xdg_positioner
840
+
*
841
+
* Defines the anchor point for the anchor rectangle. The specified anchor
842
+
* is used derive an anchor point that the child surface will be
843
+
* positioned relative to. If a corner anchor is set (e.g. 'top_left' or
844
+
* 'bottom_right'), the anchor point will be at the specified corner;
845
+
* otherwise, the derived anchor point will be centered on the specified
846
+
* edge, or in the center of the anchor rectangle if no edge is specified.
847
+
*/
848
+
static inline void
849
+
xdg_positioner_set_anchor(struct xdg_positioner *xdg_positioner, uint32_t anchor)
850
+
{
851
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner,
852
+
XDG_POSITIONER_SET_ANCHOR, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, anchor);
853
+
}
854
+
855
+
/**
856
+
* @ingroup iface_xdg_positioner
857
+
*
858
+
* Defines in what direction a surface should be positioned, relative to
859
+
* the anchor point of the parent surface. If a corner gravity is
860
+
* specified (e.g. 'bottom_right' or 'top_left'), then the child surface
861
+
* will be placed towards the specified gravity; otherwise, the child
862
+
* surface will be centered over the anchor point on any axis that had no
863
+
* gravity specified. If the gravity is not in the ‘gravity’ enum, an
864
+
* invalid_input error is raised.
865
+
*/
866
+
static inline void
867
+
xdg_positioner_set_gravity(struct xdg_positioner *xdg_positioner, uint32_t gravity)
868
+
{
869
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner,
870
+
XDG_POSITIONER_SET_GRAVITY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, gravity);
871
+
}
872
+
873
+
/**
874
+
* @ingroup iface_xdg_positioner
875
+
*
876
+
* Specify how the window should be positioned if the originally intended
877
+
* position caused the surface to be constrained, meaning at least
878
+
* partially outside positioning boundaries set by the compositor. The
879
+
* adjustment is set by constructing a bitmask describing the adjustment to
880
+
* be made when the surface is constrained on that axis.
881
+
*
882
+
* If no bit for one axis is set, the compositor will assume that the child
883
+
* surface should not change its position on that axis when constrained.
884
+
*
885
+
* If more than one bit for one axis is set, the order of how adjustments
886
+
* are applied is specified in the corresponding adjustment descriptions.
887
+
*
888
+
* The default adjustment is none.
889
+
*/
890
+
static inline void
891
+
xdg_positioner_set_constraint_adjustment(struct xdg_positioner *xdg_positioner, uint32_t constraint_adjustment)
892
+
{
893
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner,
894
+
XDG_POSITIONER_SET_CONSTRAINT_ADJUSTMENT, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, constraint_adjustment);
895
+
}
896
+
897
+
/**
898
+
* @ingroup iface_xdg_positioner
899
+
*
900
+
* Specify the surface position offset relative to the position of the
901
+
* anchor on the anchor rectangle and the anchor on the surface. For
902
+
* example if the anchor of the anchor rectangle is at (x, y), the surface
903
+
* has the gravity bottom|right, and the offset is (ox, oy), the calculated
904
+
* surface position will be (x + ox, y + oy). The offset position of the
905
+
* surface is the one used for constraint testing. See
906
+
* set_constraint_adjustment.
907
+
*
908
+
* An example use case is placing a popup menu on top of a user interface
909
+
* element, while aligning the user interface element of the parent surface
910
+
* with some user interface element placed somewhere in the popup surface.
911
+
*/
912
+
static inline void
913
+
xdg_positioner_set_offset(struct xdg_positioner *xdg_positioner, int32_t x, int32_t y)
914
+
{
915
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner,
916
+
XDG_POSITIONER_SET_OFFSET, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, x, y);
917
+
}
918
+
919
+
/**
920
+
* @ingroup iface_xdg_positioner
921
+
*
922
+
* When set reactive, the surface is reconstrained if the conditions used
923
+
* for constraining changed, e.g. the parent window moved.
924
+
*
925
+
* If the conditions changed and the popup was reconstrained, an
926
+
* xdg_popup.configure event is sent with updated geometry, followed by an
927
+
* xdg_surface.configure event.
928
+
*/
929
+
static inline void
930
+
xdg_positioner_set_reactive(struct xdg_positioner *xdg_positioner)
931
+
{
932
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner,
933
+
XDG_POSITIONER_SET_REACTIVE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0);
934
+
}
935
+
936
+
/**
937
+
* @ingroup iface_xdg_positioner
938
+
*
939
+
* Set the parent window geometry the compositor should use when
940
+
* positioning the popup. The compositor may use this information to
941
+
* determine the future state the popup should be constrained using. If
942
+
* this doesn't match the dimension of the parent the popup is eventually
943
+
* positioned against, the behavior is undefined.
944
+
*
945
+
* The arguments are given in the surface-local coordinate space.
946
+
*/
947
+
static inline void
948
+
xdg_positioner_set_parent_size(struct xdg_positioner *xdg_positioner, int32_t parent_width, int32_t parent_height)
949
+
{
950
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner,
951
+
XDG_POSITIONER_SET_PARENT_SIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, parent_width, parent_height);
952
+
}
953
+
954
+
/**
955
+
* @ingroup iface_xdg_positioner
956
+
*
957
+
* Set the serial of an xdg_surface.configure event this positioner will be
958
+
* used in response to. The compositor may use this information together
959
+
* with set_parent_size to determine what future state the popup should be
960
+
* constrained using.
961
+
*/
962
+
static inline void
963
+
xdg_positioner_set_parent_configure(struct xdg_positioner *xdg_positioner, uint32_t serial)
964
+
{
965
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_positioner,
966
+
XDG_POSITIONER_SET_PARENT_CONFIGURE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_positioner), 0, serial);
967
+
}
968
+
969
+
#ifndef XDG_SURFACE_ERROR_ENUM
970
+
#define XDG_SURFACE_ERROR_ENUM
971
+
enum xdg_surface_error {
972
+
/**
973
+
* Surface was not fully constructed
974
+
*/
975
+
XDG_SURFACE_ERROR_NOT_CONSTRUCTED = 1,
976
+
/**
977
+
* Surface was already constructed
978
+
*/
979
+
XDG_SURFACE_ERROR_ALREADY_CONSTRUCTED = 2,
980
+
/**
981
+
* Attaching a buffer to an unconfigured surface
982
+
*/
983
+
XDG_SURFACE_ERROR_UNCONFIGURED_BUFFER = 3,
984
+
/**
985
+
* Invalid serial number when acking a configure event
986
+
*/
987
+
XDG_SURFACE_ERROR_INVALID_SERIAL = 4,
988
+
/**
989
+
* Width or height was zero or negative
990
+
*/
991
+
XDG_SURFACE_ERROR_INVALID_SIZE = 5,
992
+
/**
993
+
* Surface was destroyed before its role object
994
+
*/
995
+
XDG_SURFACE_ERROR_DEFUNCT_ROLE_OBJECT = 6,
996
+
};
997
+
#endif /* XDG_SURFACE_ERROR_ENUM */
998
+
999
+
/**
1000
+
* @ingroup iface_xdg_surface
1001
+
* @struct xdg_surface_listener
1002
+
*/
1003
+
struct xdg_surface_listener {
1004
+
/**
1005
+
* suggest a surface change
1006
+
*
1007
+
* The configure event marks the end of a configure sequence. A
1008
+
* configure sequence is a set of one or more events configuring
1009
+
* the state of the xdg_surface, including the final
1010
+
* xdg_surface.configure event.
1011
+
*
1012
+
* Where applicable, xdg_surface surface roles will during a
1013
+
* configure sequence extend this event as a latched state sent as
1014
+
* events before the xdg_surface.configure event. Such events
1015
+
* should be considered to make up a set of atomically applied
1016
+
* configuration states, where the xdg_surface.configure commits
1017
+
* the accumulated state.
1018
+
*
1019
+
* Clients should arrange their surface for the new states, and
1020
+
* then send an ack_configure request with the serial sent in this
1021
+
* configure event at some point before committing the new surface.
1022
+
*
1023
+
* If the client receives multiple configure events before it can
1024
+
* respond to one, it is free to discard all but the last event it
1025
+
* received.
1026
+
* @param serial serial of the configure event
1027
+
*/
1028
+
void (*configure)(void *data,
1029
+
struct xdg_surface *xdg_surface,
1030
+
uint32_t serial);
1031
+
};
1032
+
1033
+
/**
1034
+
* @ingroup iface_xdg_surface
1035
+
*/
1036
+
static inline int
1037
+
xdg_surface_add_listener(struct xdg_surface *xdg_surface,
1038
+
const struct xdg_surface_listener *listener, void *data)
1039
+
{
1040
+
return wl_proxy_add_listener((struct wl_proxy *) xdg_surface,
1041
+
(void (**)(void)) listener, data);
1042
+
}
1043
+
1044
+
#define XDG_SURFACE_DESTROY 0
1045
+
#define XDG_SURFACE_GET_TOPLEVEL 1
1046
+
#define XDG_SURFACE_GET_POPUP 2
1047
+
#define XDG_SURFACE_SET_WINDOW_GEOMETRY 3
1048
+
#define XDG_SURFACE_ACK_CONFIGURE 4
1049
+
1050
+
/**
1051
+
* @ingroup iface_xdg_surface
1052
+
*/
1053
+
#define XDG_SURFACE_CONFIGURE_SINCE_VERSION 1
1054
+
1055
+
/**
1056
+
* @ingroup iface_xdg_surface
1057
+
*/
1058
+
#define XDG_SURFACE_DESTROY_SINCE_VERSION 1
1059
+
/**
1060
+
* @ingroup iface_xdg_surface
1061
+
*/
1062
+
#define XDG_SURFACE_GET_TOPLEVEL_SINCE_VERSION 1
1063
+
/**
1064
+
* @ingroup iface_xdg_surface
1065
+
*/
1066
+
#define XDG_SURFACE_GET_POPUP_SINCE_VERSION 1
1067
+
/**
1068
+
* @ingroup iface_xdg_surface
1069
+
*/
1070
+
#define XDG_SURFACE_SET_WINDOW_GEOMETRY_SINCE_VERSION 1
1071
+
/**
1072
+
* @ingroup iface_xdg_surface
1073
+
*/
1074
+
#define XDG_SURFACE_ACK_CONFIGURE_SINCE_VERSION 1
1075
+
1076
+
/** @ingroup iface_xdg_surface */
1077
+
static inline void
1078
+
xdg_surface_set_user_data(struct xdg_surface *xdg_surface, void *user_data)
1079
+
{
1080
+
wl_proxy_set_user_data((struct wl_proxy *) xdg_surface, user_data);
1081
+
}
1082
+
1083
+
/** @ingroup iface_xdg_surface */
1084
+
static inline void *
1085
+
xdg_surface_get_user_data(struct xdg_surface *xdg_surface)
1086
+
{
1087
+
return wl_proxy_get_user_data((struct wl_proxy *) xdg_surface);
1088
+
}
1089
+
1090
+
static inline uint32_t
1091
+
xdg_surface_get_version(struct xdg_surface *xdg_surface)
1092
+
{
1093
+
return wl_proxy_get_version((struct wl_proxy *) xdg_surface);
1094
+
}
1095
+
1096
+
/**
1097
+
* @ingroup iface_xdg_surface
1098
+
*
1099
+
* Destroy the xdg_surface object. An xdg_surface must only be destroyed
1100
+
* after its role object has been destroyed, otherwise
1101
+
* a defunct_role_object error is raised.
1102
+
*/
1103
+
static inline void
1104
+
xdg_surface_destroy(struct xdg_surface *xdg_surface)
1105
+
{
1106
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface,
1107
+
XDG_SURFACE_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_surface), WL_MARSHAL_FLAG_DESTROY);
1108
+
}
1109
+
1110
+
/**
1111
+
* @ingroup iface_xdg_surface
1112
+
*
1113
+
* This creates an xdg_toplevel object for the given xdg_surface and gives
1114
+
* the associated wl_surface the xdg_toplevel role.
1115
+
*
1116
+
* See the documentation of xdg_toplevel for more details about what an
1117
+
* xdg_toplevel is and how it is used.
1118
+
*/
1119
+
static inline struct xdg_toplevel *
1120
+
xdg_surface_get_toplevel(struct xdg_surface *xdg_surface)
1121
+
{
1122
+
struct wl_proxy *id;
1123
+
1124
+
id = wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface,
1125
+
XDG_SURFACE_GET_TOPLEVEL, &xdg_toplevel_interface, wl_proxy_get_version((struct wl_proxy *) xdg_surface), 0, NULL);
1126
+
1127
+
return (struct xdg_toplevel *) id;
1128
+
}
1129
+
1130
+
/**
1131
+
* @ingroup iface_xdg_surface
1132
+
*
1133
+
* This creates an xdg_popup object for the given xdg_surface and gives
1134
+
* the associated wl_surface the xdg_popup role.
1135
+
*
1136
+
* If null is passed as a parent, a parent surface must be specified using
1137
+
* some other protocol, before committing the initial state.
1138
+
*
1139
+
* See the documentation of xdg_popup for more details about what an
1140
+
* xdg_popup is and how it is used.
1141
+
*/
1142
+
static inline struct xdg_popup *
1143
+
xdg_surface_get_popup(struct xdg_surface *xdg_surface, struct xdg_surface *parent, struct xdg_positioner *positioner)
1144
+
{
1145
+
struct wl_proxy *id;
1146
+
1147
+
id = wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface,
1148
+
XDG_SURFACE_GET_POPUP, &xdg_popup_interface, wl_proxy_get_version((struct wl_proxy *) xdg_surface), 0, NULL, parent, positioner);
1149
+
1150
+
return (struct xdg_popup *) id;
1151
+
}
1152
+
1153
+
/**
1154
+
* @ingroup iface_xdg_surface
1155
+
*
1156
+
* The window geometry of a surface is its "visible bounds" from the
1157
+
* user's perspective. Client-side decorations often have invisible
1158
+
* portions like drop-shadows which should be ignored for the
1159
+
* purposes of aligning, placing and constraining windows. Note that
1160
+
* in some situations, compositors may clip rendering to the window
1161
+
* geometry, so the client should avoid putting functional elements
1162
+
* outside of it.
1163
+
*
1164
+
* The window geometry is double-buffered state, see wl_surface.commit.
1165
+
*
1166
+
* When maintaining a position, the compositor should treat the (x, y)
1167
+
* coordinate of the window geometry as the top left corner of the window.
1168
+
* A client changing the (x, y) window geometry coordinate should in
1169
+
* general not alter the position of the window.
1170
+
*
1171
+
* Once the window geometry of the surface is set, it is not possible to
1172
+
* unset it, and it will remain the same until set_window_geometry is
1173
+
* called again, even if a new subsurface or buffer is attached.
1174
+
*
1175
+
* If never set, the value is the full bounds of the surface,
1176
+
* including any subsurfaces. This updates dynamically on every
1177
+
* commit. This unset is meant for extremely simple clients.
1178
+
*
1179
+
* The arguments are given in the surface-local coordinate space of
1180
+
* the wl_surface associated with this xdg_surface, and may extend outside
1181
+
* of the wl_surface itself to mark parts of the subsurface tree as part of
1182
+
* the window geometry.
1183
+
*
1184
+
* When applied, the effective window geometry will be the set window
1185
+
* geometry clamped to the bounding rectangle of the combined
1186
+
* geometry of the surface of the xdg_surface and the associated
1187
+
* subsurfaces.
1188
+
*
1189
+
* The effective geometry will not be recalculated unless a new call to
1190
+
* set_window_geometry is done and the new pending surface state is
1191
+
* subsequently applied.
1192
+
*
1193
+
* The width and height of the effective window geometry must be
1194
+
* greater than zero. Setting an invalid size will raise an
1195
+
* invalid_size error.
1196
+
*/
1197
+
static inline void
1198
+
xdg_surface_set_window_geometry(struct xdg_surface *xdg_surface, int32_t x, int32_t y, int32_t width, int32_t height)
1199
+
{
1200
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface,
1201
+
XDG_SURFACE_SET_WINDOW_GEOMETRY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_surface), 0, x, y, width, height);
1202
+
}
1203
+
1204
+
/**
1205
+
* @ingroup iface_xdg_surface
1206
+
*
1207
+
* When a configure event is received, if a client commits the
1208
+
* surface in response to the configure event, then the client
1209
+
* must make an ack_configure request sometime before the commit
1210
+
* request, passing along the serial of the configure event.
1211
+
*
1212
+
* For instance, for toplevel surfaces the compositor might use this
1213
+
* information to move a surface to the top left only when the client has
1214
+
* drawn itself for the maximized or fullscreen state.
1215
+
*
1216
+
* If the client receives multiple configure events before it
1217
+
* can respond to one, it only has to ack the last configure event.
1218
+
* Acking a configure event that was never sent raises an invalid_serial
1219
+
* error.
1220
+
*
1221
+
* A client is not required to commit immediately after sending
1222
+
* an ack_configure request - it may even ack_configure several times
1223
+
* before its next surface commit.
1224
+
*
1225
+
* A client may send multiple ack_configure requests before committing, but
1226
+
* only the last request sent before a commit indicates which configure
1227
+
* event the client really is responding to.
1228
+
*
1229
+
* Sending an ack_configure request consumes the serial number sent with
1230
+
* the request, as well as serial numbers sent by all configure events
1231
+
* sent on this xdg_surface prior to the configure event referenced by
1232
+
* the committed serial.
1233
+
*
1234
+
* It is an error to issue multiple ack_configure requests referencing a
1235
+
* serial from the same configure event, or to issue an ack_configure
1236
+
* request referencing a serial from a configure event issued before the
1237
+
* event identified by the last ack_configure request for the same
1238
+
* xdg_surface. Doing so will raise an invalid_serial error.
1239
+
*/
1240
+
static inline void
1241
+
xdg_surface_ack_configure(struct xdg_surface *xdg_surface, uint32_t serial)
1242
+
{
1243
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_surface,
1244
+
XDG_SURFACE_ACK_CONFIGURE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_surface), 0, serial);
1245
+
}
1246
+
1247
+
#ifndef XDG_TOPLEVEL_ERROR_ENUM
1248
+
#define XDG_TOPLEVEL_ERROR_ENUM
1249
+
enum xdg_toplevel_error {
1250
+
/**
1251
+
* provided value is not a valid variant of the resize_edge enum
1252
+
*/
1253
+
XDG_TOPLEVEL_ERROR_INVALID_RESIZE_EDGE = 0,
1254
+
/**
1255
+
* invalid parent toplevel
1256
+
*/
1257
+
XDG_TOPLEVEL_ERROR_INVALID_PARENT = 1,
1258
+
/**
1259
+
* client provided an invalid min or max size
1260
+
*/
1261
+
XDG_TOPLEVEL_ERROR_INVALID_SIZE = 2,
1262
+
};
1263
+
#endif /* XDG_TOPLEVEL_ERROR_ENUM */
1264
+
1265
+
#ifndef XDG_TOPLEVEL_RESIZE_EDGE_ENUM
1266
+
#define XDG_TOPLEVEL_RESIZE_EDGE_ENUM
1267
+
/**
1268
+
* @ingroup iface_xdg_toplevel
1269
+
* edge values for resizing
1270
+
*
1271
+
* These values are used to indicate which edge of a surface
1272
+
* is being dragged in a resize operation.
1273
+
*/
1274
+
enum xdg_toplevel_resize_edge {
1275
+
XDG_TOPLEVEL_RESIZE_EDGE_NONE = 0,
1276
+
XDG_TOPLEVEL_RESIZE_EDGE_TOP = 1,
1277
+
XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM = 2,
1278
+
XDG_TOPLEVEL_RESIZE_EDGE_LEFT = 4,
1279
+
XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT = 5,
1280
+
XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT = 6,
1281
+
XDG_TOPLEVEL_RESIZE_EDGE_RIGHT = 8,
1282
+
XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT = 9,
1283
+
XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT = 10,
1284
+
};
1285
+
#endif /* XDG_TOPLEVEL_RESIZE_EDGE_ENUM */
1286
+
1287
+
#ifndef XDG_TOPLEVEL_STATE_ENUM
1288
+
#define XDG_TOPLEVEL_STATE_ENUM
1289
+
/**
1290
+
* @ingroup iface_xdg_toplevel
1291
+
* types of state on the surface
1292
+
*
1293
+
* The different state values used on the surface. This is designed for
1294
+
* state values like maximized, fullscreen. It is paired with the
1295
+
* configure event to ensure that both the client and the compositor
1296
+
* setting the state can be synchronized.
1297
+
*
1298
+
* States set in this way are double-buffered, see wl_surface.commit.
1299
+
*/
1300
+
enum xdg_toplevel_state {
1301
+
/**
1302
+
* the surface is maximized
1303
+
* the surface is maximized
1304
+
*
1305
+
* The surface is maximized. The window geometry specified in the
1306
+
* configure event must be obeyed by the client, or the
1307
+
* xdg_wm_base.invalid_surface_state error is raised.
1308
+
*
1309
+
* The client should draw without shadow or other decoration
1310
+
* outside of the window geometry.
1311
+
*/
1312
+
XDG_TOPLEVEL_STATE_MAXIMIZED = 1,
1313
+
/**
1314
+
* the surface is fullscreen
1315
+
* the surface is fullscreen
1316
+
*
1317
+
* The surface is fullscreen. The window geometry specified in
1318
+
* the configure event is a maximum; the client cannot resize
1319
+
* beyond it. For a surface to cover the whole fullscreened area,
1320
+
* the geometry dimensions must be obeyed by the client. For more
1321
+
* details, see xdg_toplevel.set_fullscreen.
1322
+
*/
1323
+
XDG_TOPLEVEL_STATE_FULLSCREEN = 2,
1324
+
/**
1325
+
* the surface is being resized
1326
+
* the surface is being resized
1327
+
*
1328
+
* The surface is being resized. The window geometry specified in
1329
+
* the configure event is a maximum; the client cannot resize
1330
+
* beyond it. Clients that have aspect ratio or cell sizing
1331
+
* configuration can use a smaller size, however.
1332
+
*/
1333
+
XDG_TOPLEVEL_STATE_RESIZING = 3,
1334
+
/**
1335
+
* the surface is now activated
1336
+
* the surface is now activated
1337
+
*
1338
+
* Client window decorations should be painted as if the window
1339
+
* is active. Do not assume this means that the window actually has
1340
+
* keyboard or pointer focus.
1341
+
*/
1342
+
XDG_TOPLEVEL_STATE_ACTIVATED = 4,
1343
+
/**
1344
+
* the surface’s left edge is tiled
1345
+
*
1346
+
* The window is currently in a tiled layout and the left edge is
1347
+
* considered to be adjacent to another part of the tiling grid.
1348
+
*
1349
+
* The client should draw without shadow or other decoration
1350
+
* outside of the window geometry on the left edge.
1351
+
* @since 2
1352
+
*/
1353
+
XDG_TOPLEVEL_STATE_TILED_LEFT = 5,
1354
+
/**
1355
+
* the surface’s right edge is tiled
1356
+
*
1357
+
* The window is currently in a tiled layout and the right edge
1358
+
* is considered to be adjacent to another part of the tiling grid.
1359
+
*
1360
+
* The client should draw without shadow or other decoration
1361
+
* outside of the window geometry on the right edge.
1362
+
* @since 2
1363
+
*/
1364
+
XDG_TOPLEVEL_STATE_TILED_RIGHT = 6,
1365
+
/**
1366
+
* the surface’s top edge is tiled
1367
+
*
1368
+
* The window is currently in a tiled layout and the top edge is
1369
+
* considered to be adjacent to another part of the tiling grid.
1370
+
*
1371
+
* The client should draw without shadow or other decoration
1372
+
* outside of the window geometry on the top edge.
1373
+
* @since 2
1374
+
*/
1375
+
XDG_TOPLEVEL_STATE_TILED_TOP = 7,
1376
+
/**
1377
+
* the surface’s bottom edge is tiled
1378
+
*
1379
+
* The window is currently in a tiled layout and the bottom edge
1380
+
* is considered to be adjacent to another part of the tiling grid.
1381
+
*
1382
+
* The client should draw without shadow or other decoration
1383
+
* outside of the window geometry on the bottom edge.
1384
+
* @since 2
1385
+
*/
1386
+
XDG_TOPLEVEL_STATE_TILED_BOTTOM = 8,
1387
+
/**
1388
+
* surface repaint is suspended
1389
+
*
1390
+
* The surface is currently not ordinarily being repainted; for
1391
+
* example because its content is occluded by another window, or
1392
+
* its outputs are switched off due to screen locking.
1393
+
* @since 6
1394
+
*/
1395
+
XDG_TOPLEVEL_STATE_SUSPENDED = 9,
1396
+
/**
1397
+
* the surface’s left edge is constrained
1398
+
*
1399
+
* The left edge of the window is currently constrained, meaning
1400
+
* it shouldn't attempt to resize from that edge. It can for
1401
+
* example mean it's tiled next to a monitor edge on the
1402
+
* constrained side of the window.
1403
+
* @since 7
1404
+
*/
1405
+
XDG_TOPLEVEL_STATE_CONSTRAINED_LEFT = 10,
1406
+
/**
1407
+
* the surface’s right edge is constrained
1408
+
*
1409
+
* The right edge of the window is currently constrained, meaning
1410
+
* it shouldn't attempt to resize from that edge. It can for
1411
+
* example mean it's tiled next to a monitor edge on the
1412
+
* constrained side of the window.
1413
+
* @since 7
1414
+
*/
1415
+
XDG_TOPLEVEL_STATE_CONSTRAINED_RIGHT = 11,
1416
+
/**
1417
+
* the surface’s top edge is constrained
1418
+
*
1419
+
* The top edge of the window is currently constrained, meaning
1420
+
* it shouldn't attempt to resize from that edge. It can for
1421
+
* example mean it's tiled next to a monitor edge on the
1422
+
* constrained side of the window.
1423
+
* @since 7
1424
+
*/
1425
+
XDG_TOPLEVEL_STATE_CONSTRAINED_TOP = 12,
1426
+
/**
1427
+
* the surface’s bottom edge is constrained
1428
+
*
1429
+
* The bottom edge of the window is currently constrained,
1430
+
* meaning it shouldn't attempt to resize from that edge. It can
1431
+
* for example mean it's tiled next to a monitor edge on the
1432
+
* constrained side of the window.
1433
+
* @since 7
1434
+
*/
1435
+
XDG_TOPLEVEL_STATE_CONSTRAINED_BOTTOM = 13,
1436
+
};
1437
+
/**
1438
+
* @ingroup iface_xdg_toplevel
1439
+
*/
1440
+
#define XDG_TOPLEVEL_STATE_TILED_LEFT_SINCE_VERSION 2
1441
+
/**
1442
+
* @ingroup iface_xdg_toplevel
1443
+
*/
1444
+
#define XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION 2
1445
+
/**
1446
+
* @ingroup iface_xdg_toplevel
1447
+
*/
1448
+
#define XDG_TOPLEVEL_STATE_TILED_TOP_SINCE_VERSION 2
1449
+
/**
1450
+
* @ingroup iface_xdg_toplevel
1451
+
*/
1452
+
#define XDG_TOPLEVEL_STATE_TILED_BOTTOM_SINCE_VERSION 2
1453
+
/**
1454
+
* @ingroup iface_xdg_toplevel
1455
+
*/
1456
+
#define XDG_TOPLEVEL_STATE_SUSPENDED_SINCE_VERSION 6
1457
+
/**
1458
+
* @ingroup iface_xdg_toplevel
1459
+
*/
1460
+
#define XDG_TOPLEVEL_STATE_CONSTRAINED_LEFT_SINCE_VERSION 7
1461
+
/**
1462
+
* @ingroup iface_xdg_toplevel
1463
+
*/
1464
+
#define XDG_TOPLEVEL_STATE_CONSTRAINED_RIGHT_SINCE_VERSION 7
1465
+
/**
1466
+
* @ingroup iface_xdg_toplevel
1467
+
*/
1468
+
#define XDG_TOPLEVEL_STATE_CONSTRAINED_TOP_SINCE_VERSION 7
1469
+
/**
1470
+
* @ingroup iface_xdg_toplevel
1471
+
*/
1472
+
#define XDG_TOPLEVEL_STATE_CONSTRAINED_BOTTOM_SINCE_VERSION 7
1473
+
#endif /* XDG_TOPLEVEL_STATE_ENUM */
1474
+
1475
+
#ifndef XDG_TOPLEVEL_WM_CAPABILITIES_ENUM
1476
+
#define XDG_TOPLEVEL_WM_CAPABILITIES_ENUM
1477
+
enum xdg_toplevel_wm_capabilities {
1478
+
/**
1479
+
* show_window_menu is available
1480
+
*/
1481
+
XDG_TOPLEVEL_WM_CAPABILITIES_WINDOW_MENU = 1,
1482
+
/**
1483
+
* set_maximized and unset_maximized are available
1484
+
*/
1485
+
XDG_TOPLEVEL_WM_CAPABILITIES_MAXIMIZE = 2,
1486
+
/**
1487
+
* set_fullscreen and unset_fullscreen are available
1488
+
*/
1489
+
XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN = 3,
1490
+
/**
1491
+
* set_minimized is available
1492
+
*/
1493
+
XDG_TOPLEVEL_WM_CAPABILITIES_MINIMIZE = 4,
1494
+
};
1495
+
#endif /* XDG_TOPLEVEL_WM_CAPABILITIES_ENUM */
1496
+
1497
+
/**
1498
+
* @ingroup iface_xdg_toplevel
1499
+
* @struct xdg_toplevel_listener
1500
+
*/
1501
+
struct xdg_toplevel_listener {
1502
+
/**
1503
+
* suggest a surface change
1504
+
*
1505
+
* This configure event asks the client to resize its toplevel
1506
+
* surface or to change its state. The configured state should not
1507
+
* be applied immediately. See xdg_surface.configure for details.
1508
+
*
1509
+
* The width and height arguments specify a hint to the window
1510
+
* about how its surface should be resized in window geometry
1511
+
* coordinates. See set_window_geometry.
1512
+
*
1513
+
* If the width or height arguments are zero, it means the client
1514
+
* should decide its own window dimension. This may happen when the
1515
+
* compositor needs to configure the state of the surface but
1516
+
* doesn't have any information about any previous or expected
1517
+
* dimension.
1518
+
*
1519
+
* The states listed in the event specify how the width/height
1520
+
* arguments should be interpreted, and possibly how it should be
1521
+
* drawn.
1522
+
*
1523
+
* Clients must send an ack_configure in response to this event.
1524
+
* See xdg_surface.configure and xdg_surface.ack_configure for
1525
+
* details.
1526
+
*/
1527
+
void (*configure)(void *data,
1528
+
struct xdg_toplevel *xdg_toplevel,
1529
+
int32_t width,
1530
+
int32_t height,
1531
+
struct wl_array *states);
1532
+
/**
1533
+
* surface wants to be closed
1534
+
*
1535
+
* The close event is sent by the compositor when the user wants
1536
+
* the surface to be closed. This should be equivalent to the user
1537
+
* clicking the close button in client-side decorations, if your
1538
+
* application has any.
1539
+
*
1540
+
* This is only a request that the user intends to close the
1541
+
* window. The client may choose to ignore this request, or show a
1542
+
* dialog to ask the user to save their data, etc.
1543
+
*/
1544
+
void (*close)(void *data,
1545
+
struct xdg_toplevel *xdg_toplevel);
1546
+
/**
1547
+
* recommended window geometry bounds
1548
+
*
1549
+
* The configure_bounds event may be sent prior to a
1550
+
* xdg_toplevel.configure event to communicate the bounds a window
1551
+
* geometry size is recommended to constrain to.
1552
+
*
1553
+
* The passed width and height are in surface coordinate space. If
1554
+
* width and height are 0, it means bounds is unknown and
1555
+
* equivalent to as if no configure_bounds event was ever sent for
1556
+
* this surface.
1557
+
*
1558
+
* The bounds can for example correspond to the size of a monitor
1559
+
* excluding any panels or other shell components, so that a
1560
+
* surface isn't created in a way that it cannot fit.
1561
+
*
1562
+
* The bounds may change at any point, and in such a case, a new
1563
+
* xdg_toplevel.configure_bounds will be sent, followed by
1564
+
* xdg_toplevel.configure and xdg_surface.configure.
1565
+
* @since 4
1566
+
*/
1567
+
void (*configure_bounds)(void *data,
1568
+
struct xdg_toplevel *xdg_toplevel,
1569
+
int32_t width,
1570
+
int32_t height);
1571
+
/**
1572
+
* compositor capabilities
1573
+
*
1574
+
* This event advertises the capabilities supported by the
1575
+
* compositor. If a capability isn't supported, clients should hide
1576
+
* or disable the UI elements that expose this functionality. For
1577
+
* instance, if the compositor doesn't advertise support for
1578
+
* minimized toplevels, a button triggering the set_minimized
1579
+
* request should not be displayed.
1580
+
*
1581
+
* The compositor will ignore requests it doesn't support. For
1582
+
* instance, a compositor which doesn't advertise support for
1583
+
* minimized will ignore set_minimized requests.
1584
+
*
1585
+
* Compositors must send this event once before the first
1586
+
* xdg_surface.configure event. When the capabilities change,
1587
+
* compositors must send this event again and then send an
1588
+
* xdg_surface.configure event.
1589
+
*
1590
+
* The configured state should not be applied immediately. See
1591
+
* xdg_surface.configure for details.
1592
+
*
1593
+
* The capabilities are sent as an array of 32-bit unsigned
1594
+
* integers in native endianness.
1595
+
* @param capabilities array of 32-bit capabilities
1596
+
* @since 5
1597
+
*/
1598
+
void (*wm_capabilities)(void *data,
1599
+
struct xdg_toplevel *xdg_toplevel,
1600
+
struct wl_array *capabilities);
1601
+
};
1602
+
1603
+
/**
1604
+
* @ingroup iface_xdg_toplevel
1605
+
*/
1606
+
static inline int
1607
+
xdg_toplevel_add_listener(struct xdg_toplevel *xdg_toplevel,
1608
+
const struct xdg_toplevel_listener *listener, void *data)
1609
+
{
1610
+
return wl_proxy_add_listener((struct wl_proxy *) xdg_toplevel,
1611
+
(void (**)(void)) listener, data);
1612
+
}
1613
+
1614
+
#define XDG_TOPLEVEL_DESTROY 0
1615
+
#define XDG_TOPLEVEL_SET_PARENT 1
1616
+
#define XDG_TOPLEVEL_SET_TITLE 2
1617
+
#define XDG_TOPLEVEL_SET_APP_ID 3
1618
+
#define XDG_TOPLEVEL_SHOW_WINDOW_MENU 4
1619
+
#define XDG_TOPLEVEL_MOVE 5
1620
+
#define XDG_TOPLEVEL_RESIZE 6
1621
+
#define XDG_TOPLEVEL_SET_MAX_SIZE 7
1622
+
#define XDG_TOPLEVEL_SET_MIN_SIZE 8
1623
+
#define XDG_TOPLEVEL_SET_MAXIMIZED 9
1624
+
#define XDG_TOPLEVEL_UNSET_MAXIMIZED 10
1625
+
#define XDG_TOPLEVEL_SET_FULLSCREEN 11
1626
+
#define XDG_TOPLEVEL_UNSET_FULLSCREEN 12
1627
+
#define XDG_TOPLEVEL_SET_MINIMIZED 13
1628
+
1629
+
/**
1630
+
* @ingroup iface_xdg_toplevel
1631
+
*/
1632
+
#define XDG_TOPLEVEL_CONFIGURE_SINCE_VERSION 1
1633
+
/**
1634
+
* @ingroup iface_xdg_toplevel
1635
+
*/
1636
+
#define XDG_TOPLEVEL_CLOSE_SINCE_VERSION 1
1637
+
/**
1638
+
* @ingroup iface_xdg_toplevel
1639
+
*/
1640
+
#define XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION 4
1641
+
/**
1642
+
* @ingroup iface_xdg_toplevel
1643
+
*/
1644
+
#define XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION 5
1645
+
1646
+
/**
1647
+
* @ingroup iface_xdg_toplevel
1648
+
*/
1649
+
#define XDG_TOPLEVEL_DESTROY_SINCE_VERSION 1
1650
+
/**
1651
+
* @ingroup iface_xdg_toplevel
1652
+
*/
1653
+
#define XDG_TOPLEVEL_SET_PARENT_SINCE_VERSION 1
1654
+
/**
1655
+
* @ingroup iface_xdg_toplevel
1656
+
*/
1657
+
#define XDG_TOPLEVEL_SET_TITLE_SINCE_VERSION 1
1658
+
/**
1659
+
* @ingroup iface_xdg_toplevel
1660
+
*/
1661
+
#define XDG_TOPLEVEL_SET_APP_ID_SINCE_VERSION 1
1662
+
/**
1663
+
* @ingroup iface_xdg_toplevel
1664
+
*/
1665
+
#define XDG_TOPLEVEL_SHOW_WINDOW_MENU_SINCE_VERSION 1
1666
+
/**
1667
+
* @ingroup iface_xdg_toplevel
1668
+
*/
1669
+
#define XDG_TOPLEVEL_MOVE_SINCE_VERSION 1
1670
+
/**
1671
+
* @ingroup iface_xdg_toplevel
1672
+
*/
1673
+
#define XDG_TOPLEVEL_RESIZE_SINCE_VERSION 1
1674
+
/**
1675
+
* @ingroup iface_xdg_toplevel
1676
+
*/
1677
+
#define XDG_TOPLEVEL_SET_MAX_SIZE_SINCE_VERSION 1
1678
+
/**
1679
+
* @ingroup iface_xdg_toplevel
1680
+
*/
1681
+
#define XDG_TOPLEVEL_SET_MIN_SIZE_SINCE_VERSION 1
1682
+
/**
1683
+
* @ingroup iface_xdg_toplevel
1684
+
*/
1685
+
#define XDG_TOPLEVEL_SET_MAXIMIZED_SINCE_VERSION 1
1686
+
/**
1687
+
* @ingroup iface_xdg_toplevel
1688
+
*/
1689
+
#define XDG_TOPLEVEL_UNSET_MAXIMIZED_SINCE_VERSION 1
1690
+
/**
1691
+
* @ingroup iface_xdg_toplevel
1692
+
*/
1693
+
#define XDG_TOPLEVEL_SET_FULLSCREEN_SINCE_VERSION 1
1694
+
/**
1695
+
* @ingroup iface_xdg_toplevel
1696
+
*/
1697
+
#define XDG_TOPLEVEL_UNSET_FULLSCREEN_SINCE_VERSION 1
1698
+
/**
1699
+
* @ingroup iface_xdg_toplevel
1700
+
*/
1701
+
#define XDG_TOPLEVEL_SET_MINIMIZED_SINCE_VERSION 1
1702
+
1703
+
/** @ingroup iface_xdg_toplevel */
1704
+
static inline void
1705
+
xdg_toplevel_set_user_data(struct xdg_toplevel *xdg_toplevel, void *user_data)
1706
+
{
1707
+
wl_proxy_set_user_data((struct wl_proxy *) xdg_toplevel, user_data);
1708
+
}
1709
+
1710
+
/** @ingroup iface_xdg_toplevel */
1711
+
static inline void *
1712
+
xdg_toplevel_get_user_data(struct xdg_toplevel *xdg_toplevel)
1713
+
{
1714
+
return wl_proxy_get_user_data((struct wl_proxy *) xdg_toplevel);
1715
+
}
1716
+
1717
+
static inline uint32_t
1718
+
xdg_toplevel_get_version(struct xdg_toplevel *xdg_toplevel)
1719
+
{
1720
+
return wl_proxy_get_version((struct wl_proxy *) xdg_toplevel);
1721
+
}
1722
+
1723
+
/**
1724
+
* @ingroup iface_xdg_toplevel
1725
+
*
1726
+
* This request destroys the role surface and unmaps the surface;
1727
+
* see "Unmapping" behavior in interface section for details.
1728
+
*/
1729
+
static inline void
1730
+
xdg_toplevel_destroy(struct xdg_toplevel *xdg_toplevel)
1731
+
{
1732
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
1733
+
XDG_TOPLEVEL_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), WL_MARSHAL_FLAG_DESTROY);
1734
+
}
1735
+
1736
+
/**
1737
+
* @ingroup iface_xdg_toplevel
1738
+
*
1739
+
* Set the "parent" of this surface. This surface should be stacked
1740
+
* above the parent surface and all other ancestor surfaces.
1741
+
*
1742
+
* Parent surfaces should be set on dialogs, toolboxes, or other
1743
+
* "auxiliary" surfaces, so that the parent is raised when the dialog
1744
+
* is raised.
1745
+
*
1746
+
* Setting a null parent for a child surface unsets its parent. Setting
1747
+
* a null parent for a surface which currently has no parent is a no-op.
1748
+
*
1749
+
* Only mapped surfaces can have child surfaces. Setting a parent which
1750
+
* is not mapped is equivalent to setting a null parent. If a surface
1751
+
* becomes unmapped, its children's parent is set to the parent of
1752
+
* the now-unmapped surface. If the now-unmapped surface has no parent,
1753
+
* its children's parent is unset. If the now-unmapped surface becomes
1754
+
* mapped again, its parent-child relationship is not restored.
1755
+
*
1756
+
* The parent toplevel must not be one of the child toplevel's
1757
+
* descendants, and the parent must be different from the child toplevel,
1758
+
* otherwise the invalid_parent protocol error is raised.
1759
+
*/
1760
+
static inline void
1761
+
xdg_toplevel_set_parent(struct xdg_toplevel *xdg_toplevel, struct xdg_toplevel *parent)
1762
+
{
1763
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
1764
+
XDG_TOPLEVEL_SET_PARENT, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, parent);
1765
+
}
1766
+
1767
+
/**
1768
+
* @ingroup iface_xdg_toplevel
1769
+
*
1770
+
* Set a short title for the surface.
1771
+
*
1772
+
* This string may be used to identify the surface in a task bar,
1773
+
* window list, or other user interface elements provided by the
1774
+
* compositor.
1775
+
*
1776
+
* The string must be encoded in UTF-8.
1777
+
*/
1778
+
static inline void
1779
+
xdg_toplevel_set_title(struct xdg_toplevel *xdg_toplevel, const char *title)
1780
+
{
1781
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
1782
+
XDG_TOPLEVEL_SET_TITLE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, title);
1783
+
}
1784
+
1785
+
/**
1786
+
* @ingroup iface_xdg_toplevel
1787
+
*
1788
+
* Set an application identifier for the surface.
1789
+
*
1790
+
* The app ID identifies the general class of applications to which
1791
+
* the surface belongs. The compositor can use this to group multiple
1792
+
* surfaces together, or to determine how to launch a new application.
1793
+
*
1794
+
* For D-Bus activatable applications, the app ID is used as the D-Bus
1795
+
* service name.
1796
+
*
1797
+
* The compositor shell will try to group application surfaces together
1798
+
* by their app ID. As a best practice, it is suggested to select app
1799
+
* ID's that match the basename of the application's .desktop file.
1800
+
* For example, "org.freedesktop.FooViewer" where the .desktop file is
1801
+
* "org.freedesktop.FooViewer.desktop".
1802
+
*
1803
+
* Like other properties, a set_app_id request can be sent after the
1804
+
* xdg_toplevel has been mapped to update the property.
1805
+
*
1806
+
* See the desktop-entry specification [0] for more details on
1807
+
* application identifiers and how they relate to well-known D-Bus
1808
+
* names and .desktop files.
1809
+
*
1810
+
* [0] https://standards.freedesktop.org/desktop-entry-spec/
1811
+
*/
1812
+
static inline void
1813
+
xdg_toplevel_set_app_id(struct xdg_toplevel *xdg_toplevel, const char *app_id)
1814
+
{
1815
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
1816
+
XDG_TOPLEVEL_SET_APP_ID, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, app_id);
1817
+
}
1818
+
1819
+
/**
1820
+
* @ingroup iface_xdg_toplevel
1821
+
*
1822
+
* Clients implementing client-side decorations might want to show
1823
+
* a context menu when right-clicking on the decorations, giving the
1824
+
* user a menu that they can use to maximize or minimize the window.
1825
+
*
1826
+
* This request asks the compositor to pop up such a window menu at
1827
+
* the given position, relative to the local surface coordinates of
1828
+
* the parent surface. There are no guarantees as to what menu items
1829
+
* the window menu contains, or even if a window menu will be drawn
1830
+
* at all.
1831
+
*
1832
+
* This request must be used in response to some sort of user action
1833
+
* like a button press, key press, or touch down event.
1834
+
*/
1835
+
static inline void
1836
+
xdg_toplevel_show_window_menu(struct xdg_toplevel *xdg_toplevel, struct wl_seat *seat, uint32_t serial, int32_t x, int32_t y)
1837
+
{
1838
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
1839
+
XDG_TOPLEVEL_SHOW_WINDOW_MENU, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, seat, serial, x, y);
1840
+
}
1841
+
1842
+
/**
1843
+
* @ingroup iface_xdg_toplevel
1844
+
*
1845
+
* Start an interactive, user-driven move of the surface.
1846
+
*
1847
+
* This request must be used in response to some sort of user action
1848
+
* like a button press, key press, or touch down event. The passed
1849
+
* serial is used to determine the type of interactive move (touch,
1850
+
* pointer, etc).
1851
+
*
1852
+
* The server may ignore move requests depending on the state of
1853
+
* the surface (e.g. fullscreen or maximized), or if the passed serial
1854
+
* is no longer valid.
1855
+
*
1856
+
* If triggered, the surface will lose the focus of the device
1857
+
* (wl_pointer, wl_touch, etc) used for the move. It is up to the
1858
+
* compositor to visually indicate that the move is taking place, such as
1859
+
* updating a pointer cursor, during the move. There is no guarantee
1860
+
* that the device focus will return when the move is completed.
1861
+
*/
1862
+
static inline void
1863
+
xdg_toplevel_move(struct xdg_toplevel *xdg_toplevel, struct wl_seat *seat, uint32_t serial)
1864
+
{
1865
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
1866
+
XDG_TOPLEVEL_MOVE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, seat, serial);
1867
+
}
1868
+
1869
+
/**
1870
+
* @ingroup iface_xdg_toplevel
1871
+
*
1872
+
* Start a user-driven, interactive resize of the surface.
1873
+
*
1874
+
* This request must be used in response to some sort of user action
1875
+
* like a button press, key press, or touch down event. The passed
1876
+
* serial is used to determine the type of interactive resize (touch,
1877
+
* pointer, etc).
1878
+
*
1879
+
* The server may ignore resize requests depending on the state of
1880
+
* the surface (e.g. fullscreen or maximized).
1881
+
*
1882
+
* If triggered, the client will receive configure events with the
1883
+
* "resize" state enum value and the expected sizes. See the "resize"
1884
+
* enum value for more details about what is required. The client
1885
+
* must also acknowledge configure events using "ack_configure". After
1886
+
* the resize is completed, the client will receive another "configure"
1887
+
* event without the resize state.
1888
+
*
1889
+
* If triggered, the surface also will lose the focus of the device
1890
+
* (wl_pointer, wl_touch, etc) used for the resize. It is up to the
1891
+
* compositor to visually indicate that the resize is taking place,
1892
+
* such as updating a pointer cursor, during the resize. There is no
1893
+
* guarantee that the device focus will return when the resize is
1894
+
* completed.
1895
+
*
1896
+
* The edges parameter specifies how the surface should be resized, and
1897
+
* is one of the values of the resize_edge enum. Values not matching
1898
+
* a variant of the enum will cause the invalid_resize_edge protocol error.
1899
+
* The compositor may use this information to update the surface position
1900
+
* for example when dragging the top left corner. The compositor may also
1901
+
* use this information to adapt its behavior, e.g. choose an appropriate
1902
+
* cursor image.
1903
+
*/
1904
+
static inline void
1905
+
xdg_toplevel_resize(struct xdg_toplevel *xdg_toplevel, struct wl_seat *seat, uint32_t serial, uint32_t edges)
1906
+
{
1907
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
1908
+
XDG_TOPLEVEL_RESIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, seat, serial, edges);
1909
+
}
1910
+
1911
+
/**
1912
+
* @ingroup iface_xdg_toplevel
1913
+
*
1914
+
* Set a maximum size for the window.
1915
+
*
1916
+
* The client can specify a maximum size so that the compositor does
1917
+
* not try to configure the window beyond this size.
1918
+
*
1919
+
* The width and height arguments are in window geometry coordinates.
1920
+
* See xdg_surface.set_window_geometry.
1921
+
*
1922
+
* Values set in this way are double-buffered, see wl_surface.commit.
1923
+
*
1924
+
* The compositor can use this information to allow or disallow
1925
+
* different states like maximize or fullscreen and draw accurate
1926
+
* animations.
1927
+
*
1928
+
* Similarly, a tiling window manager may use this information to
1929
+
* place and resize client windows in a more effective way.
1930
+
*
1931
+
* The client should not rely on the compositor to obey the maximum
1932
+
* size. The compositor may decide to ignore the values set by the
1933
+
* client and request a larger size.
1934
+
*
1935
+
* If never set, or a value of zero in the request, means that the
1936
+
* client has no expected maximum size in the given dimension.
1937
+
* As a result, a client wishing to reset the maximum size
1938
+
* to an unspecified state can use zero for width and height in the
1939
+
* request.
1940
+
*
1941
+
* Requesting a maximum size to be smaller than the minimum size of
1942
+
* a surface is illegal and will result in an invalid_size error.
1943
+
*
1944
+
* The width and height must be greater than or equal to zero. Using
1945
+
* strictly negative values for width or height will result in a
1946
+
* invalid_size error.
1947
+
*/
1948
+
static inline void
1949
+
xdg_toplevel_set_max_size(struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height)
1950
+
{
1951
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
1952
+
XDG_TOPLEVEL_SET_MAX_SIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, width, height);
1953
+
}
1954
+
1955
+
/**
1956
+
* @ingroup iface_xdg_toplevel
1957
+
*
1958
+
* Set a minimum size for the window.
1959
+
*
1960
+
* The client can specify a minimum size so that the compositor does
1961
+
* not try to configure the window below this size.
1962
+
*
1963
+
* The width and height arguments are in window geometry coordinates.
1964
+
* See xdg_surface.set_window_geometry.
1965
+
*
1966
+
* Values set in this way are double-buffered, see wl_surface.commit.
1967
+
*
1968
+
* The compositor can use this information to allow or disallow
1969
+
* different states like maximize or fullscreen and draw accurate
1970
+
* animations.
1971
+
*
1972
+
* Similarly, a tiling window manager may use this information to
1973
+
* place and resize client windows in a more effective way.
1974
+
*
1975
+
* The client should not rely on the compositor to obey the minimum
1976
+
* size. The compositor may decide to ignore the values set by the
1977
+
* client and request a smaller size.
1978
+
*
1979
+
* If never set, or a value of zero in the request, means that the
1980
+
* client has no expected minimum size in the given dimension.
1981
+
* As a result, a client wishing to reset the minimum size
1982
+
* to an unspecified state can use zero for width and height in the
1983
+
* request.
1984
+
*
1985
+
* Requesting a minimum size to be larger than the maximum size of
1986
+
* a surface is illegal and will result in an invalid_size error.
1987
+
*
1988
+
* The width and height must be greater than or equal to zero. Using
1989
+
* strictly negative values for width and height will result in a
1990
+
* invalid_size error.
1991
+
*/
1992
+
static inline void
1993
+
xdg_toplevel_set_min_size(struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height)
1994
+
{
1995
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
1996
+
XDG_TOPLEVEL_SET_MIN_SIZE, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, width, height);
1997
+
}
1998
+
1999
+
/**
2000
+
* @ingroup iface_xdg_toplevel
2001
+
*
2002
+
* Maximize the surface.
2003
+
*
2004
+
* After requesting that the surface should be maximized, the compositor
2005
+
* will respond by emitting a configure event. Whether this configure
2006
+
* actually sets the window maximized is subject to compositor policies.
2007
+
* The client must then update its content, drawing in the configured
2008
+
* state. The client must also acknowledge the configure when committing
2009
+
* the new content (see ack_configure).
2010
+
*
2011
+
* It is up to the compositor to decide how and where to maximize the
2012
+
* surface, for example which output and what region of the screen should
2013
+
* be used.
2014
+
*
2015
+
* If the surface was already maximized, the compositor will still emit
2016
+
* a configure event with the "maximized" state.
2017
+
*
2018
+
* If the surface is in a fullscreen state, this request has no direct
2019
+
* effect. It may alter the state the surface is returned to when
2020
+
* unmaximized unless overridden by the compositor.
2021
+
*/
2022
+
static inline void
2023
+
xdg_toplevel_set_maximized(struct xdg_toplevel *xdg_toplevel)
2024
+
{
2025
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
2026
+
XDG_TOPLEVEL_SET_MAXIMIZED, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0);
2027
+
}
2028
+
2029
+
/**
2030
+
* @ingroup iface_xdg_toplevel
2031
+
*
2032
+
* Unmaximize the surface.
2033
+
*
2034
+
* After requesting that the surface should be unmaximized, the compositor
2035
+
* will respond by emitting a configure event. Whether this actually
2036
+
* un-maximizes the window is subject to compositor policies.
2037
+
* If available and applicable, the compositor will include the window
2038
+
* geometry dimensions the window had prior to being maximized in the
2039
+
* configure event. The client must then update its content, drawing it in
2040
+
* the configured state. The client must also acknowledge the configure
2041
+
* when committing the new content (see ack_configure).
2042
+
*
2043
+
* It is up to the compositor to position the surface after it was
2044
+
* unmaximized; usually the position the surface had before maximizing, if
2045
+
* applicable.
2046
+
*
2047
+
* If the surface was already not maximized, the compositor will still
2048
+
* emit a configure event without the "maximized" state.
2049
+
*
2050
+
* If the surface is in a fullscreen state, this request has no direct
2051
+
* effect. It may alter the state the surface is returned to when
2052
+
* unmaximized unless overridden by the compositor.
2053
+
*/
2054
+
static inline void
2055
+
xdg_toplevel_unset_maximized(struct xdg_toplevel *xdg_toplevel)
2056
+
{
2057
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
2058
+
XDG_TOPLEVEL_UNSET_MAXIMIZED, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0);
2059
+
}
2060
+
2061
+
/**
2062
+
* @ingroup iface_xdg_toplevel
2063
+
*
2064
+
* Make the surface fullscreen.
2065
+
*
2066
+
* After requesting that the surface should be fullscreened, the
2067
+
* compositor will respond by emitting a configure event. Whether the
2068
+
* client is actually put into a fullscreen state is subject to compositor
2069
+
* policies. The client must also acknowledge the configure when
2070
+
* committing the new content (see ack_configure).
2071
+
*
2072
+
* The output passed by the request indicates the client's preference as
2073
+
* to which display it should be set fullscreen on. If this value is NULL,
2074
+
* it's up to the compositor to choose which display will be used to map
2075
+
* this surface.
2076
+
*
2077
+
* If the surface doesn't cover the whole output, the compositor will
2078
+
* position the surface in the center of the output and compensate with
2079
+
* with border fill covering the rest of the output. The content of the
2080
+
* border fill is undefined, but should be assumed to be in some way that
2081
+
* attempts to blend into the surrounding area (e.g. solid black).
2082
+
*
2083
+
* If the fullscreened surface is not opaque, the compositor must make
2084
+
* sure that other screen content not part of the same surface tree (made
2085
+
* up of subsurfaces, popups or similarly coupled surfaces) are not
2086
+
* visible below the fullscreened surface.
2087
+
*/
2088
+
static inline void
2089
+
xdg_toplevel_set_fullscreen(struct xdg_toplevel *xdg_toplevel, struct wl_output *output)
2090
+
{
2091
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
2092
+
XDG_TOPLEVEL_SET_FULLSCREEN, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0, output);
2093
+
}
2094
+
2095
+
/**
2096
+
* @ingroup iface_xdg_toplevel
2097
+
*
2098
+
* Make the surface no longer fullscreen.
2099
+
*
2100
+
* After requesting that the surface should be unfullscreened, the
2101
+
* compositor will respond by emitting a configure event.
2102
+
* Whether this actually removes the fullscreen state of the client is
2103
+
* subject to compositor policies.
2104
+
*
2105
+
* Making a surface unfullscreen sets states for the surface based on the following:
2106
+
* * the state(s) it may have had before becoming fullscreen
2107
+
* * any state(s) decided by the compositor
2108
+
* * any state(s) requested by the client while the surface was fullscreen
2109
+
*
2110
+
* The compositor may include the previous window geometry dimensions in
2111
+
* the configure event, if applicable.
2112
+
*
2113
+
* The client must also acknowledge the configure when committing the new
2114
+
* content (see ack_configure).
2115
+
*/
2116
+
static inline void
2117
+
xdg_toplevel_unset_fullscreen(struct xdg_toplevel *xdg_toplevel)
2118
+
{
2119
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
2120
+
XDG_TOPLEVEL_UNSET_FULLSCREEN, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0);
2121
+
}
2122
+
2123
+
/**
2124
+
* @ingroup iface_xdg_toplevel
2125
+
*
2126
+
* Request that the compositor minimize your surface. There is no
2127
+
* way to know if the surface is currently minimized, nor is there
2128
+
* any way to unset minimization on this surface.
2129
+
*
2130
+
* If you are looking to throttle redrawing when minimized, please
2131
+
* instead use the wl_surface.frame event for this, as this will
2132
+
* also work with live previews on windows in Alt-Tab, Expose or
2133
+
* similar compositor features.
2134
+
*/
2135
+
static inline void
2136
+
xdg_toplevel_set_minimized(struct xdg_toplevel *xdg_toplevel)
2137
+
{
2138
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_toplevel,
2139
+
XDG_TOPLEVEL_SET_MINIMIZED, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_toplevel), 0);
2140
+
}
2141
+
2142
+
#ifndef XDG_POPUP_ERROR_ENUM
2143
+
#define XDG_POPUP_ERROR_ENUM
2144
+
enum xdg_popup_error {
2145
+
/**
2146
+
* tried to grab after being mapped
2147
+
*/
2148
+
XDG_POPUP_ERROR_INVALID_GRAB = 0,
2149
+
};
2150
+
#endif /* XDG_POPUP_ERROR_ENUM */
2151
+
2152
+
/**
2153
+
* @ingroup iface_xdg_popup
2154
+
* @struct xdg_popup_listener
2155
+
*/
2156
+
struct xdg_popup_listener {
2157
+
/**
2158
+
* configure the popup surface
2159
+
*
2160
+
* This event asks the popup surface to configure itself given
2161
+
* the configuration. The configured state should not be applied
2162
+
* immediately. See xdg_surface.configure for details.
2163
+
*
2164
+
* The x and y arguments represent the position the popup was
2165
+
* placed at given the xdg_positioner rule, relative to the upper
2166
+
* left corner of the window geometry of the parent surface.
2167
+
*
2168
+
* For version 2 or older, the configure event for an xdg_popup is
2169
+
* only ever sent once for the initial configuration. Starting with
2170
+
* version 3, it may be sent again if the popup is setup with an
2171
+
* xdg_positioner with set_reactive requested, or in response to
2172
+
* xdg_popup.reposition requests.
2173
+
* @param x x position relative to parent surface window geometry
2174
+
* @param y y position relative to parent surface window geometry
2175
+
* @param width window geometry width
2176
+
* @param height window geometry height
2177
+
*/
2178
+
void (*configure)(void *data,
2179
+
struct xdg_popup *xdg_popup,
2180
+
int32_t x,
2181
+
int32_t y,
2182
+
int32_t width,
2183
+
int32_t height);
2184
+
/**
2185
+
* popup interaction is done
2186
+
*
2187
+
* The popup_done event is sent out when a popup is dismissed by
2188
+
* the compositor. The client should destroy the xdg_popup object
2189
+
* at this point.
2190
+
*/
2191
+
void (*popup_done)(void *data,
2192
+
struct xdg_popup *xdg_popup);
2193
+
/**
2194
+
* signal the completion of a repositioned request
2195
+
*
2196
+
* The repositioned event is sent as part of a popup
2197
+
* configuration sequence, together with xdg_popup.configure and
2198
+
* lastly xdg_surface.configure to notify the completion of a
2199
+
* reposition request.
2200
+
*
2201
+
* The repositioned event is to notify about the completion of a
2202
+
* xdg_popup.reposition request. The token argument is the token
2203
+
* passed in the xdg_popup.reposition request.
2204
+
*
2205
+
* Immediately after this event is emitted, xdg_popup.configure and
2206
+
* xdg_surface.configure will be sent with the updated size and
2207
+
* position, as well as a new configure serial.
2208
+
*
2209
+
* The client should optionally update the content of the popup,
2210
+
* but must acknowledge the new popup configuration for the new
2211
+
* position to take effect. See xdg_surface.ack_configure for
2212
+
* details.
2213
+
* @param token reposition request token
2214
+
* @since 3
2215
+
*/
2216
+
void (*repositioned)(void *data,
2217
+
struct xdg_popup *xdg_popup,
2218
+
uint32_t token);
2219
+
};
2220
+
2221
+
/**
2222
+
* @ingroup iface_xdg_popup
2223
+
*/
2224
+
static inline int
2225
+
xdg_popup_add_listener(struct xdg_popup *xdg_popup,
2226
+
const struct xdg_popup_listener *listener, void *data)
2227
+
{
2228
+
return wl_proxy_add_listener((struct wl_proxy *) xdg_popup,
2229
+
(void (**)(void)) listener, data);
2230
+
}
2231
+
2232
+
#define XDG_POPUP_DESTROY 0
2233
+
#define XDG_POPUP_GRAB 1
2234
+
#define XDG_POPUP_REPOSITION 2
2235
+
2236
+
/**
2237
+
* @ingroup iface_xdg_popup
2238
+
*/
2239
+
#define XDG_POPUP_CONFIGURE_SINCE_VERSION 1
2240
+
/**
2241
+
* @ingroup iface_xdg_popup
2242
+
*/
2243
+
#define XDG_POPUP_POPUP_DONE_SINCE_VERSION 1
2244
+
/**
2245
+
* @ingroup iface_xdg_popup
2246
+
*/
2247
+
#define XDG_POPUP_REPOSITIONED_SINCE_VERSION 3
2248
+
2249
+
/**
2250
+
* @ingroup iface_xdg_popup
2251
+
*/
2252
+
#define XDG_POPUP_DESTROY_SINCE_VERSION 1
2253
+
/**
2254
+
* @ingroup iface_xdg_popup
2255
+
*/
2256
+
#define XDG_POPUP_GRAB_SINCE_VERSION 1
2257
+
/**
2258
+
* @ingroup iface_xdg_popup
2259
+
*/
2260
+
#define XDG_POPUP_REPOSITION_SINCE_VERSION 3
2261
+
2262
+
/** @ingroup iface_xdg_popup */
2263
+
static inline void
2264
+
xdg_popup_set_user_data(struct xdg_popup *xdg_popup, void *user_data)
2265
+
{
2266
+
wl_proxy_set_user_data((struct wl_proxy *) xdg_popup, user_data);
2267
+
}
2268
+
2269
+
/** @ingroup iface_xdg_popup */
2270
+
static inline void *
2271
+
xdg_popup_get_user_data(struct xdg_popup *xdg_popup)
2272
+
{
2273
+
return wl_proxy_get_user_data((struct wl_proxy *) xdg_popup);
2274
+
}
2275
+
2276
+
static inline uint32_t
2277
+
xdg_popup_get_version(struct xdg_popup *xdg_popup)
2278
+
{
2279
+
return wl_proxy_get_version((struct wl_proxy *) xdg_popup);
2280
+
}
2281
+
2282
+
/**
2283
+
* @ingroup iface_xdg_popup
2284
+
*
2285
+
* This destroys the popup. Explicitly destroying the xdg_popup
2286
+
* object will also dismiss the popup, and unmap the surface.
2287
+
*
2288
+
* If this xdg_popup is not the "topmost" popup, the
2289
+
* xdg_wm_base.not_the_topmost_popup protocol error will be sent.
2290
+
*/
2291
+
static inline void
2292
+
xdg_popup_destroy(struct xdg_popup *xdg_popup)
2293
+
{
2294
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_popup,
2295
+
XDG_POPUP_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_popup), WL_MARSHAL_FLAG_DESTROY);
2296
+
}
2297
+
2298
+
/**
2299
+
* @ingroup iface_xdg_popup
2300
+
*
2301
+
* This request makes the created popup take an explicit grab. An explicit
2302
+
* grab will be dismissed when the user dismisses the popup, or when the
2303
+
* client destroys the xdg_popup. This can be done by the user clicking
2304
+
* outside the surface, using the keyboard, or even locking the screen
2305
+
* through closing the lid or a timeout.
2306
+
*
2307
+
* If the compositor denies the grab, the popup will be immediately
2308
+
* dismissed.
2309
+
*
2310
+
* This request must be used in response to some sort of user action like a
2311
+
* button press, key press, or touch down event. The serial number of the
2312
+
* event should be passed as 'serial'.
2313
+
*
2314
+
* The parent of a grabbing popup must either be an xdg_toplevel surface or
2315
+
* another xdg_popup with an explicit grab. If the parent is another
2316
+
* xdg_popup it means that the popups are nested, with this popup now being
2317
+
* the topmost popup.
2318
+
*
2319
+
* Nested popups must be destroyed in the reverse order they were created
2320
+
* in, e.g. the only popup you are allowed to destroy at all times is the
2321
+
* topmost one.
2322
+
*
2323
+
* When compositors choose to dismiss a popup, they may dismiss every
2324
+
* nested grabbing popup as well. When a compositor dismisses popups, it
2325
+
* will follow the same dismissing order as required from the client.
2326
+
*
2327
+
* If the topmost grabbing popup is destroyed, the grab will be returned to
2328
+
* the parent of the popup, if that parent previously had an explicit grab.
2329
+
*
2330
+
* If the parent is a grabbing popup which has already been dismissed, this
2331
+
* popup will be immediately dismissed. If the parent is a popup that did
2332
+
* not take an explicit grab, an error will be raised.
2333
+
*
2334
+
* During a popup grab, the client owning the grab will receive pointer
2335
+
* and touch events for all their surfaces as normal (similar to an
2336
+
* "owner-events" grab in X11 parlance), while the top most grabbing popup
2337
+
* will always have keyboard focus.
2338
+
*/
2339
+
static inline void
2340
+
xdg_popup_grab(struct xdg_popup *xdg_popup, struct wl_seat *seat, uint32_t serial)
2341
+
{
2342
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_popup,
2343
+
XDG_POPUP_GRAB, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_popup), 0, seat, serial);
2344
+
}
2345
+
2346
+
/**
2347
+
* @ingroup iface_xdg_popup
2348
+
*
2349
+
* Reposition an already-mapped popup. The popup will be placed given the
2350
+
* details in the passed xdg_positioner object, and a
2351
+
* xdg_popup.repositioned followed by xdg_popup.configure and
2352
+
* xdg_surface.configure will be emitted in response. Any parameters set
2353
+
* by the previous positioner will be discarded.
2354
+
*
2355
+
* The passed token will be sent in the corresponding
2356
+
* xdg_popup.repositioned event. The new popup position will not take
2357
+
* effect until the corresponding configure event is acknowledged by the
2358
+
* client. See xdg_popup.repositioned for details. The token itself is
2359
+
* opaque, and has no other special meaning.
2360
+
*
2361
+
* If multiple reposition requests are sent, the compositor may skip all
2362
+
* but the last one.
2363
+
*
2364
+
* If the popup is repositioned in response to a configure event for its
2365
+
* parent, the client should send an xdg_positioner.set_parent_configure
2366
+
* and possibly an xdg_positioner.set_parent_size request to allow the
2367
+
* compositor to properly constrain the popup.
2368
+
*
2369
+
* If the popup is repositioned together with a parent that is being
2370
+
* resized, but not in response to a configure event, the client should
2371
+
* send an xdg_positioner.set_parent_size request.
2372
+
*/
2373
+
static inline void
2374
+
xdg_popup_reposition(struct xdg_popup *xdg_popup, struct xdg_positioner *positioner, uint32_t token)
2375
+
{
2376
+
wl_proxy_marshal_flags((struct wl_proxy *) xdg_popup,
2377
+
XDG_POPUP_REPOSITION, NULL, wl_proxy_get_version((struct wl_proxy *) xdg_popup), 0, positioner, token);
2378
+
}
2379
+
2380
+
#ifdef __cplusplus
2381
+
}
2382
+
#endif
2383
+
2384
+
#endif
+139
internal/screenshot/portal.go
+139
internal/screenshot/portal.go
···
1
+
package screenshot
2
+
3
+
import (
4
+
"fmt"
5
+
"net/url"
6
+
"strings"
7
+
"time"
8
+
9
+
"github.com/godbus/dbus/v5"
10
+
)
11
+
12
+
const (
13
+
portalService = "org.freedesktop.portal.Desktop"
14
+
portalPath = "/org/freedesktop/portal/desktop"
15
+
portalInterface = "org.freedesktop.portal.Screenshot"
16
+
requestIface = "org.freedesktop.portal.Request"
17
+
)
18
+
19
+
// CaptureScreenshot triggers the XDG Desktop Portal screenshot dialog.
20
+
// Returns the path to the captured image file.
21
+
// The interactive parameter controls whether the user can select a region (true)
22
+
// or if it captures the entire screen immediately (false).
23
+
func CaptureScreenshot(interactive bool) (string, error) {
24
+
conn, err := dbus.ConnectSessionBus()
25
+
if err != nil {
26
+
return "", fmt.Errorf("failed to connect to session bus: %w", err)
27
+
}
28
+
defer conn.Close()
29
+
30
+
// Generate unique handle token
31
+
token := fmt.Sprintf("blup_%d", time.Now().UnixNano())
32
+
33
+
// Build the expected request path
34
+
// The path format is: /org/freedesktop/portal/desktop/request/{sender}/{token}
35
+
// where sender is the unique bus name with ':' replaced by '_' and '.' replaced by '_'
36
+
sender := conn.Names()[0]
37
+
sender = strings.ReplaceAll(sender[1:], ".", "_") // Remove leading ':' and replace dots
38
+
handlePath := dbus.ObjectPath(fmt.Sprintf("/org/freedesktop/portal/desktop/request/%s/%s", sender, token))
39
+
40
+
// Subscribe to Response signal before making request
41
+
ch := make(chan *dbus.Signal, 10)
42
+
conn.Signal(ch)
43
+
44
+
// Use AddMatchSignal for more reliable matching
45
+
if err := conn.AddMatchSignal(
46
+
dbus.WithMatchObjectPath(handlePath),
47
+
dbus.WithMatchInterface(requestIface),
48
+
dbus.WithMatchMember("Response"),
49
+
); err != nil {
50
+
return "", fmt.Errorf("failed to add signal match: %w", err)
51
+
}
52
+
defer conn.RemoveMatchSignal(
53
+
dbus.WithMatchObjectPath(handlePath),
54
+
dbus.WithMatchInterface(requestIface),
55
+
dbus.WithMatchMember("Response"),
56
+
)
57
+
58
+
// Call Screenshot method
59
+
obj := conn.Object(portalService, dbus.ObjectPath(portalPath))
60
+
options := map[string]dbus.Variant{
61
+
"handle_token": dbus.MakeVariant(token),
62
+
"interactive": dbus.MakeVariant(interactive),
63
+
}
64
+
65
+
var requestPath dbus.ObjectPath
66
+
err = obj.Call(portalInterface+".Screenshot", 0, "", options).Store(&requestPath)
67
+
if err != nil {
68
+
return "", fmt.Errorf("failed to call Screenshot: %w", err)
69
+
}
70
+
71
+
// Wait for Response signal with timeout
72
+
timeout := time.After(120 * time.Second)
73
+
for {
74
+
select {
75
+
case signal := <-ch:
76
+
// Check if this is the signal we're waiting for
77
+
if signal.Path != handlePath {
78
+
continue
79
+
}
80
+
if signal.Name != requestIface+".Response" {
81
+
continue
82
+
}
83
+
84
+
if len(signal.Body) < 2 {
85
+
return "", fmt.Errorf("invalid response signal: body has %d elements, expected at least 2", len(signal.Body))
86
+
}
87
+
88
+
responseCode, ok := signal.Body[0].(uint32)
89
+
if !ok {
90
+
return "", fmt.Errorf("invalid response code type: %T", signal.Body[0])
91
+
}
92
+
93
+
if responseCode != 0 {
94
+
if responseCode == 1 {
95
+
return "", fmt.Errorf("screenshot cancelled by user")
96
+
}
97
+
return "", fmt.Errorf("screenshot failed with code: %d", responseCode)
98
+
}
99
+
100
+
results, ok := signal.Body[1].(map[string]dbus.Variant)
101
+
if !ok {
102
+
return "", fmt.Errorf("invalid results type: %T", signal.Body[1])
103
+
}
104
+
105
+
uriVariant, ok := results["uri"]
106
+
if !ok {
107
+
return "", fmt.Errorf("no uri in response")
108
+
}
109
+
110
+
uri, ok := uriVariant.Value().(string)
111
+
if !ok {
112
+
return "", fmt.Errorf("invalid uri type")
113
+
}
114
+
115
+
// Convert file:// URI to path
116
+
filePath, err := uriToPath(uri)
117
+
if err != nil {
118
+
return "", fmt.Errorf("failed to parse URI: %w", err)
119
+
}
120
+
121
+
return filePath, nil
122
+
123
+
case <-timeout:
124
+
return "", fmt.Errorf("timeout waiting for screenshot response")
125
+
}
126
+
}
127
+
}
128
+
129
+
// uriToPath converts a file:// URI to a filesystem path
130
+
func uriToPath(uri string) (string, error) {
131
+
u, err := url.Parse(uri)
132
+
if err != nil {
133
+
return "", err
134
+
}
135
+
if u.Scheme != "file" {
136
+
return "", fmt.Errorf("expected file:// URI, got %s", u.Scheme)
137
+
}
138
+
return u.Path, nil
139
+
}
+62
-63
internal/util/util.go
+62
-63
internal/util/util.go
···
1
1
package util
2
2
3
3
import (
4
-
"fmt"
5
-
"math/big"
6
-
"strings"
7
-
"github.com/ipfs/go-cid"
4
+
"fmt"
5
+
"github.com/ipfs/go-cid"
6
+
"math/big"
7
+
"strings"
8
8
)
9
9
10
10
const base62Alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
11
11
12
12
// ConvertCIDBase32ToBase62 converts an IPFS CID from base32 to base62
13
13
func ConvertCIDBase32ToBase62(cidBase32 string) (string, error) {
14
-
c, err := cid.Decode(cidBase32)
15
-
if err != nil {
16
-
return "", err
17
-
}
18
-
return encodeBase62(c.Bytes()), nil
14
+
c, err := cid.Decode(cidBase32)
15
+
if err != nil {
16
+
return "", err
17
+
}
18
+
return encodeBase62(c.Bytes()), nil
19
19
}
20
20
21
21
// ConvertCIDBase62ToBase32 converts an IPFS CID from base62 to base32
22
22
func ConvertCIDBase62ToBase32(cidBase62 string) (string, error) {
23
-
decodedBytes, err := decodeBase62(cidBase62)
24
-
if err != nil {
25
-
return "", fmt.Errorf("failed to decode base62: %w", err)
26
-
}
27
-
c, err := cid.Cast(decodedBytes)
28
-
if err != nil {
29
-
return "", err
30
-
}
23
+
decodedBytes, err := decodeBase62(cidBase62)
24
+
if err != nil {
25
+
return "", fmt.Errorf("failed to decode base62: %w", err)
26
+
}
27
+
c, err := cid.Cast(decodedBytes)
28
+
if err != nil {
29
+
return "", err
30
+
}
31
31
32
-
return c.String(), nil
32
+
return c.String(), nil
33
33
}
34
34
35
35
func encodeBase62(data []byte) string {
36
-
if len(data) == 0 {
37
-
return ""
38
-
}
36
+
if len(data) == 0 {
37
+
return ""
38
+
}
39
39
40
-
num := new(big.Int).SetBytes(data)
41
-
if num.Cmp(big.NewInt(0)) == 0 {
42
-
return "0"
43
-
}
40
+
num := new(big.Int).SetBytes(data)
41
+
if num.Cmp(big.NewInt(0)) == 0 {
42
+
return "0"
43
+
}
44
44
45
-
var result []byte
46
-
base := big.NewInt(62)
47
-
zero := big.NewInt(0)
45
+
var result []byte
46
+
base := big.NewInt(62)
47
+
zero := big.NewInt(0)
48
48
49
-
50
-
for num.Cmp(zero) > 0 {
51
-
remainder := new(big.Int)
52
-
num.DivMod(num, base, remainder)
53
-
result = append(result, base62Alphabet[remainder.Int64()])
54
-
}
49
+
for num.Cmp(zero) > 0 {
50
+
remainder := new(big.Int)
51
+
num.DivMod(num, base, remainder)
52
+
result = append(result, base62Alphabet[remainder.Int64()])
53
+
}
55
54
56
-
// Reverse the result
57
-
for i, j := 0, len(result)-1; i < j; i, j = i+1, j-1 {
58
-
result[i], result[j] = result[j], result[i]
59
-
}
55
+
// Reverse the result
56
+
for i, j := 0, len(result)-1; i < j; i, j = i+1, j-1 {
57
+
result[i], result[j] = result[j], result[i]
58
+
}
60
59
61
-
return string(result)
60
+
return string(result)
62
61
}
63
62
64
63
func decodeBase62(encoded string) ([]byte, error) {
65
-
if encoded == "" {
66
-
return []byte{}, nil
67
-
}
64
+
if encoded == "" {
65
+
return []byte{}, nil
66
+
}
68
67
69
-
num := big.NewInt(0)
70
-
base := big.NewInt(62)
68
+
num := big.NewInt(0)
69
+
base := big.NewInt(62)
71
70
72
-
for _, char := range encoded {
73
-
index := strings.IndexRune(base62Alphabet, char)
74
-
if index == -1 {
75
-
return nil, fmt.Errorf("invalid character in base62 string: %c", char)
76
-
}
71
+
for _, char := range encoded {
72
+
index := strings.IndexRune(base62Alphabet, char)
73
+
if index == -1 {
74
+
return nil, fmt.Errorf("invalid character in base62 string: %c", char)
75
+
}
77
76
78
-
num.Mul(num, base)
79
-
num.Add(num, big.NewInt(int64(index)))
80
-
}
77
+
num.Mul(num, base)
78
+
num.Add(num, big.NewInt(int64(index)))
79
+
}
81
80
82
-
return num.Bytes(), nil
81
+
return num.Bytes(), nil
83
82
}
84
83
85
84
func IsBase32(str string) bool {
86
-
if str == "" {
87
-
return false
88
-
}
89
-
// Base32 uses A-Z, 2-7 (case insensitive)
90
-
for _, char := range strings.ToUpper(str) {
91
-
if !((char >= 'A' && char <= 'Z') || (char >= '2' && char <= '7') || char == '=') {
92
-
return false
93
-
}
94
-
}
95
-
return len(str) > 0
85
+
if str == "" {
86
+
return false
87
+
}
88
+
// Base32 uses A-Z, 2-7 (case insensitive)
89
+
for _, char := range strings.ToUpper(str) {
90
+
if !((char >= 'A' && char <= 'Z') || (char >= '2' && char <= '7') || char == '=') {
91
+
return false
92
+
}
93
+
}
94
+
return len(str) > 0
96
95
}
+219
-219
internal/util/util_test.go
+219
-219
internal/util/util_test.go
···
8
8
9
9
// Real IPFS CIDs for testing
10
10
var validCIDs = []string{
11
-
"bafkreigns2g4c46vrdvj6wlv7jka2binxftkadssvv5mxakqz4vulbfroi",
12
-
"bafkreigms7evfvvxtsb2azgx64wfqv3xt62elwwt5zjtv2dcgd4idu3erm",
13
-
"bafkreieedz3pv6onkm5ombpwbx43ytwzff3qgzing5ym45xthlnvku2wha",
11
+
"bafkreigns2g4c46vrdvj6wlv7jka2binxftkadssvv5mxakqz4vulbfroi",
12
+
"bafkreigms7evfvvxtsb2azgx64wfqv3xt62elwwt5zjtv2dcgd4idu3erm",
13
+
"bafkreieedz3pv6onkm5ombpwbx43ytwzff3qgzing5ym45xthlnvku2wha",
14
14
}
15
15
16
16
func TestConvertCIDBase32ToBase62(t *testing.T) {
17
-
tests := []struct {
18
-
name string
19
-
input string
20
-
wantErr bool
21
-
}{
22
-
{
23
-
name: "valid IPFS CID 1",
24
-
input: "bafkreigns2g4c46vrdvj6wlv7jka2binxftkadssvv5mxakqz4vulbfroi",
25
-
wantErr: false,
26
-
},
27
-
{
28
-
name: "valid IPFS CID 2",
29
-
input: "bafkreigms7evfvvxtsb2azgx64wfqv3xt62elwwt5zjtv2dcgd4idu3erm",
30
-
wantErr: false,
31
-
},
32
-
{
33
-
name: "valid IPFS CID 3",
34
-
input: "bafkreieedz3pv6onkm5ombpwbx43ytwzff3qgzing5ym45xthlnvku2wha",
35
-
wantErr: false,
36
-
},
37
-
{
38
-
name: "empty string",
39
-
input: "",
40
-
wantErr: true,
41
-
},
42
-
{
43
-
name: "invalid characters",
44
-
input: "invalid123!@#",
45
-
wantErr: true,
46
-
},
47
-
{
48
-
name: "only prefix",
49
-
input: "bafkrei",
50
-
wantErr: true,
51
-
},
52
-
}
17
+
tests := []struct {
18
+
name string
19
+
input string
20
+
wantErr bool
21
+
}{
22
+
{
23
+
name: "valid IPFS CID 1",
24
+
input: "bafkreigns2g4c46vrdvj6wlv7jka2binxftkadssvv5mxakqz4vulbfroi",
25
+
wantErr: false,
26
+
},
27
+
{
28
+
name: "valid IPFS CID 2",
29
+
input: "bafkreigms7evfvvxtsb2azgx64wfqv3xt62elwwt5zjtv2dcgd4idu3erm",
30
+
wantErr: false,
31
+
},
32
+
{
33
+
name: "valid IPFS CID 3",
34
+
input: "bafkreieedz3pv6onkm5ombpwbx43ytwzff3qgzing5ym45xthlnvku2wha",
35
+
wantErr: false,
36
+
},
37
+
{
38
+
name: "empty string",
39
+
input: "",
40
+
wantErr: true,
41
+
},
42
+
{
43
+
name: "invalid characters",
44
+
input: "invalid123!@#",
45
+
wantErr: true,
46
+
},
47
+
{
48
+
name: "only prefix",
49
+
input: "bafkrei",
50
+
wantErr: true,
51
+
},
52
+
}
53
53
54
-
for _, tt := range tests {
55
-
t.Run(tt.name, func(t *testing.T) {
56
-
result, err := ConvertCIDBase32ToBase62(tt.input)
54
+
for _, tt := range tests {
55
+
t.Run(tt.name, func(t *testing.T) {
56
+
result, err := ConvertCIDBase32ToBase62(tt.input)
57
57
58
-
if tt.wantErr {
59
-
if err == nil {
60
-
t.Errorf("ConvertCIDBase32ToBase62() expected error but got %v", result)
61
-
}
62
-
return
63
-
}
58
+
if tt.wantErr {
59
+
if err == nil {
60
+
t.Errorf("ConvertCIDBase32ToBase62() expected error but got %v", result)
61
+
}
62
+
return
63
+
}
64
64
65
-
if err != nil {
66
-
t.Errorf("ConvertCIDBase32ToBase62() unexpected error: %v", err)
67
-
return
68
-
}
65
+
if err != nil {
66
+
t.Errorf("ConvertCIDBase32ToBase62() unexpected error: %v", err)
67
+
return
68
+
}
69
69
70
-
if result == "" {
71
-
t.Errorf("ConvertCIDBase32ToBase62() returned empty result")
72
-
}
70
+
if result == "" {
71
+
t.Errorf("ConvertCIDBase32ToBase62() returned empty result")
72
+
}
73
73
74
-
t.Logf("Converted %s to %s", tt.input, result)
75
-
})
76
-
}
74
+
t.Logf("Converted %s to %s", tt.input, result)
75
+
})
76
+
}
77
77
}
78
78
79
79
func TestRoundTripConversionWithRealCIDs(t *testing.T) {
80
-
for i, originalCID := range validCIDs {
81
-
t.Run(fmt.Sprintf("real_cid_%d", i+1), func(t *testing.T) {
82
-
// Convert to base62
83
-
base62Result, err := ConvertCIDBase32ToBase62(originalCID)
84
-
if err != nil {
85
-
t.Fatalf("Failed to convert to base62: %v", err)
86
-
}
80
+
for i, originalCID := range validCIDs {
81
+
t.Run(fmt.Sprintf("real_cid_%d", i+1), func(t *testing.T) {
82
+
// Convert to base62
83
+
base62Result, err := ConvertCIDBase32ToBase62(originalCID)
84
+
if err != nil {
85
+
t.Fatalf("Failed to convert to base62: %v", err)
86
+
}
87
87
88
-
t.Logf("Original CID: %s", originalCID)
89
-
t.Logf("Base62: %s", base62Result)
90
-
t.Logf("Length reduction: %d -> %d chars (%.1f%% reduction)",
91
-
len(originalCID), len(base62Result),
92
-
float64(len(originalCID)-len(base62Result))/float64(len(originalCID))*100)
88
+
t.Logf("Original CID: %s", originalCID)
89
+
t.Logf("Base62: %s", base62Result)
90
+
t.Logf("Length reduction: %d -> %d chars (%.1f%% reduction)",
91
+
len(originalCID), len(base62Result),
92
+
float64(len(originalCID)-len(base62Result))/float64(len(originalCID))*100)
93
93
94
-
// Convert back to base32
95
-
base32Result, err := ConvertCIDBase62ToBase32(base62Result)
96
-
if err != nil {
97
-
t.Fatalf("Failed to convert back to base32: %v", err)
98
-
}
94
+
// Convert back to base32
95
+
base32Result, err := ConvertCIDBase62ToBase32(base62Result)
96
+
if err != nil {
97
+
t.Fatalf("Failed to convert back to base32: %v", err)
98
+
}
99
99
100
-
t.Logf("Restored: %s", base32Result)
100
+
t.Logf("Restored: %s", base32Result)
101
101
102
-
// Compare (case insensitive since base32 can be uppercase/lowercase)
103
-
if !strings.EqualFold(originalCID, base32Result) {
104
-
t.Errorf("Round trip failed:\nOriginal: %s\nBase62: %s\nRestored: %s",
105
-
originalCID, base62Result, base32Result)
106
-
}
107
-
})
108
-
}
102
+
// Compare (case insensitive since base32 can be uppercase/lowercase)
103
+
if !strings.EqualFold(originalCID, base32Result) {
104
+
t.Errorf("Round trip failed:\nOriginal: %s\nBase62: %s\nRestored: %s",
105
+
originalCID, base62Result, base32Result)
106
+
}
107
+
})
108
+
}
109
109
}
110
110
111
111
func TestIsBase32WithRealCIDs(t *testing.T) {
112
-
tests := []struct {
113
-
name string
114
-
input string
115
-
expected bool
116
-
}{
117
-
{
118
-
name: "real CID 1",
119
-
input: "bafkreigns2g4c46vrdvj6wlv7jka2binxftkadssvv5mxakqz4vulbfroi",
120
-
expected: true,
121
-
},
122
-
{
123
-
name: "real CID 2",
124
-
input: "bafkreigms7evfvvxtsb2azgx64wfqv3xt62elwwt5zjtv2dcgd4idu3erm",
125
-
expected: true,
126
-
},
127
-
{
128
-
name: "real CID 3",
129
-
input: "bafkreieedz3pv6onkm5ombpwbx43ytwzff3qgzing5ym45xthlnvku2wha",
130
-
expected: true,
131
-
},
132
-
{
133
-
name: "real CID uppercase",
134
-
input: strings.ToUpper("bafkreigns2g4c46vrdvj6wlv7jka2binxftkadssvv5mxakqz4vulbfroi"),
135
-
expected: true,
136
-
},
137
-
{
138
-
name: "empty string",
139
-
input: "",
140
-
expected: false,
141
-
},
142
-
{
143
-
name: "invalid characters",
144
-
input: "bafkrei123invalid!@#",
145
-
expected: false,
146
-
},
147
-
{
148
-
name: "contains 0 and 1 (invalid in base32)",
149
-
input: "bafkrei01234567890",
150
-
expected: false,
151
-
},
152
-
{
153
-
name: "contains 8 and 9 (invalid in base32)",
154
-
input: "bafkrei89abcdef",
155
-
expected: false,
156
-
},
157
-
}
112
+
tests := []struct {
113
+
name string
114
+
input string
115
+
expected bool
116
+
}{
117
+
{
118
+
name: "real CID 1",
119
+
input: "bafkreigns2g4c46vrdvj6wlv7jka2binxftkadssvv5mxakqz4vulbfroi",
120
+
expected: true,
121
+
},
122
+
{
123
+
name: "real CID 2",
124
+
input: "bafkreigms7evfvvxtsb2azgx64wfqv3xt62elwwt5zjtv2dcgd4idu3erm",
125
+
expected: true,
126
+
},
127
+
{
128
+
name: "real CID 3",
129
+
input: "bafkreieedz3pv6onkm5ombpwbx43ytwzff3qgzing5ym45xthlnvku2wha",
130
+
expected: true,
131
+
},
132
+
{
133
+
name: "real CID uppercase",
134
+
input: strings.ToUpper("bafkreigns2g4c46vrdvj6wlv7jka2binxftkadssvv5mxakqz4vulbfroi"),
135
+
expected: true,
136
+
},
137
+
{
138
+
name: "empty string",
139
+
input: "",
140
+
expected: false,
141
+
},
142
+
{
143
+
name: "invalid characters",
144
+
input: "bafkrei123invalid!@#",
145
+
expected: false,
146
+
},
147
+
{
148
+
name: "contains 0 and 1 (invalid in base32)",
149
+
input: "bafkrei01234567890",
150
+
expected: false,
151
+
},
152
+
{
153
+
name: "contains 8 and 9 (invalid in base32)",
154
+
input: "bafkrei89abcdef",
155
+
expected: false,
156
+
},
157
+
}
158
158
159
-
for _, tt := range tests {
160
-
t.Run(tt.name, func(t *testing.T) {
161
-
result := IsBase32(tt.input)
162
-
if result != tt.expected {
163
-
t.Errorf("IsBase32(%q) = %v, expected %v", tt.input, result, tt.expected)
164
-
}
165
-
})
166
-
}
159
+
for _, tt := range tests {
160
+
t.Run(tt.name, func(t *testing.T) {
161
+
result := IsBase32(tt.input)
162
+
if result != tt.expected {
163
+
t.Errorf("IsBase32(%q) = %v, expected %v", tt.input, result, tt.expected)
164
+
}
165
+
})
166
+
}
167
167
}
168
168
169
169
func TestCompressionRatio(t *testing.T) {
170
-
t.Log("Testing compression ratios with real CIDs:")
170
+
t.Log("Testing compression ratios with real CIDs:")
171
171
172
-
var totalOriginalLength, totalBase62Length int
172
+
var totalOriginalLength, totalBase62Length int
173
173
174
-
for i, cid := range validCIDs {
175
-
base62, err := ConvertCIDBase32ToBase62(cid)
176
-
if err != nil {
177
-
t.Fatalf("Failed to convert CID %d: %v", i+1, err)
178
-
}
174
+
for i, cid := range validCIDs {
175
+
base62, err := ConvertCIDBase32ToBase62(cid)
176
+
if err != nil {
177
+
t.Fatalf("Failed to convert CID %d: %v", i+1, err)
178
+
}
179
179
180
-
originalLen := len(cid)
181
-
base62Len := len(base62)
182
-
reduction := float64(originalLen-base62Len) / float64(originalLen) * 100
180
+
originalLen := len(cid)
181
+
base62Len := len(base62)
182
+
reduction := float64(originalLen-base62Len) / float64(originalLen) * 100
183
183
184
-
totalOriginalLength += originalLen
185
-
totalBase62Length += base62Len
184
+
totalOriginalLength += originalLen
185
+
totalBase62Length += base62Len
186
186
187
-
t.Logf("CID %d: %d -> %d chars (%.1f%% reduction)",
188
-
i+1, originalLen, base62Len, reduction)
189
-
}
187
+
t.Logf("CID %d: %d -> %d chars (%.1f%% reduction)",
188
+
i+1, originalLen, base62Len, reduction)
189
+
}
190
190
191
-
overallReduction := float64(totalOriginalLength-totalBase62Length) / float64(totalOriginalLength) * 100
192
-
t.Logf("Overall: %d -> %d chars (%.1f%% reduction)",
193
-
totalOriginalLength, totalBase62Length, overallReduction)
191
+
overallReduction := float64(totalOriginalLength-totalBase62Length) / float64(totalOriginalLength) * 100
192
+
t.Logf("Overall: %d -> %d chars (%.1f%% reduction)",
193
+
totalOriginalLength, totalBase62Length, overallReduction)
194
194
}
195
195
196
196
func TestSpecificCIDConversions(t *testing.T) {
197
-
// Test each CID individually with detailed logging
198
-
testCases := []struct {
199
-
name string
200
-
cid string
201
-
}{
202
-
{"CID with 'igns2g4c'", "bafkreigns2g4c46vrdvj6wlv7jka2binxftkadssvv5mxakqz4vulbfroi"},
203
-
{"CID with 'igms7evf'", "bafkreigms7evfvvxtsb2azgx64wfqv3xt62elwwt5zjtv2dcgd4idu3erm"},
204
-
{"CID with 'ieedz3pv'", "bafkreieedz3pv6onkm5ombpwbx43ytwzff3qgzing5ym45xthlnvku2wha"},
205
-
}
197
+
// Test each CID individually with detailed logging
198
+
testCases := []struct {
199
+
name string
200
+
cid string
201
+
}{
202
+
{"CID with 'igns2g4c'", "bafkreigns2g4c46vrdvj6wlv7jka2binxftkadssvv5mxakqz4vulbfroi"},
203
+
{"CID with 'igms7evf'", "bafkreigms7evfvvxtsb2azgx64wfqv3xt62elwwt5zjtv2dcgd4idu3erm"},
204
+
{"CID with 'ieedz3pv'", "bafkreieedz3pv6onkm5ombpwbx43ytwzff3qgzing5ym45xthlnvku2wha"},
205
+
}
206
206
207
-
for _, tc := range testCases {
208
-
t.Run(tc.name, func(t *testing.T) {
209
-
// Test IsBase32
210
-
if !IsBase32(tc.cid) {
211
-
t.Errorf("IsBase32 failed for %s", tc.cid)
212
-
}
207
+
for _, tc := range testCases {
208
+
t.Run(tc.name, func(t *testing.T) {
209
+
// Test IsBase32
210
+
if !IsBase32(tc.cid) {
211
+
t.Errorf("IsBase32 failed for %s", tc.cid)
212
+
}
213
213
214
-
// Test conversion to base62
215
-
base62, err := ConvertCIDBase32ToBase62(tc.cid)
216
-
if err != nil {
217
-
t.Fatalf("ConvertCIDBase32ToBase62 failed: %v", err)
218
-
}
214
+
// Test conversion to base62
215
+
base62, err := ConvertCIDBase32ToBase62(tc.cid)
216
+
if err != nil {
217
+
t.Fatalf("ConvertCIDBase32ToBase62 failed: %v", err)
218
+
}
219
219
220
-
// Test conversion back to base32
221
-
restored, err := ConvertCIDBase62ToBase32(base62)
222
-
if err != nil {
223
-
t.Fatalf("ConvertCIDBase62ToBase32 failed: %v", err)
224
-
}
220
+
// Test conversion back to base32
221
+
restored, err := ConvertCIDBase62ToBase32(base62)
222
+
if err != nil {
223
+
t.Fatalf("ConvertCIDBase62ToBase32 failed: %v", err)
224
+
}
225
225
226
-
// Verify round trip
227
-
if !strings.EqualFold(tc.cid, restored) {
228
-
t.Errorf("Round trip failed for %s", tc.cid)
229
-
t.Errorf(" Original: %s", tc.cid)
230
-
t.Errorf(" Base62: %s", base62)
231
-
t.Errorf(" Restored: %s", restored)
232
-
} else {
233
-
t.Logf("✓ Round trip successful")
234
-
t.Logf(" Original: %s", tc.cid)
235
-
t.Logf(" Base62: %s", base62)
236
-
t.Logf(" Restored: %s", restored)
237
-
}
238
-
})
239
-
}
226
+
// Verify round trip
227
+
if !strings.EqualFold(tc.cid, restored) {
228
+
t.Errorf("Round trip failed for %s", tc.cid)
229
+
t.Errorf(" Original: %s", tc.cid)
230
+
t.Errorf(" Base62: %s", base62)
231
+
t.Errorf(" Restored: %s", restored)
232
+
} else {
233
+
t.Logf("✓ Round trip successful")
234
+
t.Logf(" Original: %s", tc.cid)
235
+
t.Logf(" Base62: %s", base62)
236
+
t.Logf(" Restored: %s", restored)
237
+
}
238
+
})
239
+
}
240
240
}
241
241
242
242
// Benchmark with real CIDs
243
243
func BenchmarkConvertRealCIDBase32ToBase62(b *testing.B) {
244
-
cid := validCIDs[0] // Use first real CID
244
+
cid := validCIDs[0] // Use first real CID
245
245
246
-
b.ResetTimer()
247
-
for i := 0; i < b.N; i++ {
248
-
_, err := ConvertCIDBase32ToBase62(cid)
249
-
if err != nil {
250
-
b.Fatal(err)
251
-
}
252
-
}
246
+
b.ResetTimer()
247
+
for i := 0; i < b.N; i++ {
248
+
_, err := ConvertCIDBase32ToBase62(cid)
249
+
if err != nil {
250
+
b.Fatal(err)
251
+
}
252
+
}
253
253
}
254
254
255
255
func BenchmarkConvertRealCIDBase62ToBase32(b *testing.B) {
256
-
// Convert real CID to base62 first
257
-
base62CID, err := ConvertCIDBase32ToBase62(validCIDs[0])
258
-
if err != nil {
259
-
b.Fatal(err)
260
-
}
256
+
// Convert real CID to base62 first
257
+
base62CID, err := ConvertCIDBase32ToBase62(validCIDs[0])
258
+
if err != nil {
259
+
b.Fatal(err)
260
+
}
261
261
262
-
b.ResetTimer()
263
-
for i := 0; i < b.N; i++ {
264
-
_, err := ConvertCIDBase62ToBase32(base62CID)
265
-
if err != nil {
266
-
b.Fatal(err)
267
-
}
268
-
}
262
+
b.ResetTimer()
263
+
for i := 0; i < b.N; i++ {
264
+
_, err := ConvertCIDBase62ToBase32(base62CID)
265
+
if err != nil {
266
+
b.Fatal(err)
267
+
}
268
+
}
269
269
}
270
270
271
271
func BenchmarkIsBase32RealCID(b *testing.B) {
272
-
cid := validCIDs[0]
272
+
cid := validCIDs[0]
273
273
274
-
b.ResetTimer()
275
-
for i := 0; i < b.N; i++ {
276
-
IsBase32(cid)
277
-
}
274
+
b.ResetTimer()
275
+
for i := 0; i < b.N; i++ {
276
+
IsBase32(cid)
277
+
}
278
278
}