From a2b924d7e9492b978ad6dc33b6c1ffcb304b4bc5 Mon Sep 17 00:00:00 2001 From: Nippy Date: Sat, 9 May 2026 13:33:09 +0200 Subject: raveos update --- .../DankMaterialShell/core/pkg/dbusutil/variant.go | 95 - .../core/pkg/dbusutil/variant_test.go | 155 - .../DankMaterialShell/core/pkg/go-wayland/AUTHORS | 3 - .../DankMaterialShell/core/pkg/go-wayland/LICENSE | 24 - .../core/pkg/go-wayland/README.md | 25 - .../DankMaterialShell/core/pkg/go-wayland/generate | 4 - .../core/pkg/go-wayland/generatep | 9 - .../core/pkg/go-wayland/wayland/client/client.go | 7542 -------------------- .../core/pkg/go-wayland/wayland/client/common.go | 55 - .../core/pkg/go-wayland/wayland/client/context.go | 143 - .../pkg/go-wayland/wayland/client/context_test.go | 111 - .../core/pkg/go-wayland/wayland/client/display.go | 37 - .../core/pkg/go-wayland/wayland/client/doc.go | 6 - .../core/pkg/go-wayland/wayland/client/event.go | 120 - .../core/pkg/go-wayland/wayland/client/request.go | 44 - .../core/pkg/go-wayland/wayland/client/util.go | 24 - .../wayland/stable/xdg-shell/xdg_shell.go | 13 - .../DankMaterialShell/core/pkg/ipp/CREDITS.MD | 5 - .../DankMaterialShell/core/pkg/ipp/LICENSE | 201 - .../DankMaterialShell/core/pkg/ipp/adapter-http.go | 132 - .../DankMaterialShell/core/pkg/ipp/adapter.go | 9 - .../DankMaterialShell/core/pkg/ipp/attribute.go | 528 -- .../DankMaterialShell/core/pkg/ipp/constants.go | 450 -- .../DankMaterialShell/core/pkg/ipp/cups-client.go | 313 - .../DankMaterialShell/core/pkg/ipp/error.go | 31 - .../DankMaterialShell/core/pkg/ipp/ipp-client.go | 329 - .../DankMaterialShell/core/pkg/ipp/request.go | 299 - .../DankMaterialShell/core/pkg/ipp/response.go | 383 - .../DankMaterialShell/core/pkg/ipp/utils.go | 28 - .../DankMaterialShell/core/pkg/syncmap/LICENSE | 28 - .../DankMaterialShell/core/pkg/syncmap/syncmap.go | 537 -- 31 files changed, 11683 deletions(-) delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/dbusutil/variant.go delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/dbusutil/variant_test.go delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/AUTHORS delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/LICENSE delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/README.md delete mode 100755 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/generate delete mode 100755 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/generatep delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/client.go delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/common.go delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/context.go delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/context_test.go delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/display.go delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/doc.go delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/event.go delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/request.go delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/util.go delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/stable/xdg-shell/xdg_shell.go delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/CREDITS.MD delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/LICENSE delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/adapter-http.go delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/adapter.go delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/attribute.go delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/constants.go delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/cups-client.go delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/error.go delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/ipp-client.go delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/request.go delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/response.go delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/utils.go delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/syncmap/LICENSE delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/syncmap/syncmap.go (limited to 'raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg') diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/dbusutil/variant.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/dbusutil/variant.go deleted file mode 100644 index 4080b66..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/dbusutil/variant.go +++ /dev/null @@ -1,95 +0,0 @@ -package dbusutil - -import "github.com/godbus/dbus/v5" - -func As[T any](v dbus.Variant) (T, bool) { - val, ok := v.Value().(T) - return val, ok -} - -func AsOr[T any](v dbus.Variant, def T) T { - if val, ok := v.Value().(T); ok { - return val - } - return def -} - -func Get[T any](m map[string]dbus.Variant, key string) (T, bool) { - v, ok := m[key] - if !ok { - var zero T - return zero, false - } - return As[T](v) -} - -func GetOr[T any](m map[string]dbus.Variant, key string, def T) T { - v, ok := m[key] - if !ok { - return def - } - return AsOr(v, def) -} - -func Normalize(v any) any { - switch val := v.(type) { - case dbus.Variant: - return Normalize(val.Value()) - case dbus.ObjectPath: - return string(val) - case []dbus.ObjectPath: - result := make([]string, len(val)) - for i, p := range val { - result[i] = string(p) - } - return result - case map[string]dbus.Variant: - result := make(map[string]any) - for k, vv := range val { - result[k] = Normalize(vv.Value()) - } - return result - case map[string]any: - result := make(map[string]any) - for k, vv := range val { - result[k] = Normalize(vv) - } - return result - case map[dbus.ObjectPath]map[string]map[string]dbus.Variant: - result := make(map[string]any) - for path, ifaces := range val { - ifaceMap := make(map[string]any) - for ifaceName, props := range ifaces { - propMap := make(map[string]any) - for propName, propVal := range props { - propMap[propName] = Normalize(propVal.Value()) - } - ifaceMap[ifaceName] = propMap - } - result[string(path)] = ifaceMap - } - return result - case []any: - result := make([]any, len(val)) - for i, item := range val { - result[i] = Normalize(item) - } - return result - case []dbus.Variant: - result := make([]any, len(val)) - for i, item := range val { - result[i] = Normalize(item.Value()) - } - return result - default: - return v - } -} - -func NormalizeSlice(values []any) []any { - result := make([]any, len(values)) - for i, v := range values { - result[i] = Normalize(v) - } - return result -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/dbusutil/variant_test.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/dbusutil/variant_test.go deleted file mode 100644 index a927e54..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/dbusutil/variant_test.go +++ /dev/null @@ -1,155 +0,0 @@ -package dbusutil - -import ( - "testing" - - "github.com/godbus/dbus/v5" - "github.com/stretchr/testify/assert" -) - -func TestAs(t *testing.T) { - t.Run("string", func(t *testing.T) { - v := dbus.MakeVariant("hello") - val, ok := As[string](v) - assert.True(t, ok) - assert.Equal(t, "hello", val) - }) - - t.Run("bool", func(t *testing.T) { - v := dbus.MakeVariant(true) - val, ok := As[bool](v) - assert.True(t, ok) - assert.True(t, val) - }) - - t.Run("int32", func(t *testing.T) { - v := dbus.MakeVariant(int32(42)) - val, ok := As[int32](v) - assert.True(t, ok) - assert.Equal(t, int32(42), val) - }) - - t.Run("wrong type", func(t *testing.T) { - v := dbus.MakeVariant("hello") - _, ok := As[int](v) - assert.False(t, ok) - }) -} - -func TestAsOr(t *testing.T) { - t.Run("exists", func(t *testing.T) { - v := dbus.MakeVariant("hello") - val := AsOr(v, "default") - assert.Equal(t, "hello", val) - }) - - t.Run("wrong type uses default", func(t *testing.T) { - v := dbus.MakeVariant(123) - val := AsOr(v, "default") - assert.Equal(t, "default", val) - }) -} - -func TestGet(t *testing.T) { - m := map[string]dbus.Variant{ - "name": dbus.MakeVariant("test"), - "enabled": dbus.MakeVariant(true), - "count": dbus.MakeVariant(int32(5)), - } - - t.Run("exists", func(t *testing.T) { - val, ok := Get[string](m, "name") - assert.True(t, ok) - assert.Equal(t, "test", val) - }) - - t.Run("missing key", func(t *testing.T) { - _, ok := Get[string](m, "missing") - assert.False(t, ok) - }) - - t.Run("wrong type", func(t *testing.T) { - _, ok := Get[int](m, "name") - assert.False(t, ok) - }) -} - -func TestGetOr(t *testing.T) { - m := map[string]dbus.Variant{ - "name": dbus.MakeVariant("test"), - } - - t.Run("exists", func(t *testing.T) { - val := GetOr(m, "name", "default") - assert.Equal(t, "test", val) - }) - - t.Run("missing uses default", func(t *testing.T) { - val := GetOr(m, "missing", "default") - assert.Equal(t, "default", val) - }) - - t.Run("wrong type uses default", func(t *testing.T) { - val := GetOr(m, "name", 42) - assert.Equal(t, 42, val) - }) -} - -func TestNormalize(t *testing.T) { - t.Run("variant unwrap", func(t *testing.T) { - v := dbus.MakeVariant("hello") - result := Normalize(v) - assert.Equal(t, "hello", result) - }) - - t.Run("nested variant", func(t *testing.T) { - v := dbus.MakeVariant(dbus.MakeVariant("nested")) - result := Normalize(v) - assert.Equal(t, "nested", result) - }) - - t.Run("object path", func(t *testing.T) { - v := dbus.ObjectPath("/org/test") - result := Normalize(v) - assert.Equal(t, "/org/test", result) - }) - - t.Run("object path slice", func(t *testing.T) { - v := []dbus.ObjectPath{"/org/a", "/org/b"} - result := Normalize(v) - assert.Equal(t, []string{"/org/a", "/org/b"}, result) - }) - - t.Run("variant map", func(t *testing.T) { - v := map[string]dbus.Variant{ - "key": dbus.MakeVariant("value"), - } - result := Normalize(v) - expected := map[string]any{"key": "value"} - assert.Equal(t, expected, result) - }) - - t.Run("any slice", func(t *testing.T) { - v := []any{dbus.MakeVariant("a"), dbus.ObjectPath("/b")} - result := Normalize(v) - expected := []any{"a", "/b"} - assert.Equal(t, expected, result) - }) - - t.Run("passthrough primitives", func(t *testing.T) { - assert.Equal(t, "hello", Normalize("hello")) - assert.Equal(t, 42, Normalize(42)) - assert.Equal(t, true, Normalize(true)) - }) -} - -func TestNormalizeSlice(t *testing.T) { - input := []any{ - dbus.MakeVariant("a"), - dbus.ObjectPath("/b"), - "c", - } - result := NormalizeSlice(input) - expected := []any{"a", "/b", "c"} - assert.Equal(t, expected, result) -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/AUTHORS b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/AUTHORS deleted file mode 100644 index 7b24eab..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -// Keep this sorted - -rajveermalviya diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/LICENSE b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/LICENSE deleted file mode 100644 index 4da3300..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -Copyright 2021 go-wayland authors - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/README.md b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/README.md deleted file mode 100644 index 9e52d99..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Wayland implementation in Go - -[![Go Reference](https://pkg.go.dev/badge/github.com/AvengeMedia/DankMaterialShell/core/pkg/go-wayland/wayland.svg)](https://pkg.go.dev/github.com/AvengeMedia/DankMaterialShell/core/pkg/go-wayland/wayland) - -This module contains pure Go implementation of the Wayland protocol. -Currently only wayland-client functionality is supported. - -Go code is generated from protocol XML files using -[`go-wayland-scanner`](cmd/go-wayland-scanner/scanner.go). - -To load cursor, minimal port of `wayland-cursor` & `xcursor` in pure Go -is located at [`wayland/cursor`](wayland/cursor) & [`wayland/cursor/xcursor`](wayland/cursor/xcursor) -respectively. - -To demonstrate the functionality of this module -[`examples/imageviewer`](examples/imageviewer) contains a simple image -viewer. It demos displaying a top-level window, resizing of window, -cursor themes, pointer and keyboard. Because it's in pure Go, it can be -compiled without CGO. You can try it using the following commands: - -```sh -CGO_ENABLED=0 go install github.com/AvengeMedia/DankMaterialShell/core/pkg/go-wayland/examples/imageviewer@latest - -imageviewer file.jpg -``` diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/generate b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/generate deleted file mode 100755 index 02ad975..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/generate +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -cd ./wayland -go generate -x ./... diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/generatep b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/generatep deleted file mode 100755 index bd660d7..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/generatep +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env sh - -# Runs go generate for each directory, but in parallel. Any arguments are appended to the -# go generate command. -# Usage: $ ./generatep [go generate arguments] -# Print all generate commands: $ ./generatep -x - -cd ./wayland || exit 1 -find . -type f -name '*.go' -exec dirname {} \; | sort -u | parallel -j 0 go generate "$1" {}/. diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/client.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/client.go deleted file mode 100644 index fd49c20..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/client.go +++ /dev/null @@ -1,7542 +0,0 @@ -// Generated by go-wayland-scanner -// https://github.com/yaslama/go-wayland/cmd/go-wayland-scanner -// XML file : https://gitlab.freedesktop.org/wayland/wayland/-/raw/1.24.0/protocol/wayland.xml?ref_type=tags -// -// wayland Protocol Copyright: -// -// Copyright © 2008-2011 Kristian Høgsberg -// Copyright © 2010-2011 Intel Corporation -// Copyright © 2012-2013 Collabora, Ltd. -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation files -// (the "Software"), to deal in the Software without restriction, -// including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, -// and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice (including the -// next paragraph) shall be included in all copies or substantial -// portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -package client - -import "golang.org/x/sys/unix" - -// DisplayInterfaceName is the name of the interface as it appears in the [client.Registry]. -// It can be used to match the [client.RegistryGlobalEvent.Interface] in the -// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies. -const DisplayInterfaceName = "wl_display" - -// Display : core global object -// -// The core global object. This is a special singleton object. It -// is used for internal Wayland protocol features. -type Display struct { - BaseProxy - errorHandler DisplayErrorHandlerFunc - deleteIdHandler DisplayDeleteIdHandlerFunc -} - -// NewDisplay : core global object -// -// The core global object. This is a special singleton object. It -// is used for internal Wayland protocol features. -func NewDisplay(ctx *Context) *Display { - wlDisplay := &Display{} - ctx.Register(wlDisplay) - return wlDisplay -} - -// Sync : asynchronous roundtrip -// -// The sync request asks the server to emit the 'done' event -// on the returned wl_callback object. Since requests are -// handled in-order and events are delivered in-order, this can -// be used as a barrier to ensure all previous requests and the -// resulting events have been handled. -// -// The object returned by this request will be destroyed by the -// compositor after the callback is fired and as such the client must not -// attempt to use it after that point. -// -// The callback_data passed in the callback is undefined and should be ignored. -func (i *Display) Sync() (*Callback, error) { - callback := NewCallback(i.Context()) - const opcode = 0 - const _reqBufLen = 8 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], callback.ID()) - err := i.Context().WriteMsg(_reqBuf[:], nil) - return callback, err -} - -// GetRegistry : get global registry object -// -// This request creates a registry object that allows the client -// to list and bind the global objects available from the -// compositor. -// -// It should be noted that the server side resources consumed in -// response to a get_registry request can only be released when the -// client disconnects, not when the client side proxy is destroyed. -// Therefore, clients should invoke get_registry as infrequently as -// possible to avoid wasting memory. -func (i *Display) GetRegistry() (*Registry, error) { - registry := NewRegistry(i.Context()) - const opcode = 1 - const _reqBufLen = 8 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], registry.ID()) - err := i.Context().WriteMsg(_reqBuf[:], nil) - return registry, err -} - -func (i *Display) Destroy() error { - i.MarkZombie() - return nil -} - -type DisplayError uint32 - -// DisplayError : global error values -// -// These errors are global and can be emitted in response to any -// server request. -const ( - // DisplayErrorInvalidObject : server couldn't find object - DisplayErrorInvalidObject DisplayError = 0 - // DisplayErrorInvalidMethod : method doesn't exist on the specified interface or malformed request - DisplayErrorInvalidMethod DisplayError = 1 - // DisplayErrorNoMemory : server is out of memory - DisplayErrorNoMemory DisplayError = 2 - // DisplayErrorImplementation : implementation error in compositor - DisplayErrorImplementation DisplayError = 3 -) - -func (e DisplayError) Name() string { - switch e { - case DisplayErrorInvalidObject: - return "invalid_object" - case DisplayErrorInvalidMethod: - return "invalid_method" - case DisplayErrorNoMemory: - return "no_memory" - case DisplayErrorImplementation: - return "implementation" - default: - return "" - } -} - -func (e DisplayError) Value() string { - switch e { - case DisplayErrorInvalidObject: - return "0" - case DisplayErrorInvalidMethod: - return "1" - case DisplayErrorNoMemory: - return "2" - case DisplayErrorImplementation: - return "3" - default: - return "" - } -} - -func (e DisplayError) String() string { - return e.Name() + "=" + e.Value() -} - -// DisplayErrorEvent : fatal error event -// -// The error event is sent out when a fatal (non-recoverable) -// error has occurred. The object_id argument is the object -// where the error occurred, most often in response to a request -// to that object. The code identifies the error and is defined -// by the object interface. As such, each interface defines its -// own set of error codes. The message is a brief description -// of the error, for (debugging) convenience. -type DisplayErrorEvent struct { - ObjectId Proxy - Code uint32 - Message string -} -type DisplayErrorHandlerFunc func(DisplayErrorEvent) - -// SetErrorHandler : sets handler for DisplayErrorEvent -func (i *Display) SetErrorHandler(f DisplayErrorHandlerFunc) { - i.errorHandler = f -} - -// DisplayDeleteIdEvent : acknowledge object ID deletion -// -// This event is used internally by the object ID management -// logic. When a client deletes an object that it had created, -// the server will send this event to acknowledge that it has -// seen the delete request. When the client receives this event, -// it will know that it can safely reuse the object ID. -type DisplayDeleteIdEvent struct { - Id uint32 -} -type DisplayDeleteIdHandlerFunc func(DisplayDeleteIdEvent) - -// SetDeleteIdHandler : sets handler for DisplayDeleteIdEvent -func (i *Display) SetDeleteIdHandler(f DisplayDeleteIdHandlerFunc) { - i.deleteIdHandler = f -} - -func (i *Display) Dispatch(opcode uint32, fd int, data []byte) { - switch opcode { - case 0: - if i.errorHandler == nil { - return - } - var e DisplayErrorEvent - l := 0 - e.ObjectId = i.Context().GetProxy(Uint32(data[l : l+4])) - l += 4 - e.Code = Uint32(data[l : l+4]) - l += 4 - messageLen := PaddedLen(int(Uint32(data[l : l+4]))) - l += 4 - e.Message = String(data[l : l+messageLen]) - - i.errorHandler(e) - case 1: - var e DisplayDeleteIdEvent - l := 0 - e.Id = Uint32(data[l : l+4]) - l += 4 - - i.Context().DeleteID(e.Id) - - if i.deleteIdHandler != nil { - i.deleteIdHandler(e) - } - } -} - -// RegistryInterfaceName is the name of the interface as it appears in the [client.Registry]. -// It can be used to match the [client.RegistryGlobalEvent.Interface] in the -// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies. -const RegistryInterfaceName = "wl_registry" - -// Registry : global registry object -// -// The singleton global registry object. The server has a number of -// global objects that are available to all clients. These objects -// typically represent an actual object in the server (for example, -// an input device) or they are singleton objects that provide -// extension functionality. -// -// When a client creates a registry object, the registry object -// will emit a global event for each global currently in the -// registry. Globals come and go as a result of device or -// monitor hotplugs, reconfiguration or other events, and the -// registry will send out global and global_remove events to -// keep the client up to date with the changes. To mark the end -// of the initial burst of events, the client can use the -// wl_display.sync request immediately after calling -// wl_display.get_registry. -// -// A client can bind to a global object by using the bind -// request. This creates a client-side handle that lets the object -// emit events to the client and lets the client invoke requests on -// the object. -type Registry struct { - BaseProxy - globalHandler RegistryGlobalHandlerFunc - globalRemoveHandler RegistryGlobalRemoveHandlerFunc -} - -// NewRegistry : global registry object -// -// The singleton global registry object. The server has a number of -// global objects that are available to all clients. These objects -// typically represent an actual object in the server (for example, -// an input device) or they are singleton objects that provide -// extension functionality. -// -// When a client creates a registry object, the registry object -// will emit a global event for each global currently in the -// registry. Globals come and go as a result of device or -// monitor hotplugs, reconfiguration or other events, and the -// registry will send out global and global_remove events to -// keep the client up to date with the changes. To mark the end -// of the initial burst of events, the client can use the -// wl_display.sync request immediately after calling -// wl_display.get_registry. -// -// A client can bind to a global object by using the bind -// request. This creates a client-side handle that lets the object -// emit events to the client and lets the client invoke requests on -// the object. -func NewRegistry(ctx *Context) *Registry { - wlRegistry := &Registry{} - ctx.Register(wlRegistry) - return wlRegistry -} - -// Bind : bind an object to the display -// -// Binds a new, client-created object to the server using the -// specified name as the identifier. -// -// name: unique numeric name of the object -func (i *Registry) Bind(name uint32, iface string, version uint32, id Proxy) error { - const opcode = 0 - ifaceLen := PaddedLen(len(iface) + 1) - _reqBufLen := 8 + 4 + (4 + ifaceLen) + 4 + 4 - _reqBuf := make([]byte, _reqBufLen) - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(name)) - l += 4 - PutString(_reqBuf[l:l+(4+ifaceLen)], iface) - l += (4 + ifaceLen) - PutUint32(_reqBuf[l:l+4], uint32(version)) - l += 4 - PutUint32(_reqBuf[l:l+4], id.ID()) - l += 4 - err := i.Context().WriteMsg(_reqBuf, nil) - return err -} - -func (i *Registry) Destroy() error { - i.MarkZombie() - return nil -} - -// RegistryGlobalEvent : announce global object -// -// Notify the client of global objects. -// -// The event notifies the client that a global object with -// the given name is now available, and it implements the -// given version of the given interface. -type RegistryGlobalEvent struct { - Name uint32 - Interface string - Version uint32 -} -type RegistryGlobalHandlerFunc func(RegistryGlobalEvent) - -// SetGlobalHandler : sets handler for RegistryGlobalEvent -func (i *Registry) SetGlobalHandler(f RegistryGlobalHandlerFunc) { - i.globalHandler = f -} - -// RegistryGlobalRemoveEvent : announce removal of global object -// -// Notify the client of removed global objects. -// -// This event notifies the client that the global identified -// by name is no longer available. If the client bound to -// the global using the bind request, the client should now -// destroy that object. -// -// The object remains valid and requests to the object will be -// ignored until the client destroys it, to avoid races between -// the global going away and a client sending a request to it. -type RegistryGlobalRemoveEvent struct { - Name uint32 -} -type RegistryGlobalRemoveHandlerFunc func(RegistryGlobalRemoveEvent) - -// SetGlobalRemoveHandler : sets handler for RegistryGlobalRemoveEvent -func (i *Registry) SetGlobalRemoveHandler(f RegistryGlobalRemoveHandlerFunc) { - i.globalRemoveHandler = f -} - -func (i *Registry) Dispatch(opcode uint32, fd int, data []byte) { - switch opcode { - case 0: - if i.globalHandler == nil { - return - } - var e RegistryGlobalEvent - l := 0 - e.Name = Uint32(data[l : l+4]) - l += 4 - interfaceLen := PaddedLen(int(Uint32(data[l : l+4]))) - l += 4 - e.Interface = String(data[l : l+interfaceLen]) - l += interfaceLen - e.Version = Uint32(data[l : l+4]) - l += 4 - - i.globalHandler(e) - case 1: - if i.globalRemoveHandler == nil { - return - } - var e RegistryGlobalRemoveEvent - l := 0 - e.Name = Uint32(data[l : l+4]) - l += 4 - - i.globalRemoveHandler(e) - } -} - -// CallbackInterfaceName is the name of the interface as it appears in the [client.Registry]. -// It can be used to match the [client.RegistryGlobalEvent.Interface] in the -// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies. -const CallbackInterfaceName = "wl_callback" - -// Callback : callback object -// -// Clients can handle the 'done' event to get notified when -// the related request is done. -// -// Note, because wl_callback objects are created from multiple independent -// factory interfaces, the wl_callback interface is frozen at version 1. -type Callback struct { - BaseProxy - doneHandler CallbackDoneHandlerFunc -} - -// NewCallback : callback object -// -// Clients can handle the 'done' event to get notified when -// the related request is done. -// -// Note, because wl_callback objects are created from multiple independent -// factory interfaces, the wl_callback interface is frozen at version 1. -func NewCallback(ctx *Context) *Callback { - wlCallback := &Callback{} - ctx.Register(wlCallback) - return wlCallback -} - -func (i *Callback) Destroy() error { - i.MarkZombie() - return nil -} - -// CallbackDoneEvent : done event -// -// Notify the client when the related request is done. -type CallbackDoneEvent struct { - CallbackData uint32 -} -type CallbackDoneHandlerFunc func(CallbackDoneEvent) - -// SetDoneHandler : sets handler for CallbackDoneEvent -func (i *Callback) SetDoneHandler(f CallbackDoneHandlerFunc) { - i.doneHandler = f -} - -func (i *Callback) Dispatch(opcode uint32, fd int, data []byte) { - switch opcode { - case 0: - if i.doneHandler == nil { - return - } - var e CallbackDoneEvent - l := 0 - e.CallbackData = Uint32(data[l : l+4]) - l += 4 - - i.doneHandler(e) - } -} - -// CompositorInterfaceName is the name of the interface as it appears in the [client.Registry]. -// It can be used to match the [client.RegistryGlobalEvent.Interface] in the -// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies. -const CompositorInterfaceName = "wl_compositor" - -// Compositor : the compositor singleton -// -// A compositor. This object is a singleton global. The -// compositor is in charge of combining the contents of multiple -// surfaces into one displayable output. -type Compositor struct { - BaseProxy -} - -// NewCompositor : the compositor singleton -// -// A compositor. This object is a singleton global. The -// compositor is in charge of combining the contents of multiple -// surfaces into one displayable output. -func NewCompositor(ctx *Context) *Compositor { - wlCompositor := &Compositor{} - ctx.Register(wlCompositor) - return wlCompositor -} - -// CreateSurface : create new surface -// -// Ask the compositor to create a new surface. -func (i *Compositor) CreateSurface() (*Surface, error) { - id := NewSurface(i.Context()) - const opcode = 0 - const _reqBufLen = 8 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], id.ID()) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return id, err -} - -// CreateRegion : create new region -// -// Ask the compositor to create a new region. -func (i *Compositor) CreateRegion() (*Region, error) { - id := NewRegion(i.Context()) - const opcode = 1 - const _reqBufLen = 8 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], id.ID()) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return id, err -} - -func (i *Compositor) Destroy() error { - i.MarkZombie() - return nil -} - -// ShmPoolInterfaceName is the name of the interface as it appears in the [client.Registry]. -// It can be used to match the [client.RegistryGlobalEvent.Interface] in the -// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies. -const ShmPoolInterfaceName = "wl_shm_pool" - -// ShmPool : a shared memory pool -// -// The wl_shm_pool object encapsulates a piece of memory shared -// between the compositor and client. Through the wl_shm_pool -// object, the client can allocate shared memory wl_buffer objects. -// All objects created through the same pool share the same -// underlying mapped memory. Reusing the mapped memory avoids the -// setup/teardown overhead and is useful when interactively resizing -// a surface or for many small buffers. -type ShmPool struct { - BaseProxy -} - -// NewShmPool : a shared memory pool -// -// The wl_shm_pool object encapsulates a piece of memory shared -// between the compositor and client. Through the wl_shm_pool -// object, the client can allocate shared memory wl_buffer objects. -// All objects created through the same pool share the same -// underlying mapped memory. Reusing the mapped memory avoids the -// setup/teardown overhead and is useful when interactively resizing -// a surface or for many small buffers. -func NewShmPool(ctx *Context) *ShmPool { - wlShmPool := &ShmPool{} - ctx.Register(wlShmPool) - return wlShmPool -} - -// CreateBuffer : create a buffer from the pool -// -// Create a wl_buffer object from the pool. -// -// The buffer is created offset bytes into the pool and has -// width and height as specified. The stride argument specifies -// the number of bytes from the beginning of one row to the beginning -// of the next. The format is the pixel format of the buffer and -// must be one of those advertised through the wl_shm.format event. -// -// A buffer will keep a reference to the pool it was created from -// so it is valid to destroy the pool immediately after creating -// a buffer from it. -// -// offset: buffer byte offset within the pool -// width: buffer width, in pixels -// height: buffer height, in pixels -// stride: number of bytes from the beginning of one row to the beginning of the next row -// format: buffer pixel format -func (i *ShmPool) CreateBuffer(offset, width, height, stride int32, format uint32) (*Buffer, error) { - id := NewBuffer(i.Context()) - const opcode = 0 - const _reqBufLen = 8 + 4 + 4 + 4 + 4 + 4 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], id.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(offset)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(width)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(height)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(stride)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(format)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return id, err -} - -// Destroy : destroy the pool -// -// Destroy the shared memory pool. -// -// The mmapped memory will be released when all -// buffers that have been created from this pool -// are gone. -func (i *ShmPool) Destroy() error { - defer i.MarkZombie() - const opcode = 1 - const _reqBufLen = 8 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// Resize : change the size of the pool mapping -// -// This request will cause the server to remap the backing memory -// for the pool from the file descriptor passed when the pool was -// created, but using the new size. This request can only be -// used to make the pool bigger. -// -// This request only changes the amount of bytes that are mmapped -// by the server and does not touch the file corresponding to the -// file descriptor passed at creation time. It is the client's -// responsibility to ensure that the file is at least as big as -// the new pool size. -// -// size: new size of the pool, in bytes -func (i *ShmPool) Resize(size int32) error { - const opcode = 2 - const _reqBufLen = 8 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(size)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// ShmInterfaceName is the name of the interface as it appears in the [client.Registry]. -// It can be used to match the [client.RegistryGlobalEvent.Interface] in the -// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies. -const ShmInterfaceName = "wl_shm" - -// Shm : shared memory support -// -// A singleton global object that provides support for shared -// memory. -// -// Clients can create wl_shm_pool objects using the create_pool -// request. -// -// On binding the wl_shm object one or more format events -// are emitted to inform clients about the valid pixel formats -// that can be used for buffers. -type Shm struct { - BaseProxy - formatHandler ShmFormatHandlerFunc -} - -// NewShm : shared memory support -// -// A singleton global object that provides support for shared -// memory. -// -// Clients can create wl_shm_pool objects using the create_pool -// request. -// -// On binding the wl_shm object one or more format events -// are emitted to inform clients about the valid pixel formats -// that can be used for buffers. -func NewShm(ctx *Context) *Shm { - wlShm := &Shm{} - ctx.Register(wlShm) - return wlShm -} - -// CreatePool : create a shm pool -// -// Create a new wl_shm_pool object. -// -// The pool can be used to create shared memory based buffer -// objects. The server will mmap size bytes of the passed file -// descriptor, to use as backing memory for the pool. -// -// fd: file descriptor for the pool -// size: pool size, in bytes -func (i *Shm) CreatePool(fd int, size int32) (*ShmPool, error) { - id := NewShmPool(i.Context()) - const opcode = 0 - const _reqBufLen = 8 + 4 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], id.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(size)) - l += 4 - oob := unix.UnixRights(int(fd)) - err := i.Context().WriteMsg(_reqBuf[:], oob) - return id, err -} - -// Release : release the shm object -// -// Using this request a client can tell the server that it is not going to -// use the shm object anymore. -// -// Objects created via this interface remain unaffected. -func (i *Shm) Release() error { - defer i.MarkZombie() - const opcode = 1 - const _reqBufLen = 8 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -type ShmError uint32 - -// ShmError : wl_shm error values -// -// These errors can be emitted in response to wl_shm requests. -const ( - // ShmErrorInvalidFormat : buffer format is not known - ShmErrorInvalidFormat ShmError = 0 - // ShmErrorInvalidStride : invalid size or stride during pool or buffer creation - ShmErrorInvalidStride ShmError = 1 - // ShmErrorInvalidFd : mmapping the file descriptor failed - ShmErrorInvalidFd ShmError = 2 -) - -func (e ShmError) Name() string { - switch e { - case ShmErrorInvalidFormat: - return "invalid_format" - case ShmErrorInvalidStride: - return "invalid_stride" - case ShmErrorInvalidFd: - return "invalid_fd" - default: - return "" - } -} - -func (e ShmError) Value() string { - switch e { - case ShmErrorInvalidFormat: - return "0" - case ShmErrorInvalidStride: - return "1" - case ShmErrorInvalidFd: - return "2" - default: - return "" - } -} - -func (e ShmError) String() string { - return e.Name() + "=" + e.Value() -} - -type ShmFormat uint32 - -// ShmFormat : pixel formats -// -// This describes the memory layout of an individual pixel. -// -// All renderers should support argb8888 and xrgb8888 but any other -// formats are optional and may not be supported by the particular -// renderer in use. -// -// The drm format codes match the macros defined in drm_fourcc.h, except -// argb8888 and xrgb8888. The formats actually supported by the compositor -// will be reported by the format event. -// -// For all wl_shm formats and unless specified in another protocol -// extension, pre-multiplied alpha is used for pixel values. -const ( - // ShmFormatArgb8888 : 32-bit ARGB format, [31:0] A:R:G:B 8:8:8:8 little endian - ShmFormatArgb8888 ShmFormat = 0 - // ShmFormatXrgb8888 : 32-bit RGB format, [31:0] x:R:G:B 8:8:8:8 little endian - ShmFormatXrgb8888 ShmFormat = 1 - // ShmFormatC8 : 8-bit color index format, [7:0] C - ShmFormatC8 ShmFormat = 0x20203843 - // ShmFormatRgb332 : 8-bit RGB format, [7:0] R:G:B 3:3:2 - ShmFormatRgb332 ShmFormat = 0x38424752 - // ShmFormatBgr233 : 8-bit BGR format, [7:0] B:G:R 2:3:3 - ShmFormatBgr233 ShmFormat = 0x38524742 - // ShmFormatXrgb4444 : 16-bit xRGB format, [15:0] x:R:G:B 4:4:4:4 little endian - ShmFormatXrgb4444 ShmFormat = 0x32315258 - // ShmFormatXbgr4444 : 16-bit xBGR format, [15:0] x:B:G:R 4:4:4:4 little endian - ShmFormatXbgr4444 ShmFormat = 0x32314258 - // ShmFormatRgbx4444 : 16-bit RGBx format, [15:0] R:G:B:x 4:4:4:4 little endian - ShmFormatRgbx4444 ShmFormat = 0x32315852 - // ShmFormatBgrx4444 : 16-bit BGRx format, [15:0] B:G:R:x 4:4:4:4 little endian - ShmFormatBgrx4444 ShmFormat = 0x32315842 - // ShmFormatArgb4444 : 16-bit ARGB format, [15:0] A:R:G:B 4:4:4:4 little endian - ShmFormatArgb4444 ShmFormat = 0x32315241 - // ShmFormatAbgr4444 : 16-bit ABGR format, [15:0] A:B:G:R 4:4:4:4 little endian - ShmFormatAbgr4444 ShmFormat = 0x32314241 - // ShmFormatRgba4444 : 16-bit RBGA format, [15:0] R:G:B:A 4:4:4:4 little endian - ShmFormatRgba4444 ShmFormat = 0x32314152 - // ShmFormatBgra4444 : 16-bit BGRA format, [15:0] B:G:R:A 4:4:4:4 little endian - ShmFormatBgra4444 ShmFormat = 0x32314142 - // ShmFormatXrgb1555 : 16-bit xRGB format, [15:0] x:R:G:B 1:5:5:5 little endian - ShmFormatXrgb1555 ShmFormat = 0x35315258 - // ShmFormatXbgr1555 : 16-bit xBGR 1555 format, [15:0] x:B:G:R 1:5:5:5 little endian - ShmFormatXbgr1555 ShmFormat = 0x35314258 - // ShmFormatRgbx5551 : 16-bit RGBx 5551 format, [15:0] R:G:B:x 5:5:5:1 little endian - ShmFormatRgbx5551 ShmFormat = 0x35315852 - // ShmFormatBgrx5551 : 16-bit BGRx 5551 format, [15:0] B:G:R:x 5:5:5:1 little endian - ShmFormatBgrx5551 ShmFormat = 0x35315842 - // ShmFormatArgb1555 : 16-bit ARGB 1555 format, [15:0] A:R:G:B 1:5:5:5 little endian - ShmFormatArgb1555 ShmFormat = 0x35315241 - // ShmFormatAbgr1555 : 16-bit ABGR 1555 format, [15:0] A:B:G:R 1:5:5:5 little endian - ShmFormatAbgr1555 ShmFormat = 0x35314241 - // ShmFormatRgba5551 : 16-bit RGBA 5551 format, [15:0] R:G:B:A 5:5:5:1 little endian - ShmFormatRgba5551 ShmFormat = 0x35314152 - // ShmFormatBgra5551 : 16-bit BGRA 5551 format, [15:0] B:G:R:A 5:5:5:1 little endian - ShmFormatBgra5551 ShmFormat = 0x35314142 - // ShmFormatRgb565 : 16-bit RGB 565 format, [15:0] R:G:B 5:6:5 little endian - ShmFormatRgb565 ShmFormat = 0x36314752 - // ShmFormatBgr565 : 16-bit BGR 565 format, [15:0] B:G:R 5:6:5 little endian - ShmFormatBgr565 ShmFormat = 0x36314742 - // ShmFormatRgb888 : 24-bit RGB format, [23:0] R:G:B little endian - ShmFormatRgb888 ShmFormat = 0x34324752 - // ShmFormatBgr888 : 24-bit BGR format, [23:0] B:G:R little endian - ShmFormatBgr888 ShmFormat = 0x34324742 - // ShmFormatXbgr8888 : 32-bit xBGR format, [31:0] x:B:G:R 8:8:8:8 little endian - ShmFormatXbgr8888 ShmFormat = 0x34324258 - // ShmFormatRgbx8888 : 32-bit RGBx format, [31:0] R:G:B:x 8:8:8:8 little endian - ShmFormatRgbx8888 ShmFormat = 0x34325852 - // ShmFormatBgrx8888 : 32-bit BGRx format, [31:0] B:G:R:x 8:8:8:8 little endian - ShmFormatBgrx8888 ShmFormat = 0x34325842 - // ShmFormatAbgr8888 : 32-bit ABGR format, [31:0] A:B:G:R 8:8:8:8 little endian - ShmFormatAbgr8888 ShmFormat = 0x34324241 - // ShmFormatRgba8888 : 32-bit RGBA format, [31:0] R:G:B:A 8:8:8:8 little endian - ShmFormatRgba8888 ShmFormat = 0x34324152 - // ShmFormatBgra8888 : 32-bit BGRA format, [31:0] B:G:R:A 8:8:8:8 little endian - ShmFormatBgra8888 ShmFormat = 0x34324142 - // ShmFormatXrgb2101010 : 32-bit xRGB format, [31:0] x:R:G:B 2:10:10:10 little endian - ShmFormatXrgb2101010 ShmFormat = 0x30335258 - // ShmFormatXbgr2101010 : 32-bit xBGR format, [31:0] x:B:G:R 2:10:10:10 little endian - ShmFormatXbgr2101010 ShmFormat = 0x30334258 - // ShmFormatRgbx1010102 : 32-bit RGBx format, [31:0] R:G:B:x 10:10:10:2 little endian - ShmFormatRgbx1010102 ShmFormat = 0x30335852 - // ShmFormatBgrx1010102 : 32-bit BGRx format, [31:0] B:G:R:x 10:10:10:2 little endian - ShmFormatBgrx1010102 ShmFormat = 0x30335842 - // ShmFormatArgb2101010 : 32-bit ARGB format, [31:0] A:R:G:B 2:10:10:10 little endian - ShmFormatArgb2101010 ShmFormat = 0x30335241 - // ShmFormatAbgr2101010 : 32-bit ABGR format, [31:0] A:B:G:R 2:10:10:10 little endian - ShmFormatAbgr2101010 ShmFormat = 0x30334241 - // ShmFormatRgba1010102 : 32-bit RGBA format, [31:0] R:G:B:A 10:10:10:2 little endian - ShmFormatRgba1010102 ShmFormat = 0x30334152 - // ShmFormatBgra1010102 : 32-bit BGRA format, [31:0] B:G:R:A 10:10:10:2 little endian - ShmFormatBgra1010102 ShmFormat = 0x30334142 - // ShmFormatYuyv : packed YCbCr format, [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian - ShmFormatYuyv ShmFormat = 0x56595559 - // ShmFormatYvyu : packed YCbCr format, [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian - ShmFormatYvyu ShmFormat = 0x55595659 - // ShmFormatUyvy : packed YCbCr format, [31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian - ShmFormatUyvy ShmFormat = 0x59565955 - // ShmFormatVyuy : packed YCbCr format, [31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian - ShmFormatVyuy ShmFormat = 0x59555956 - // ShmFormatAyuv : packed AYCbCr format, [31:0] A:Y:Cb:Cr 8:8:8:8 little endian - ShmFormatAyuv ShmFormat = 0x56555941 - // ShmFormatNv12 : 2 plane YCbCr Cr:Cb format, 2x2 subsampled Cr:Cb plane - ShmFormatNv12 ShmFormat = 0x3231564e - // ShmFormatNv21 : 2 plane YCbCr Cb:Cr format, 2x2 subsampled Cb:Cr plane - ShmFormatNv21 ShmFormat = 0x3132564e - // ShmFormatNv16 : 2 plane YCbCr Cr:Cb format, 2x1 subsampled Cr:Cb plane - ShmFormatNv16 ShmFormat = 0x3631564e - // ShmFormatNv61 : 2 plane YCbCr Cb:Cr format, 2x1 subsampled Cb:Cr plane - ShmFormatNv61 ShmFormat = 0x3136564e - // ShmFormatYuv410 : 3 plane YCbCr format, 4x4 subsampled Cb (1) and Cr (2) planes - ShmFormatYuv410 ShmFormat = 0x39565559 - // ShmFormatYvu410 : 3 plane YCbCr format, 4x4 subsampled Cr (1) and Cb (2) planes - ShmFormatYvu410 ShmFormat = 0x39555659 - // ShmFormatYuv411 : 3 plane YCbCr format, 4x1 subsampled Cb (1) and Cr (2) planes - ShmFormatYuv411 ShmFormat = 0x31315559 - // ShmFormatYvu411 : 3 plane YCbCr format, 4x1 subsampled Cr (1) and Cb (2) planes - ShmFormatYvu411 ShmFormat = 0x31315659 - // ShmFormatYuv420 : 3 plane YCbCr format, 2x2 subsampled Cb (1) and Cr (2) planes - ShmFormatYuv420 ShmFormat = 0x32315559 - // ShmFormatYvu420 : 3 plane YCbCr format, 2x2 subsampled Cr (1) and Cb (2) planes - ShmFormatYvu420 ShmFormat = 0x32315659 - // ShmFormatYuv422 : 3 plane YCbCr format, 2x1 subsampled Cb (1) and Cr (2) planes - ShmFormatYuv422 ShmFormat = 0x36315559 - // ShmFormatYvu422 : 3 plane YCbCr format, 2x1 subsampled Cr (1) and Cb (2) planes - ShmFormatYvu422 ShmFormat = 0x36315659 - // ShmFormatYuv444 : 3 plane YCbCr format, non-subsampled Cb (1) and Cr (2) planes - ShmFormatYuv444 ShmFormat = 0x34325559 - // ShmFormatYvu444 : 3 plane YCbCr format, non-subsampled Cr (1) and Cb (2) planes - ShmFormatYvu444 ShmFormat = 0x34325659 - // ShmFormatR8 : [7:0] R - ShmFormatR8 ShmFormat = 0x20203852 - // ShmFormatR16 : [15:0] R little endian - ShmFormatR16 ShmFormat = 0x20363152 - // ShmFormatRg88 : [15:0] R:G 8:8 little endian - ShmFormatRg88 ShmFormat = 0x38384752 - // ShmFormatGr88 : [15:0] G:R 8:8 little endian - ShmFormatGr88 ShmFormat = 0x38385247 - // ShmFormatRg1616 : [31:0] R:G 16:16 little endian - ShmFormatRg1616 ShmFormat = 0x32334752 - // ShmFormatGr1616 : [31:0] G:R 16:16 little endian - ShmFormatGr1616 ShmFormat = 0x32335247 - // ShmFormatXrgb16161616F : [63:0] x:R:G:B 16:16:16:16 little endian - ShmFormatXrgb16161616F ShmFormat = 0x48345258 - // ShmFormatXbgr16161616F : [63:0] x:B:G:R 16:16:16:16 little endian - ShmFormatXbgr16161616F ShmFormat = 0x48344258 - // ShmFormatArgb16161616F : [63:0] A:R:G:B 16:16:16:16 little endian - ShmFormatArgb16161616F ShmFormat = 0x48345241 - // ShmFormatAbgr16161616F : [63:0] A:B:G:R 16:16:16:16 little endian - ShmFormatAbgr16161616F ShmFormat = 0x48344241 - // ShmFormatXyuv8888 : [31:0] X:Y:Cb:Cr 8:8:8:8 little endian - ShmFormatXyuv8888 ShmFormat = 0x56555958 - // ShmFormatVuy888 : [23:0] Cr:Cb:Y 8:8:8 little endian - ShmFormatVuy888 ShmFormat = 0x34325556 - // ShmFormatVuy101010 : Y followed by U then V, 10:10:10. - ShmFormatVuy101010 ShmFormat = 0x30335556 - // ShmFormatY210 : [63:0] Cr0:0:Y1:0:Cb0:0:Y0:0 10:6:10:6:10:6:10:6 little endian per 2 Y pixels - ShmFormatY210 ShmFormat = 0x30313259 - // ShmFormatY212 : [63:0] Cr0:0:Y1:0:Cb0:0:Y0:0 12:4:12:4:12:4:12:4 little endian per 2 Y pixels - ShmFormatY212 ShmFormat = 0x32313259 - // ShmFormatY216 : [63:0] Cr0:Y1:Cb0:Y0 16:16:16:16 little endian per 2 Y pixels - ShmFormatY216 ShmFormat = 0x36313259 - // ShmFormatY410 : [31:0] A:Cr:Y:Cb 2:10:10:10 little endian - ShmFormatY410 ShmFormat = 0x30313459 - // ShmFormatY412 : [63:0] A:0:Cr:0:Y:0:Cb:0 12:4:12:4:12:4:12:4 little endian - ShmFormatY412 ShmFormat = 0x32313459 - // ShmFormatY416 : [63:0] A:Cr:Y:Cb 16:16:16:16 little endian - ShmFormatY416 ShmFormat = 0x36313459 - // ShmFormatXvyu2101010 : [31:0] X:Cr:Y:Cb 2:10:10:10 little endian - ShmFormatXvyu2101010 ShmFormat = 0x30335658 - // ShmFormatXvyu1216161616 : [63:0] X:0:Cr:0:Y:0:Cb:0 12:4:12:4:12:4:12:4 little endian - ShmFormatXvyu1216161616 ShmFormat = 0x36335658 - // ShmFormatXvyu16161616 : [63:0] X:Cr:Y:Cb 16:16:16:16 little endian - ShmFormatXvyu16161616 ShmFormat = 0x38345658 - // ShmFormatY0L0 : [63:0] A3:A2:Y3:0:Cr0:0:Y2:0:A1:A0:Y1:0:Cb0:0:Y0:0 1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian - ShmFormatY0L0 ShmFormat = 0x304c3059 - // ShmFormatX0L0 : [63:0] X3:X2:Y3:0:Cr0:0:Y2:0:X1:X0:Y1:0:Cb0:0:Y0:0 1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian - ShmFormatX0L0 ShmFormat = 0x304c3058 - // ShmFormatY0L2 : [63:0] A3:A2:Y3:Cr0:Y2:A1:A0:Y1:Cb0:Y0 1:1:10:10:10:1:1:10:10:10 little endian - ShmFormatY0L2 ShmFormat = 0x324c3059 - // ShmFormatX0L2 : [63:0] X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0 1:1:10:10:10:1:1:10:10:10 little endian - ShmFormatX0L2 ShmFormat = 0x324c3058 - ShmFormatYuv4208Bit ShmFormat = 0x38305559 - ShmFormatYuv42010Bit ShmFormat = 0x30315559 - ShmFormatXrgb8888A8 ShmFormat = 0x38415258 - ShmFormatXbgr8888A8 ShmFormat = 0x38414258 - ShmFormatRgbx8888A8 ShmFormat = 0x38415852 - ShmFormatBgrx8888A8 ShmFormat = 0x38415842 - ShmFormatRgb888A8 ShmFormat = 0x38413852 - ShmFormatBgr888A8 ShmFormat = 0x38413842 - ShmFormatRgb565A8 ShmFormat = 0x38413552 - ShmFormatBgr565A8 ShmFormat = 0x38413542 - // ShmFormatNv24 : non-subsampled Cr:Cb plane - ShmFormatNv24 ShmFormat = 0x3432564e - // ShmFormatNv42 : non-subsampled Cb:Cr plane - ShmFormatNv42 ShmFormat = 0x3234564e - // ShmFormatP210 : 2x1 subsampled Cr:Cb plane, 10 bit per channel - ShmFormatP210 ShmFormat = 0x30313250 - // ShmFormatP010 : 2x2 subsampled Cr:Cb plane 10 bits per channel - ShmFormatP010 ShmFormat = 0x30313050 - // ShmFormatP012 : 2x2 subsampled Cr:Cb plane 12 bits per channel - ShmFormatP012 ShmFormat = 0x32313050 - // ShmFormatP016 : 2x2 subsampled Cr:Cb plane 16 bits per channel - ShmFormatP016 ShmFormat = 0x36313050 - // ShmFormatAxbxgxrx106106106106 : [63:0] A:x:B:x:G:x:R:x 10:6:10:6:10:6:10:6 little endian - ShmFormatAxbxgxrx106106106106 ShmFormat = 0x30314241 - // ShmFormatNv15 : 2x2 subsampled Cr:Cb plane - ShmFormatNv15 ShmFormat = 0x3531564e - ShmFormatQ410 ShmFormat = 0x30313451 - ShmFormatQ401 ShmFormat = 0x31303451 - // ShmFormatXrgb16161616 : [63:0] x:R:G:B 16:16:16:16 little endian - ShmFormatXrgb16161616 ShmFormat = 0x38345258 - // ShmFormatXbgr16161616 : [63:0] x:B:G:R 16:16:16:16 little endian - ShmFormatXbgr16161616 ShmFormat = 0x38344258 - // ShmFormatArgb16161616 : [63:0] A:R:G:B 16:16:16:16 little endian - ShmFormatArgb16161616 ShmFormat = 0x38345241 - // ShmFormatAbgr16161616 : [63:0] A:B:G:R 16:16:16:16 little endian - ShmFormatAbgr16161616 ShmFormat = 0x38344241 - // ShmFormatC1 : [7:0] C0:C1:C2:C3:C4:C5:C6:C7 1:1:1:1:1:1:1:1 eight pixels/byte - ShmFormatC1 ShmFormat = 0x20203143 - // ShmFormatC2 : [7:0] C0:C1:C2:C3 2:2:2:2 four pixels/byte - ShmFormatC2 ShmFormat = 0x20203243 - // ShmFormatC4 : [7:0] C0:C1 4:4 two pixels/byte - ShmFormatC4 ShmFormat = 0x20203443 - // ShmFormatD1 : [7:0] D0:D1:D2:D3:D4:D5:D6:D7 1:1:1:1:1:1:1:1 eight pixels/byte - ShmFormatD1 ShmFormat = 0x20203144 - // ShmFormatD2 : [7:0] D0:D1:D2:D3 2:2:2:2 four pixels/byte - ShmFormatD2 ShmFormat = 0x20203244 - // ShmFormatD4 : [7:0] D0:D1 4:4 two pixels/byte - ShmFormatD4 ShmFormat = 0x20203444 - // ShmFormatD8 : [7:0] D - ShmFormatD8 ShmFormat = 0x20203844 - // ShmFormatR1 : [7:0] R0:R1:R2:R3:R4:R5:R6:R7 1:1:1:1:1:1:1:1 eight pixels/byte - ShmFormatR1 ShmFormat = 0x20203152 - // ShmFormatR2 : [7:0] R0:R1:R2:R3 2:2:2:2 four pixels/byte - ShmFormatR2 ShmFormat = 0x20203252 - // ShmFormatR4 : [7:0] R0:R1 4:4 two pixels/byte - ShmFormatR4 ShmFormat = 0x20203452 - // ShmFormatR10 : [15:0] x:R 6:10 little endian - ShmFormatR10 ShmFormat = 0x20303152 - // ShmFormatR12 : [15:0] x:R 4:12 little endian - ShmFormatR12 ShmFormat = 0x20323152 - // ShmFormatAvuy8888 : [31:0] A:Cr:Cb:Y 8:8:8:8 little endian - ShmFormatAvuy8888 ShmFormat = 0x59555641 - // ShmFormatXvuy8888 : [31:0] X:Cr:Cb:Y 8:8:8:8 little endian - ShmFormatXvuy8888 ShmFormat = 0x59555658 - // ShmFormatP030 : 2x2 subsampled Cr:Cb plane 10 bits per channel packed - ShmFormatP030 ShmFormat = 0x30333050 -) - -func (e ShmFormat) Name() string { - switch e { - case ShmFormatArgb8888: - return "argb8888" - case ShmFormatXrgb8888: - return "xrgb8888" - case ShmFormatC8: - return "c8" - case ShmFormatRgb332: - return "rgb332" - case ShmFormatBgr233: - return "bgr233" - case ShmFormatXrgb4444: - return "xrgb4444" - case ShmFormatXbgr4444: - return "xbgr4444" - case ShmFormatRgbx4444: - return "rgbx4444" - case ShmFormatBgrx4444: - return "bgrx4444" - case ShmFormatArgb4444: - return "argb4444" - case ShmFormatAbgr4444: - return "abgr4444" - case ShmFormatRgba4444: - return "rgba4444" - case ShmFormatBgra4444: - return "bgra4444" - case ShmFormatXrgb1555: - return "xrgb1555" - case ShmFormatXbgr1555: - return "xbgr1555" - case ShmFormatRgbx5551: - return "rgbx5551" - case ShmFormatBgrx5551: - return "bgrx5551" - case ShmFormatArgb1555: - return "argb1555" - case ShmFormatAbgr1555: - return "abgr1555" - case ShmFormatRgba5551: - return "rgba5551" - case ShmFormatBgra5551: - return "bgra5551" - case ShmFormatRgb565: - return "rgb565" - case ShmFormatBgr565: - return "bgr565" - case ShmFormatRgb888: - return "rgb888" - case ShmFormatBgr888: - return "bgr888" - case ShmFormatXbgr8888: - return "xbgr8888" - case ShmFormatRgbx8888: - return "rgbx8888" - case ShmFormatBgrx8888: - return "bgrx8888" - case ShmFormatAbgr8888: - return "abgr8888" - case ShmFormatRgba8888: - return "rgba8888" - case ShmFormatBgra8888: - return "bgra8888" - case ShmFormatXrgb2101010: - return "xrgb2101010" - case ShmFormatXbgr2101010: - return "xbgr2101010" - case ShmFormatRgbx1010102: - return "rgbx1010102" - case ShmFormatBgrx1010102: - return "bgrx1010102" - case ShmFormatArgb2101010: - return "argb2101010" - case ShmFormatAbgr2101010: - return "abgr2101010" - case ShmFormatRgba1010102: - return "rgba1010102" - case ShmFormatBgra1010102: - return "bgra1010102" - case ShmFormatYuyv: - return "yuyv" - case ShmFormatYvyu: - return "yvyu" - case ShmFormatUyvy: - return "uyvy" - case ShmFormatVyuy: - return "vyuy" - case ShmFormatAyuv: - return "ayuv" - case ShmFormatNv12: - return "nv12" - case ShmFormatNv21: - return "nv21" - case ShmFormatNv16: - return "nv16" - case ShmFormatNv61: - return "nv61" - case ShmFormatYuv410: - return "yuv410" - case ShmFormatYvu410: - return "yvu410" - case ShmFormatYuv411: - return "yuv411" - case ShmFormatYvu411: - return "yvu411" - case ShmFormatYuv420: - return "yuv420" - case ShmFormatYvu420: - return "yvu420" - case ShmFormatYuv422: - return "yuv422" - case ShmFormatYvu422: - return "yvu422" - case ShmFormatYuv444: - return "yuv444" - case ShmFormatYvu444: - return "yvu444" - case ShmFormatR8: - return "r8" - case ShmFormatR16: - return "r16" - case ShmFormatRg88: - return "rg88" - case ShmFormatGr88: - return "gr88" - case ShmFormatRg1616: - return "rg1616" - case ShmFormatGr1616: - return "gr1616" - case ShmFormatXrgb16161616F: - return "xrgb16161616f" - case ShmFormatXbgr16161616F: - return "xbgr16161616f" - case ShmFormatArgb16161616F: - return "argb16161616f" - case ShmFormatAbgr16161616F: - return "abgr16161616f" - case ShmFormatXyuv8888: - return "xyuv8888" - case ShmFormatVuy888: - return "vuy888" - case ShmFormatVuy101010: - return "vuy101010" - case ShmFormatY210: - return "y210" - case ShmFormatY212: - return "y212" - case ShmFormatY216: - return "y216" - case ShmFormatY410: - return "y410" - case ShmFormatY412: - return "y412" - case ShmFormatY416: - return "y416" - case ShmFormatXvyu2101010: - return "xvyu2101010" - case ShmFormatXvyu1216161616: - return "xvyu12_16161616" - case ShmFormatXvyu16161616: - return "xvyu16161616" - case ShmFormatY0L0: - return "y0l0" - case ShmFormatX0L0: - return "x0l0" - case ShmFormatY0L2: - return "y0l2" - case ShmFormatX0L2: - return "x0l2" - case ShmFormatYuv4208Bit: - return "yuv420_8bit" - case ShmFormatYuv42010Bit: - return "yuv420_10bit" - case ShmFormatXrgb8888A8: - return "xrgb8888_a8" - case ShmFormatXbgr8888A8: - return "xbgr8888_a8" - case ShmFormatRgbx8888A8: - return "rgbx8888_a8" - case ShmFormatBgrx8888A8: - return "bgrx8888_a8" - case ShmFormatRgb888A8: - return "rgb888_a8" - case ShmFormatBgr888A8: - return "bgr888_a8" - case ShmFormatRgb565A8: - return "rgb565_a8" - case ShmFormatBgr565A8: - return "bgr565_a8" - case ShmFormatNv24: - return "nv24" - case ShmFormatNv42: - return "nv42" - case ShmFormatP210: - return "p210" - case ShmFormatP010: - return "p010" - case ShmFormatP012: - return "p012" - case ShmFormatP016: - return "p016" - case ShmFormatAxbxgxrx106106106106: - return "axbxgxrx106106106106" - case ShmFormatNv15: - return "nv15" - case ShmFormatQ410: - return "q410" - case ShmFormatQ401: - return "q401" - case ShmFormatXrgb16161616: - return "xrgb16161616" - case ShmFormatXbgr16161616: - return "xbgr16161616" - case ShmFormatArgb16161616: - return "argb16161616" - case ShmFormatAbgr16161616: - return "abgr16161616" - case ShmFormatC1: - return "c1" - case ShmFormatC2: - return "c2" - case ShmFormatC4: - return "c4" - case ShmFormatD1: - return "d1" - case ShmFormatD2: - return "d2" - case ShmFormatD4: - return "d4" - case ShmFormatD8: - return "d8" - case ShmFormatR1: - return "r1" - case ShmFormatR2: - return "r2" - case ShmFormatR4: - return "r4" - case ShmFormatR10: - return "r10" - case ShmFormatR12: - return "r12" - case ShmFormatAvuy8888: - return "avuy8888" - case ShmFormatXvuy8888: - return "xvuy8888" - case ShmFormatP030: - return "p030" - default: - return "" - } -} - -func (e ShmFormat) Value() string { - switch e { - case ShmFormatArgb8888: - return "0" - case ShmFormatXrgb8888: - return "1" - case ShmFormatC8: - return "0x20203843" - case ShmFormatRgb332: - return "0x38424752" - case ShmFormatBgr233: - return "0x38524742" - case ShmFormatXrgb4444: - return "0x32315258" - case ShmFormatXbgr4444: - return "0x32314258" - case ShmFormatRgbx4444: - return "0x32315852" - case ShmFormatBgrx4444: - return "0x32315842" - case ShmFormatArgb4444: - return "0x32315241" - case ShmFormatAbgr4444: - return "0x32314241" - case ShmFormatRgba4444: - return "0x32314152" - case ShmFormatBgra4444: - return "0x32314142" - case ShmFormatXrgb1555: - return "0x35315258" - case ShmFormatXbgr1555: - return "0x35314258" - case ShmFormatRgbx5551: - return "0x35315852" - case ShmFormatBgrx5551: - return "0x35315842" - case ShmFormatArgb1555: - return "0x35315241" - case ShmFormatAbgr1555: - return "0x35314241" - case ShmFormatRgba5551: - return "0x35314152" - case ShmFormatBgra5551: - return "0x35314142" - case ShmFormatRgb565: - return "0x36314752" - case ShmFormatBgr565: - return "0x36314742" - case ShmFormatRgb888: - return "0x34324752" - case ShmFormatBgr888: - return "0x34324742" - case ShmFormatXbgr8888: - return "0x34324258" - case ShmFormatRgbx8888: - return "0x34325852" - case ShmFormatBgrx8888: - return "0x34325842" - case ShmFormatAbgr8888: - return "0x34324241" - case ShmFormatRgba8888: - return "0x34324152" - case ShmFormatBgra8888: - return "0x34324142" - case ShmFormatXrgb2101010: - return "0x30335258" - case ShmFormatXbgr2101010: - return "0x30334258" - case ShmFormatRgbx1010102: - return "0x30335852" - case ShmFormatBgrx1010102: - return "0x30335842" - case ShmFormatArgb2101010: - return "0x30335241" - case ShmFormatAbgr2101010: - return "0x30334241" - case ShmFormatRgba1010102: - return "0x30334152" - case ShmFormatBgra1010102: - return "0x30334142" - case ShmFormatYuyv: - return "0x56595559" - case ShmFormatYvyu: - return "0x55595659" - case ShmFormatUyvy: - return "0x59565955" - case ShmFormatVyuy: - return "0x59555956" - case ShmFormatAyuv: - return "0x56555941" - case ShmFormatNv12: - return "0x3231564e" - case ShmFormatNv21: - return "0x3132564e" - case ShmFormatNv16: - return "0x3631564e" - case ShmFormatNv61: - return "0x3136564e" - case ShmFormatYuv410: - return "0x39565559" - case ShmFormatYvu410: - return "0x39555659" - case ShmFormatYuv411: - return "0x31315559" - case ShmFormatYvu411: - return "0x31315659" - case ShmFormatYuv420: - return "0x32315559" - case ShmFormatYvu420: - return "0x32315659" - case ShmFormatYuv422: - return "0x36315559" - case ShmFormatYvu422: - return "0x36315659" - case ShmFormatYuv444: - return "0x34325559" - case ShmFormatYvu444: - return "0x34325659" - case ShmFormatR8: - return "0x20203852" - case ShmFormatR16: - return "0x20363152" - case ShmFormatRg88: - return "0x38384752" - case ShmFormatGr88: - return "0x38385247" - case ShmFormatRg1616: - return "0x32334752" - case ShmFormatGr1616: - return "0x32335247" - case ShmFormatXrgb16161616F: - return "0x48345258" - case ShmFormatXbgr16161616F: - return "0x48344258" - case ShmFormatArgb16161616F: - return "0x48345241" - case ShmFormatAbgr16161616F: - return "0x48344241" - case ShmFormatXyuv8888: - return "0x56555958" - case ShmFormatVuy888: - return "0x34325556" - case ShmFormatVuy101010: - return "0x30335556" - case ShmFormatY210: - return "0x30313259" - case ShmFormatY212: - return "0x32313259" - case ShmFormatY216: - return "0x36313259" - case ShmFormatY410: - return "0x30313459" - case ShmFormatY412: - return "0x32313459" - case ShmFormatY416: - return "0x36313459" - case ShmFormatXvyu2101010: - return "0x30335658" - case ShmFormatXvyu1216161616: - return "0x36335658" - case ShmFormatXvyu16161616: - return "0x38345658" - case ShmFormatY0L0: - return "0x304c3059" - case ShmFormatX0L0: - return "0x304c3058" - case ShmFormatY0L2: - return "0x324c3059" - case ShmFormatX0L2: - return "0x324c3058" - case ShmFormatYuv4208Bit: - return "0x38305559" - case ShmFormatYuv42010Bit: - return "0x30315559" - case ShmFormatXrgb8888A8: - return "0x38415258" - case ShmFormatXbgr8888A8: - return "0x38414258" - case ShmFormatRgbx8888A8: - return "0x38415852" - case ShmFormatBgrx8888A8: - return "0x38415842" - case ShmFormatRgb888A8: - return "0x38413852" - case ShmFormatBgr888A8: - return "0x38413842" - case ShmFormatRgb565A8: - return "0x38413552" - case ShmFormatBgr565A8: - return "0x38413542" - case ShmFormatNv24: - return "0x3432564e" - case ShmFormatNv42: - return "0x3234564e" - case ShmFormatP210: - return "0x30313250" - case ShmFormatP010: - return "0x30313050" - case ShmFormatP012: - return "0x32313050" - case ShmFormatP016: - return "0x36313050" - case ShmFormatAxbxgxrx106106106106: - return "0x30314241" - case ShmFormatNv15: - return "0x3531564e" - case ShmFormatQ410: - return "0x30313451" - case ShmFormatQ401: - return "0x31303451" - case ShmFormatXrgb16161616: - return "0x38345258" - case ShmFormatXbgr16161616: - return "0x38344258" - case ShmFormatArgb16161616: - return "0x38345241" - case ShmFormatAbgr16161616: - return "0x38344241" - case ShmFormatC1: - return "0x20203143" - case ShmFormatC2: - return "0x20203243" - case ShmFormatC4: - return "0x20203443" - case ShmFormatD1: - return "0x20203144" - case ShmFormatD2: - return "0x20203244" - case ShmFormatD4: - return "0x20203444" - case ShmFormatD8: - return "0x20203844" - case ShmFormatR1: - return "0x20203152" - case ShmFormatR2: - return "0x20203252" - case ShmFormatR4: - return "0x20203452" - case ShmFormatR10: - return "0x20303152" - case ShmFormatR12: - return "0x20323152" - case ShmFormatAvuy8888: - return "0x59555641" - case ShmFormatXvuy8888: - return "0x59555658" - case ShmFormatP030: - return "0x30333050" - default: - return "" - } -} - -func (e ShmFormat) String() string { - return e.Name() + "=" + e.Value() -} - -// ShmFormatEvent : pixel format description -// -// Informs the client about a valid pixel format that -// can be used for buffers. Known formats include -// argb8888 and xrgb8888. -type ShmFormatEvent struct { - Format uint32 -} -type ShmFormatHandlerFunc func(ShmFormatEvent) - -// SetFormatHandler : sets handler for ShmFormatEvent -func (i *Shm) SetFormatHandler(f ShmFormatHandlerFunc) { - i.formatHandler = f -} - -func (i *Shm) Dispatch(opcode uint32, fd int, data []byte) { - switch opcode { - case 0: - if i.formatHandler == nil { - return - } - var e ShmFormatEvent - l := 0 - e.Format = Uint32(data[l : l+4]) - l += 4 - - i.formatHandler(e) - } -} - -// BufferInterfaceName is the name of the interface as it appears in the [client.Registry]. -// It can be used to match the [client.RegistryGlobalEvent.Interface] in the -// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies. -const BufferInterfaceName = "wl_buffer" - -// Buffer : content for a wl_surface -// -// A buffer provides the content for a wl_surface. Buffers are -// created through factory interfaces such as wl_shm, wp_linux_buffer_params -// (from the linux-dmabuf protocol extension) or similar. It has a width and -// a height and can be attached to a wl_surface, but the mechanism by which a -// client provides and updates the contents is defined by the buffer factory -// interface. -// -// Color channels are assumed to be electrical rather than optical (in other -// words, encoded with a transfer function) unless otherwise specified. If -// the buffer uses a format that has an alpha channel, the alpha channel is -// assumed to be premultiplied into the electrical color channel values -// (after transfer function encoding) unless otherwise specified. -// -// Note, because wl_buffer objects are created from multiple independent -// factory interfaces, the wl_buffer interface is frozen at version 1. -type Buffer struct { - BaseProxy - releaseHandler BufferReleaseHandlerFunc -} - -// NewBuffer : content for a wl_surface -// -// A buffer provides the content for a wl_surface. Buffers are -// created through factory interfaces such as wl_shm, wp_linux_buffer_params -// (from the linux-dmabuf protocol extension) or similar. It has a width and -// a height and can be attached to a wl_surface, but the mechanism by which a -// client provides and updates the contents is defined by the buffer factory -// interface. -// -// Color channels are assumed to be electrical rather than optical (in other -// words, encoded with a transfer function) unless otherwise specified. If -// the buffer uses a format that has an alpha channel, the alpha channel is -// assumed to be premultiplied into the electrical color channel values -// (after transfer function encoding) unless otherwise specified. -// -// Note, because wl_buffer objects are created from multiple independent -// factory interfaces, the wl_buffer interface is frozen at version 1. -func NewBuffer(ctx *Context) *Buffer { - wlBuffer := &Buffer{} - ctx.Register(wlBuffer) - return wlBuffer -} - -// Destroy : destroy a buffer -// -// Destroy a buffer. If and how you need to release the backing -// storage is defined by the buffer factory interface. -// -// For possible side-effects to a surface, see wl_surface.attach. -func (i *Buffer) Destroy() error { - defer i.MarkZombie() - const opcode = 0 - const _reqBufLen = 8 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// BufferReleaseEvent : compositor releases buffer -// -// Sent when this wl_buffer is no longer used by the compositor. -// -// For more information on when release events may or may not be sent, -// and what consequences it has, please see the description of -// wl_surface.attach. -// -// If a client receives a release event before the frame callback -// requested in the same wl_surface.commit that attaches this -// wl_buffer to a surface, then the client is immediately free to -// reuse the buffer and its backing storage, and does not need a -// second buffer for the next surface content update. Typically -// this is possible, when the compositor maintains a copy of the -// wl_surface contents, e.g. as a GL texture. This is an important -// optimization for GL(ES) compositors with wl_shm clients. -type BufferReleaseEvent struct{} -type BufferReleaseHandlerFunc func(BufferReleaseEvent) - -// SetReleaseHandler : sets handler for BufferReleaseEvent -func (i *Buffer) SetReleaseHandler(f BufferReleaseHandlerFunc) { - i.releaseHandler = f -} - -func (i *Buffer) Dispatch(opcode uint32, fd int, data []byte) { - switch opcode { - case 0: - if i.releaseHandler == nil { - return - } - var e BufferReleaseEvent - - i.releaseHandler(e) - } -} - -// DataOfferInterfaceName is the name of the interface as it appears in the [client.Registry]. -// It can be used to match the [client.RegistryGlobalEvent.Interface] in the -// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies. -const DataOfferInterfaceName = "wl_data_offer" - -// DataOffer : offer to transfer data -// -// A wl_data_offer represents a piece of data offered for transfer -// by another client (the source client). It is used by the -// copy-and-paste and drag-and-drop mechanisms. The offer -// describes the different mime types that the data can be -// converted to and provides the mechanism for transferring the -// data directly from the source client. -type DataOffer struct { - BaseProxy - offerHandler DataOfferOfferHandlerFunc - sourceActionsHandler DataOfferSourceActionsHandlerFunc - actionHandler DataOfferActionHandlerFunc -} - -// NewDataOffer : offer to transfer data -// -// A wl_data_offer represents a piece of data offered for transfer -// by another client (the source client). It is used by the -// copy-and-paste and drag-and-drop mechanisms. The offer -// describes the different mime types that the data can be -// converted to and provides the mechanism for transferring the -// data directly from the source client. -func NewDataOffer(ctx *Context) *DataOffer { - wlDataOffer := &DataOffer{} - ctx.Register(wlDataOffer) - return wlDataOffer -} - -// Accept : accept one of the offered mime types -// -// Indicate that the client can accept the given mime type, or -// NULL for not accepted. -// -// For objects of version 2 or older, this request is used by the -// client to give feedback whether the client can receive the given -// mime type, or NULL if none is accepted; the feedback does not -// determine whether the drag-and-drop operation succeeds or not. -// -// For objects of version 3 or newer, this request determines the -// final result of the drag-and-drop operation. If the end result -// is that no mime types were accepted, the drag-and-drop operation -// will be cancelled and the corresponding drag source will receive -// wl_data_source.cancelled. Clients may still use this event in -// conjunction with wl_data_source.action for feedback. -// -// serial: serial number of the accept request -// mimeType: mime type accepted by the client -func (i *DataOffer) Accept(serial uint32, mimeType string) error { - const opcode = 0 - mimeTypeLen := PaddedLen(len(mimeType) + 1) - _reqBufLen := 8 + 4 + (4 + mimeTypeLen) - _reqBuf := make([]byte, _reqBufLen) - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(serial)) - l += 4 - PutString(_reqBuf[l:l+(4+mimeTypeLen)], mimeType) - l += (4 + mimeTypeLen) - err := i.Context().WriteMsg(_reqBuf, nil) - return err -} - -// Receive : request that the data is transferred -// -// To transfer the offered data, the client issues this request -// and indicates the mime type it wants to receive. The transfer -// happens through the passed file descriptor (typically created -// with the pipe system call). The source client writes the data -// in the mime type representation requested and then closes the -// file descriptor. -// -// The receiving client reads from the read end of the pipe until -// EOF and then closes its end, at which point the transfer is -// complete. -// -// This request may happen multiple times for different mime types, -// both before and after wl_data_device.drop. Drag-and-drop destination -// clients may preemptively fetch data or examine it more closely to -// determine acceptance. -// -// mimeType: mime type desired by receiver -// fd: file descriptor for data transfer -func (i *DataOffer) Receive(mimeType string, fd int) error { - const opcode = 1 - mimeTypeLen := PaddedLen(len(mimeType) + 1) - _reqBufLen := 8 + (4 + mimeTypeLen) - _reqBuf := make([]byte, _reqBufLen) - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutString(_reqBuf[l:l+(4+mimeTypeLen)], mimeType) - l += (4 + mimeTypeLen) - oob := unix.UnixRights(int(fd)) - err := i.Context().WriteMsg(_reqBuf, oob) - return err -} - -// Destroy : destroy data offer -// -// Destroy the data offer. -func (i *DataOffer) Destroy() error { - defer i.MarkZombie() - const opcode = 2 - const _reqBufLen = 8 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// Finish : the offer will no longer be used -// -// Notifies the compositor that the drag destination successfully -// finished the drag-and-drop operation. -// -// Upon receiving this request, the compositor will emit -// wl_data_source.dnd_finished on the drag source client. -// -// It is a client error to perform other requests than -// wl_data_offer.destroy after this one. It is also an error to perform -// this request after a NULL mime type has been set in -// wl_data_offer.accept or no action was received through -// wl_data_offer.action. -// -// If wl_data_offer.finish request is received for a non drag and drop -// operation, the invalid_finish protocol error is raised. -func (i *DataOffer) Finish() error { - const opcode = 3 - const _reqBufLen = 8 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// SetActions : set the available/preferred drag-and-drop actions -// -// Sets the actions that the destination side client supports for -// this operation. This request may trigger the emission of -// wl_data_source.action and wl_data_offer.action events if the compositor -// needs to change the selected action. -// -// This request can be called multiple times throughout the -// drag-and-drop operation, typically in response to wl_data_device.enter -// or wl_data_device.motion events. -// -// This request determines the final result of the drag-and-drop -// operation. If the end result is that no action is accepted, -// the drag source will receive wl_data_source.cancelled. -// -// The dnd_actions argument must contain only values expressed in the -// wl_data_device_manager.dnd_actions enum, and the preferred_action -// argument must only contain one of those values set, otherwise it -// will result in a protocol error. -// -// While managing an "ask" action, the destination drag-and-drop client -// may perform further wl_data_offer.receive requests, and is expected -// to perform one last wl_data_offer.set_actions request with a preferred -// action other than "ask" (and optionally wl_data_offer.accept) before -// requesting wl_data_offer.finish, in order to convey the action selected -// by the user. If the preferred action is not in the -// wl_data_offer.source_actions mask, an error will be raised. -// -// If the "ask" action is dismissed (e.g. user cancellation), the client -// is expected to perform wl_data_offer.destroy right away. -// -// This request can only be made on drag-and-drop offers, a protocol error -// will be raised otherwise. -// -// dndActions: actions supported by the destination client -// preferredAction: action preferred by the destination client -func (i *DataOffer) SetActions(dndActions, preferredAction uint32) error { - const opcode = 4 - const _reqBufLen = 8 + 4 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(dndActions)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(preferredAction)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -type DataOfferError uint32 - -// DataOfferError : -const ( - // DataOfferErrorInvalidFinish : finish request was called untimely - DataOfferErrorInvalidFinish DataOfferError = 0 - // DataOfferErrorInvalidActionMask : action mask contains invalid values - DataOfferErrorInvalidActionMask DataOfferError = 1 - // DataOfferErrorInvalidAction : action argument has an invalid value - DataOfferErrorInvalidAction DataOfferError = 2 - // DataOfferErrorInvalidOffer : offer doesn't accept this request - DataOfferErrorInvalidOffer DataOfferError = 3 -) - -func (e DataOfferError) Name() string { - switch e { - case DataOfferErrorInvalidFinish: - return "invalid_finish" - case DataOfferErrorInvalidActionMask: - return "invalid_action_mask" - case DataOfferErrorInvalidAction: - return "invalid_action" - case DataOfferErrorInvalidOffer: - return "invalid_offer" - default: - return "" - } -} - -func (e DataOfferError) Value() string { - switch e { - case DataOfferErrorInvalidFinish: - return "0" - case DataOfferErrorInvalidActionMask: - return "1" - case DataOfferErrorInvalidAction: - return "2" - case DataOfferErrorInvalidOffer: - return "3" - default: - return "" - } -} - -func (e DataOfferError) String() string { - return e.Name() + "=" + e.Value() -} - -// DataOfferOfferEvent : advertise offered mime type -// -// Sent immediately after creating the wl_data_offer object. One -// event per offered mime type. -type DataOfferOfferEvent struct { - MimeType string -} -type DataOfferOfferHandlerFunc func(DataOfferOfferEvent) - -// SetOfferHandler : sets handler for DataOfferOfferEvent -func (i *DataOffer) SetOfferHandler(f DataOfferOfferHandlerFunc) { - i.offerHandler = f -} - -// DataOfferSourceActionsEvent : notify the source-side available actions -// -// This event indicates the actions offered by the data source. It -// will be sent immediately after creating the wl_data_offer object, -// or anytime the source side changes its offered actions through -// wl_data_source.set_actions. -type DataOfferSourceActionsEvent struct { - SourceActions uint32 -} -type DataOfferSourceActionsHandlerFunc func(DataOfferSourceActionsEvent) - -// SetSourceActionsHandler : sets handler for DataOfferSourceActionsEvent -func (i *DataOffer) SetSourceActionsHandler(f DataOfferSourceActionsHandlerFunc) { - i.sourceActionsHandler = f -} - -// DataOfferActionEvent : notify the selected action -// -// This event indicates the action selected by the compositor after -// matching the source/destination side actions. Only one action (or -// none) will be offered here. -// -// This event can be emitted multiple times during the drag-and-drop -// operation in response to destination side action changes through -// wl_data_offer.set_actions. -// -// This event will no longer be emitted after wl_data_device.drop -// happened on the drag-and-drop destination, the client must -// honor the last action received, or the last preferred one set -// through wl_data_offer.set_actions when handling an "ask" action. -// -// Compositors may also change the selected action on the fly, mainly -// in response to keyboard modifier changes during the drag-and-drop -// operation. -// -// The most recent action received is always the valid one. Prior to -// receiving wl_data_device.drop, the chosen action may change (e.g. -// due to keyboard modifiers being pressed). At the time of receiving -// wl_data_device.drop the drag-and-drop destination must honor the -// last action received. -// -// Action changes may still happen after wl_data_device.drop, -// especially on "ask" actions, where the drag-and-drop destination -// may choose another action afterwards. Action changes happening -// at this stage are always the result of inter-client negotiation, the -// compositor shall no longer be able to induce a different action. -// -// Upon "ask" actions, it is expected that the drag-and-drop destination -// may potentially choose a different action and/or mime type, -// based on wl_data_offer.source_actions and finally chosen by the -// user (e.g. popping up a menu with the available options). The -// final wl_data_offer.set_actions and wl_data_offer.accept requests -// must happen before the call to wl_data_offer.finish. -type DataOfferActionEvent struct { - DndAction uint32 -} -type DataOfferActionHandlerFunc func(DataOfferActionEvent) - -// SetActionHandler : sets handler for DataOfferActionEvent -func (i *DataOffer) SetActionHandler(f DataOfferActionHandlerFunc) { - i.actionHandler = f -} - -func (i *DataOffer) Dispatch(opcode uint32, fd int, data []byte) { - switch opcode { - case 0: - if i.offerHandler == nil { - return - } - var e DataOfferOfferEvent - l := 0 - mimeTypeLen := PaddedLen(int(Uint32(data[l : l+4]))) - l += 4 - e.MimeType = String(data[l : l+mimeTypeLen]) - l += mimeTypeLen - - i.offerHandler(e) - case 1: - if i.sourceActionsHandler == nil { - return - } - var e DataOfferSourceActionsEvent - l := 0 - e.SourceActions = Uint32(data[l : l+4]) - l += 4 - - i.sourceActionsHandler(e) - case 2: - if i.actionHandler == nil { - return - } - var e DataOfferActionEvent - l := 0 - e.DndAction = Uint32(data[l : l+4]) - l += 4 - - i.actionHandler(e) - } -} - -// DataSourceInterfaceName is the name of the interface as it appears in the [client.Registry]. -// It can be used to match the [client.RegistryGlobalEvent.Interface] in the -// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies. -const DataSourceInterfaceName = "wl_data_source" - -// DataSource : offer to transfer data -// -// The wl_data_source object is the source side of a wl_data_offer. -// It is created by the source client in a data transfer and -// provides a way to describe the offered data and a way to respond -// to requests to transfer the data. -type DataSource struct { - BaseProxy - targetHandler DataSourceTargetHandlerFunc - sendHandler DataSourceSendHandlerFunc - cancelledHandler DataSourceCancelledHandlerFunc - dndDropPerformedHandler DataSourceDndDropPerformedHandlerFunc - dndFinishedHandler DataSourceDndFinishedHandlerFunc - actionHandler DataSourceActionHandlerFunc -} - -// NewDataSource : offer to transfer data -// -// The wl_data_source object is the source side of a wl_data_offer. -// It is created by the source client in a data transfer and -// provides a way to describe the offered data and a way to respond -// to requests to transfer the data. -func NewDataSource(ctx *Context) *DataSource { - wlDataSource := &DataSource{} - ctx.Register(wlDataSource) - return wlDataSource -} - -// Offer : add an offered mime type -// -// This request adds a mime type to the set of mime types -// advertised to targets. Can be called several times to offer -// multiple types. -// -// mimeType: mime type offered by the data source -func (i *DataSource) Offer(mimeType string) error { - const opcode = 0 - mimeTypeLen := PaddedLen(len(mimeType) + 1) - _reqBufLen := 8 + (4 + mimeTypeLen) - _reqBuf := make([]byte, _reqBufLen) - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutString(_reqBuf[l:l+(4+mimeTypeLen)], mimeType) - l += (4 + mimeTypeLen) - err := i.Context().WriteMsg(_reqBuf, nil) - return err -} - -// Destroy : destroy the data source -// -// Destroy the data source. -func (i *DataSource) Destroy() error { - defer i.MarkZombie() - const opcode = 1 - const _reqBufLen = 8 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// SetActions : set the available drag-and-drop actions -// -// Sets the actions that the source side client supports for this -// operation. This request may trigger wl_data_source.action and -// wl_data_offer.action events if the compositor needs to change the -// selected action. -// -// The dnd_actions argument must contain only values expressed in the -// wl_data_device_manager.dnd_actions enum, otherwise it will result -// in a protocol error. -// -// This request must be made once only, and can only be made on sources -// used in drag-and-drop, so it must be performed before -// wl_data_device.start_drag. Attempting to use the source other than -// for drag-and-drop will raise a protocol error. -// -// dndActions: actions supported by the data source -func (i *DataSource) SetActions(dndActions uint32) error { - const opcode = 2 - const _reqBufLen = 8 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(dndActions)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -type DataSourceError uint32 - -// DataSourceError : -const ( - // DataSourceErrorInvalidActionMask : action mask contains invalid values - DataSourceErrorInvalidActionMask DataSourceError = 0 - // DataSourceErrorInvalidSource : source doesn't accept this request - DataSourceErrorInvalidSource DataSourceError = 1 -) - -func (e DataSourceError) Name() string { - switch e { - case DataSourceErrorInvalidActionMask: - return "invalid_action_mask" - case DataSourceErrorInvalidSource: - return "invalid_source" - default: - return "" - } -} - -func (e DataSourceError) Value() string { - switch e { - case DataSourceErrorInvalidActionMask: - return "0" - case DataSourceErrorInvalidSource: - return "1" - default: - return "" - } -} - -func (e DataSourceError) String() string { - return e.Name() + "=" + e.Value() -} - -// DataSourceTargetEvent : a target accepts an offered mime type -// -// Sent when a target accepts pointer_focus or motion events. If -// a target does not accept any of the offered types, type is NULL. -// -// Used for feedback during drag-and-drop. -type DataSourceTargetEvent struct { - MimeType string -} -type DataSourceTargetHandlerFunc func(DataSourceTargetEvent) - -// SetTargetHandler : sets handler for DataSourceTargetEvent -func (i *DataSource) SetTargetHandler(f DataSourceTargetHandlerFunc) { - i.targetHandler = f -} - -// DataSourceSendEvent : send the data -// -// Request for data from the client. Send the data as the -// specified mime type over the passed file descriptor, then -// close it. -type DataSourceSendEvent struct { - MimeType string - Fd int -} -type DataSourceSendHandlerFunc func(DataSourceSendEvent) - -// SetSendHandler : sets handler for DataSourceSendEvent -func (i *DataSource) SetSendHandler(f DataSourceSendHandlerFunc) { - i.sendHandler = f -} - -// DataSourceCancelledEvent : selection was cancelled -// -// This data source is no longer valid. There are several reasons why -// this could happen: -// -// - The data source has been replaced by another data source. -// - The drag-and-drop operation was performed, but the drop destination -// did not accept any of the mime types offered through -// wl_data_source.target. -// - The drag-and-drop operation was performed, but the drop destination -// did not select any of the actions present in the mask offered through -// wl_data_source.action. -// - The drag-and-drop operation was performed but didn't happen over a -// surface. -// - The compositor cancelled the drag-and-drop operation (e.g. compositor -// dependent timeouts to avoid stale drag-and-drop transfers). -// -// The client should clean up and destroy this data source. -// -// For objects of version 2 or older, wl_data_source.cancelled will -// only be emitted if the data source was replaced by another data -// source. -type DataSourceCancelledEvent struct{} -type DataSourceCancelledHandlerFunc func(DataSourceCancelledEvent) - -// SetCancelledHandler : sets handler for DataSourceCancelledEvent -func (i *DataSource) SetCancelledHandler(f DataSourceCancelledHandlerFunc) { - i.cancelledHandler = f -} - -// DataSourceDndDropPerformedEvent : the drag-and-drop operation physically finished -// -// The user performed the drop action. This event does not indicate -// acceptance, wl_data_source.cancelled may still be emitted afterwards -// if the drop destination does not accept any mime type. -// -// However, this event might however not be received if the compositor -// cancelled the drag-and-drop operation before this event could happen. -// -// Note that the data_source may still be used in the future and should -// not be destroyed here. -type DataSourceDndDropPerformedEvent struct{} -type DataSourceDndDropPerformedHandlerFunc func(DataSourceDndDropPerformedEvent) - -// SetDndDropPerformedHandler : sets handler for DataSourceDndDropPerformedEvent -func (i *DataSource) SetDndDropPerformedHandler(f DataSourceDndDropPerformedHandlerFunc) { - i.dndDropPerformedHandler = f -} - -// DataSourceDndFinishedEvent : the drag-and-drop operation concluded -// -// The drop destination finished interoperating with this data -// source, so the client is now free to destroy this data source and -// free all associated data. -// -// If the action used to perform the operation was "move", the -// source can now delete the transferred data. -type DataSourceDndFinishedEvent struct{} -type DataSourceDndFinishedHandlerFunc func(DataSourceDndFinishedEvent) - -// SetDndFinishedHandler : sets handler for DataSourceDndFinishedEvent -func (i *DataSource) SetDndFinishedHandler(f DataSourceDndFinishedHandlerFunc) { - i.dndFinishedHandler = f -} - -// DataSourceActionEvent : notify the selected action -// -// This event indicates the action selected by the compositor after -// matching the source/destination side actions. Only one action (or -// none) will be offered here. -// -// This event can be emitted multiple times during the drag-and-drop -// operation, mainly in response to destination side changes through -// wl_data_offer.set_actions, and as the data device enters/leaves -// surfaces. -// -// It is only possible to receive this event after -// wl_data_source.dnd_drop_performed if the drag-and-drop operation -// ended in an "ask" action, in which case the final wl_data_source.action -// event will happen immediately before wl_data_source.dnd_finished. -// -// Compositors may also change the selected action on the fly, mainly -// in response to keyboard modifier changes during the drag-and-drop -// operation. -// -// The most recent action received is always the valid one. The chosen -// action may change alongside negotiation (e.g. an "ask" action can turn -// into a "move" operation), so the effects of the final action must -// always be applied in wl_data_offer.dnd_finished. -// -// Clients can trigger cursor surface changes from this point, so -// they reflect the current action. -type DataSourceActionEvent struct { - DndAction uint32 -} -type DataSourceActionHandlerFunc func(DataSourceActionEvent) - -// SetActionHandler : sets handler for DataSourceActionEvent -func (i *DataSource) SetActionHandler(f DataSourceActionHandlerFunc) { - i.actionHandler = f -} - -func (i *DataSource) Dispatch(opcode uint32, fd int, data []byte) { - switch opcode { - case 0: - if i.targetHandler == nil { - return - } - var e DataSourceTargetEvent - l := 0 - mimeTypeLen := PaddedLen(int(Uint32(data[l : l+4]))) - l += 4 - e.MimeType = String(data[l : l+mimeTypeLen]) - l += mimeTypeLen - - i.targetHandler(e) - case 1: - if i.sendHandler == nil { - if fd != -1 { - unix.Close(fd) - } - return - } - var e DataSourceSendEvent - l := 0 - mimeTypeLen := PaddedLen(int(Uint32(data[l : l+4]))) - l += 4 - e.MimeType = String(data[l : l+mimeTypeLen]) - l += mimeTypeLen - e.Fd = fd - - i.sendHandler(e) - case 2: - if i.cancelledHandler == nil { - return - } - var e DataSourceCancelledEvent - - i.cancelledHandler(e) - case 3: - if i.dndDropPerformedHandler == nil { - return - } - var e DataSourceDndDropPerformedEvent - - i.dndDropPerformedHandler(e) - case 4: - if i.dndFinishedHandler == nil { - return - } - var e DataSourceDndFinishedEvent - - i.dndFinishedHandler(e) - case 5: - if i.actionHandler == nil { - return - } - var e DataSourceActionEvent - l := 0 - e.DndAction = Uint32(data[l : l+4]) - l += 4 - - i.actionHandler(e) - } -} - -// DataDeviceInterfaceName is the name of the interface as it appears in the [client.Registry]. -// It can be used to match the [client.RegistryGlobalEvent.Interface] in the -// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies. -const DataDeviceInterfaceName = "wl_data_device" - -// DataDevice : data transfer device -// -// There is one wl_data_device per seat which can be obtained -// from the global wl_data_device_manager singleton. -// -// A wl_data_device provides access to inter-client data transfer -// mechanisms such as copy-and-paste and drag-and-drop. -type DataDevice struct { - BaseProxy - dataOfferHandler DataDeviceDataOfferHandlerFunc - enterHandler DataDeviceEnterHandlerFunc - leaveHandler DataDeviceLeaveHandlerFunc - motionHandler DataDeviceMotionHandlerFunc - dropHandler DataDeviceDropHandlerFunc - selectionHandler DataDeviceSelectionHandlerFunc -} - -// NewDataDevice : data transfer device -// -// There is one wl_data_device per seat which can be obtained -// from the global wl_data_device_manager singleton. -// -// A wl_data_device provides access to inter-client data transfer -// mechanisms such as copy-and-paste and drag-and-drop. -func NewDataDevice(ctx *Context) *DataDevice { - wlDataDevice := &DataDevice{} - ctx.Register(wlDataDevice) - return wlDataDevice -} - -// StartDrag : start drag-and-drop operation -// -// This request asks the compositor to start a drag-and-drop -// operation on behalf of the client. -// -// The source argument is the data source that provides the data -// for the eventual data transfer. If source is NULL, enter, leave -// and motion events are sent only to the client that initiated the -// drag and the client is expected to handle the data passing -// internally. If source is destroyed, the drag-and-drop session will be -// cancelled. -// -// The origin surface is the surface where the drag originates and -// the client must have an active implicit grab that matches the -// serial. -// -// The icon surface is an optional (can be NULL) surface that -// provides an icon to be moved around with the cursor. Initially, -// the top-left corner of the icon surface is placed at the cursor -// hotspot, but subsequent wl_surface.offset requests can move the -// relative position. Attach requests must be confirmed with -// wl_surface.commit as usual. The icon surface is given the role of -// a drag-and-drop icon. If the icon surface already has another role, -// it raises a protocol error. -// -// The input region is ignored for wl_surfaces with the role of a -// drag-and-drop icon. -// -// The given source may not be used in any further set_selection or -// start_drag requests. Attempting to reuse a previously-used source -// may send a used_source error. -// -// source: data source for the eventual transfer -// origin: surface where the drag originates -// icon: drag-and-drop icon surface -// serial: serial number of the implicit grab on the origin -func (i *DataDevice) StartDrag(source *DataSource, origin, icon *Surface, serial uint32) error { - const opcode = 0 - const _reqBufLen = 8 + 4 + 4 + 4 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - if source == nil { - PutUint32(_reqBuf[l:l+4], 0) - l += 4 - } else { - PutUint32(_reqBuf[l:l+4], source.ID()) - l += 4 - } - PutUint32(_reqBuf[l:l+4], origin.ID()) - l += 4 - if icon == nil { - PutUint32(_reqBuf[l:l+4], 0) - l += 4 - } else { - PutUint32(_reqBuf[l:l+4], icon.ID()) - l += 4 - } - PutUint32(_reqBuf[l:l+4], uint32(serial)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// SetSelection : copy data to the selection -// -// This request asks the compositor to set the selection -// to the data from the source on behalf of the client. -// -// To unset the selection, set the source to NULL. -// -// The given source may not be used in any further set_selection or -// start_drag requests. Attempting to reuse a previously-used source -// may send a used_source error. -// -// source: data source for the selection -// serial: serial number of the event that triggered this request -func (i *DataDevice) SetSelection(source *DataSource, serial uint32) error { - const opcode = 1 - const _reqBufLen = 8 + 4 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - if source == nil { - PutUint32(_reqBuf[l:l+4], 0) - l += 4 - } else { - PutUint32(_reqBuf[l:l+4], source.ID()) - l += 4 - } - PutUint32(_reqBuf[l:l+4], uint32(serial)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// Release : destroy data device -// -// This request destroys the data device. -func (i *DataDevice) Release() error { - defer i.MarkZombie() - const opcode = 2 - const _reqBufLen = 8 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -type DataDeviceError uint32 - -// DataDeviceError : -const ( - // DataDeviceErrorRole : given wl_surface has another role - DataDeviceErrorRole DataDeviceError = 0 - // DataDeviceErrorUsedSource : source has already been used - DataDeviceErrorUsedSource DataDeviceError = 1 -) - -func (e DataDeviceError) Name() string { - switch e { - case DataDeviceErrorRole: - return "role" - case DataDeviceErrorUsedSource: - return "used_source" - default: - return "" - } -} - -func (e DataDeviceError) Value() string { - switch e { - case DataDeviceErrorRole: - return "0" - case DataDeviceErrorUsedSource: - return "1" - default: - return "" - } -} - -func (e DataDeviceError) String() string { - return e.Name() + "=" + e.Value() -} - -// DataDeviceDataOfferEvent : introduce a new wl_data_offer -// -// The data_offer event introduces a new wl_data_offer object, -// which will subsequently be used in either the -// data_device.enter event (for drag-and-drop) or the -// data_device.selection event (for selections). Immediately -// following the data_device.data_offer event, the new data_offer -// object will send out data_offer.offer events to describe the -// mime types it offers. -type DataDeviceDataOfferEvent struct { - Id *DataOffer -} -type DataDeviceDataOfferHandlerFunc func(DataDeviceDataOfferEvent) - -// SetDataOfferHandler : sets handler for DataDeviceDataOfferEvent -func (i *DataDevice) SetDataOfferHandler(f DataDeviceDataOfferHandlerFunc) { - i.dataOfferHandler = f -} - -// DataDeviceEnterEvent : initiate drag-and-drop session -// -// This event is sent when an active drag-and-drop pointer enters -// a surface owned by the client. The position of the pointer at -// enter time is provided by the x and y arguments, in surface-local -// coordinates. -type DataDeviceEnterEvent struct { - Serial uint32 - Surface *Surface - X float64 - Y float64 - Id *DataOffer -} -type DataDeviceEnterHandlerFunc func(DataDeviceEnterEvent) - -// SetEnterHandler : sets handler for DataDeviceEnterEvent -func (i *DataDevice) SetEnterHandler(f DataDeviceEnterHandlerFunc) { - i.enterHandler = f -} - -// DataDeviceLeaveEvent : end drag-and-drop session -// -// This event is sent when the drag-and-drop pointer leaves the -// surface and the session ends. The client must destroy the -// wl_data_offer introduced at enter time at this point. -type DataDeviceLeaveEvent struct{} -type DataDeviceLeaveHandlerFunc func(DataDeviceLeaveEvent) - -// SetLeaveHandler : sets handler for DataDeviceLeaveEvent -func (i *DataDevice) SetLeaveHandler(f DataDeviceLeaveHandlerFunc) { - i.leaveHandler = f -} - -// DataDeviceMotionEvent : drag-and-drop session motion -// -// This event is sent when the drag-and-drop pointer moves within -// the currently focused surface. The new position of the pointer -// is provided by the x and y arguments, in surface-local -// coordinates. -type DataDeviceMotionEvent struct { - Time uint32 - X float64 - Y float64 -} -type DataDeviceMotionHandlerFunc func(DataDeviceMotionEvent) - -// SetMotionHandler : sets handler for DataDeviceMotionEvent -func (i *DataDevice) SetMotionHandler(f DataDeviceMotionHandlerFunc) { - i.motionHandler = f -} - -// DataDeviceDropEvent : end drag-and-drop session successfully -// -// The event is sent when a drag-and-drop operation is ended -// because the implicit grab is removed. -// -// The drag-and-drop destination is expected to honor the last action -// received through wl_data_offer.action, if the resulting action is -// "copy" or "move", the destination can still perform -// wl_data_offer.receive requests, and is expected to end all -// transfers with a wl_data_offer.finish request. -// -// If the resulting action is "ask", the action will not be considered -// final. The drag-and-drop destination is expected to perform one last -// wl_data_offer.set_actions request, or wl_data_offer.destroy in order -// to cancel the operation. -type DataDeviceDropEvent struct{} -type DataDeviceDropHandlerFunc func(DataDeviceDropEvent) - -// SetDropHandler : sets handler for DataDeviceDropEvent -func (i *DataDevice) SetDropHandler(f DataDeviceDropHandlerFunc) { - i.dropHandler = f -} - -// DataDeviceSelectionEvent : advertise new selection -// -// The selection event is sent out to notify the client of a new -// wl_data_offer for the selection for this device. The -// data_device.data_offer and the data_offer.offer events are -// sent out immediately before this event to introduce the data -// offer object. The selection event is sent to a client -// immediately before receiving keyboard focus and when a new -// selection is set while the client has keyboard focus. The -// data_offer is valid until a new data_offer or NULL is received -// or until the client loses keyboard focus. Switching surface with -// keyboard focus within the same client doesn't mean a new selection -// will be sent. The client must destroy the previous selection -// data_offer, if any, upon receiving this event. -type DataDeviceSelectionEvent struct { - Id *DataOffer -} -type DataDeviceSelectionHandlerFunc func(DataDeviceSelectionEvent) - -// SetSelectionHandler : sets handler for DataDeviceSelectionEvent -func (i *DataDevice) SetSelectionHandler(f DataDeviceSelectionHandlerFunc) { - i.selectionHandler = f -} - -func (i *DataDevice) Dispatch(opcode uint32, fd int, data []byte) { - switch opcode { - case 0: - if i.dataOfferHandler == nil { - return - } - var e DataDeviceDataOfferEvent - l := 0 - e.Id = i.Context().GetProxy(Uint32(data[l : l+4])).(*DataOffer) - l += 4 - - i.dataOfferHandler(e) - case 1: - if i.enterHandler == nil { - return - } - var e DataDeviceEnterEvent - l := 0 - e.Serial = Uint32(data[l : l+4]) - l += 4 - e.Surface = i.Context().GetProxy(Uint32(data[l : l+4])).(*Surface) - l += 4 - e.X = Fixed(data[l : l+4]) - l += 4 - e.Y = Fixed(data[l : l+4]) - l += 4 - e.Id = i.Context().GetProxy(Uint32(data[l : l+4])).(*DataOffer) - l += 4 - - i.enterHandler(e) - case 2: - if i.leaveHandler == nil { - return - } - var e DataDeviceLeaveEvent - - i.leaveHandler(e) - case 3: - if i.motionHandler == nil { - return - } - var e DataDeviceMotionEvent - l := 0 - e.Time = Uint32(data[l : l+4]) - l += 4 - e.X = Fixed(data[l : l+4]) - l += 4 - e.Y = Fixed(data[l : l+4]) - l += 4 - - i.motionHandler(e) - case 4: - if i.dropHandler == nil { - return - } - var e DataDeviceDropEvent - - i.dropHandler(e) - case 5: - if i.selectionHandler == nil { - return - } - var e DataDeviceSelectionEvent - l := 0 - e.Id = i.Context().GetProxy(Uint32(data[l : l+4])).(*DataOffer) - l += 4 - - i.selectionHandler(e) - } -} - -// DataDeviceManagerInterfaceName is the name of the interface as it appears in the [client.Registry]. -// It can be used to match the [client.RegistryGlobalEvent.Interface] in the -// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies. -const DataDeviceManagerInterfaceName = "wl_data_device_manager" - -// DataDeviceManager : data transfer interface -// -// The wl_data_device_manager is a singleton global object that -// provides access to inter-client data transfer mechanisms such as -// copy-and-paste and drag-and-drop. These mechanisms are tied to -// a wl_seat and this interface lets a client get a wl_data_device -// corresponding to a wl_seat. -// -// Depending on the version bound, the objects created from the bound -// wl_data_device_manager object will have different requirements for -// functioning properly. See wl_data_source.set_actions, -// wl_data_offer.accept and wl_data_offer.finish for details. -type DataDeviceManager struct { - BaseProxy -} - -// NewDataDeviceManager : data transfer interface -// -// The wl_data_device_manager is a singleton global object that -// provides access to inter-client data transfer mechanisms such as -// copy-and-paste and drag-and-drop. These mechanisms are tied to -// a wl_seat and this interface lets a client get a wl_data_device -// corresponding to a wl_seat. -// -// Depending on the version bound, the objects created from the bound -// wl_data_device_manager object will have different requirements for -// functioning properly. See wl_data_source.set_actions, -// wl_data_offer.accept and wl_data_offer.finish for details. -func NewDataDeviceManager(ctx *Context) *DataDeviceManager { - wlDataDeviceManager := &DataDeviceManager{} - ctx.Register(wlDataDeviceManager) - return wlDataDeviceManager -} - -// CreateDataSource : create a new data source -// -// Create a new data source. -func (i *DataDeviceManager) CreateDataSource() (*DataSource, error) { - id := NewDataSource(i.Context()) - const opcode = 0 - const _reqBufLen = 8 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], id.ID()) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return id, err -} - -// GetDataDevice : create a new data device -// -// Create a new data device for a given seat. -// -// seat: seat associated with the data device -func (i *DataDeviceManager) GetDataDevice(seat *Seat) (*DataDevice, error) { - id := NewDataDevice(i.Context()) - const opcode = 1 - const _reqBufLen = 8 + 4 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], id.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], seat.ID()) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return id, err -} - -func (i *DataDeviceManager) Destroy() error { - i.MarkZombie() - return nil -} - -type DataDeviceManagerDndAction uint32 - -// DataDeviceManagerDndAction : drag and drop actions -// -// This is a bitmask of the available/preferred actions in a -// drag-and-drop operation. -// -// In the compositor, the selected action is a result of matching the -// actions offered by the source and destination sides. "action" events -// with a "none" action will be sent to both source and destination if -// there is no match. All further checks will effectively happen on -// (source actions ∩ destination actions). -// -// In addition, compositors may also pick different actions in -// reaction to key modifiers being pressed. One common design that -// is used in major toolkits (and the behavior recommended for -// compositors) is: -// -// - If no modifiers are pressed, the first match (in bit order) -// will be used. -// - Pressing Shift selects "move", if enabled in the mask. -// - Pressing Control selects "copy", if enabled in the mask. -// -// Behavior beyond that is considered implementation-dependent. -// Compositors may for example bind other modifiers (like Alt/Meta) -// or drags initiated with other buttons than BTN_LEFT to specific -// actions (e.g. "ask"). -const ( - // DataDeviceManagerDndActionNone : no action - DataDeviceManagerDndActionNone DataDeviceManagerDndAction = 0 - // DataDeviceManagerDndActionCopy : copy action - DataDeviceManagerDndActionCopy DataDeviceManagerDndAction = 1 - // DataDeviceManagerDndActionMove : move action - DataDeviceManagerDndActionMove DataDeviceManagerDndAction = 2 - // DataDeviceManagerDndActionAsk : ask action - DataDeviceManagerDndActionAsk DataDeviceManagerDndAction = 4 -) - -func (e DataDeviceManagerDndAction) Name() string { - switch e { - case DataDeviceManagerDndActionNone: - return "none" - case DataDeviceManagerDndActionCopy: - return "copy" - case DataDeviceManagerDndActionMove: - return "move" - case DataDeviceManagerDndActionAsk: - return "ask" - default: - return "" - } -} - -func (e DataDeviceManagerDndAction) Value() string { - switch e { - case DataDeviceManagerDndActionNone: - return "0" - case DataDeviceManagerDndActionCopy: - return "1" - case DataDeviceManagerDndActionMove: - return "2" - case DataDeviceManagerDndActionAsk: - return "4" - default: - return "" - } -} - -func (e DataDeviceManagerDndAction) String() string { - return e.Name() + "=" + e.Value() -} - -// ShellInterfaceName is the name of the interface as it appears in the [client.Registry]. -// It can be used to match the [client.RegistryGlobalEvent.Interface] in the -// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies. -const ShellInterfaceName = "wl_shell" - -// Shell : create desktop-style surfaces -// -// This interface is implemented by servers that provide -// desktop-style user interfaces. -// -// It allows clients to associate a wl_shell_surface with -// a basic surface. -// -// Note! This protocol is deprecated and not intended for production use. -// For desktop-style user interfaces, use xdg_shell. Compositors and clients -// should not implement this interface. -type Shell struct { - BaseProxy -} - -// NewShell : create desktop-style surfaces -// -// This interface is implemented by servers that provide -// desktop-style user interfaces. -// -// It allows clients to associate a wl_shell_surface with -// a basic surface. -// -// Note! This protocol is deprecated and not intended for production use. -// For desktop-style user interfaces, use xdg_shell. Compositors and clients -// should not implement this interface. -func NewShell(ctx *Context) *Shell { - wlShell := &Shell{} - ctx.Register(wlShell) - return wlShell -} - -// GetShellSurface : create a shell surface from a surface -// -// Create a shell surface for an existing surface. This gives -// the wl_surface the role of a shell surface. If the wl_surface -// already has another role, it raises a protocol error. -// -// Only one shell surface can be associated with a given surface. -// -// surface: surface to be given the shell surface role -func (i *Shell) GetShellSurface(surface *Surface) (*ShellSurface, error) { - id := NewShellSurface(i.Context()) - const opcode = 0 - const _reqBufLen = 8 + 4 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], id.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], surface.ID()) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return id, err -} - -func (i *Shell) Destroy() error { - i.MarkZombie() - return nil -} - -type ShellError uint32 - -// ShellError : -const ( - // ShellErrorRole : given wl_surface has another role - ShellErrorRole ShellError = 0 -) - -func (e ShellError) Name() string { - switch e { - case ShellErrorRole: - return "role" - default: - return "" - } -} - -func (e ShellError) Value() string { - switch e { - case ShellErrorRole: - return "0" - default: - return "" - } -} - -func (e ShellError) String() string { - return e.Name() + "=" + e.Value() -} - -// ShellSurfaceInterfaceName is the name of the interface as it appears in the [client.Registry]. -// It can be used to match the [client.RegistryGlobalEvent.Interface] in the -// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies. -const ShellSurfaceInterfaceName = "wl_shell_surface" - -// ShellSurface : desktop-style metadata interface -// -// An interface that may be implemented by a wl_surface, for -// implementations that provide a desktop-style user interface. -// -// It provides requests to treat surfaces like toplevel, fullscreen -// or popup windows, move, resize or maximize them, associate -// metadata like title and class, etc. -// -// On the server side the object is automatically destroyed when -// the related wl_surface is destroyed. On the client side, -// wl_shell_surface_destroy() must be called before destroying -// the wl_surface object. -type ShellSurface struct { - BaseProxy - pingHandler ShellSurfacePingHandlerFunc - configureHandler ShellSurfaceConfigureHandlerFunc - popupDoneHandler ShellSurfacePopupDoneHandlerFunc -} - -// NewShellSurface : desktop-style metadata interface -// -// An interface that may be implemented by a wl_surface, for -// implementations that provide a desktop-style user interface. -// -// It provides requests to treat surfaces like toplevel, fullscreen -// or popup windows, move, resize or maximize them, associate -// metadata like title and class, etc. -// -// On the server side the object is automatically destroyed when -// the related wl_surface is destroyed. On the client side, -// wl_shell_surface_destroy() must be called before destroying -// the wl_surface object. -func NewShellSurface(ctx *Context) *ShellSurface { - wlShellSurface := &ShellSurface{} - ctx.Register(wlShellSurface) - return wlShellSurface -} - -// Pong : respond to a ping event -// -// A client must respond to a ping event with a pong request or -// the client may be deemed unresponsive. -// -// serial: serial number of the ping event -func (i *ShellSurface) Pong(serial uint32) error { - const opcode = 0 - const _reqBufLen = 8 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(serial)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// Move : start an interactive move -// -// Start a pointer-driven move of the surface. -// -// This request must be used in response to a button press event. -// The server may ignore move requests depending on the state of -// the surface (e.g. fullscreen or maximized). -// -// seat: seat whose pointer is used -// serial: serial number of the implicit grab on the pointer -func (i *ShellSurface) Move(seat *Seat, serial uint32) error { - const opcode = 1 - const _reqBufLen = 8 + 4 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], seat.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(serial)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// Resize : start an interactive resize -// -// Start a pointer-driven resizing of the surface. -// -// This request must be used in response to a button press event. -// The server may ignore resize requests depending on the state of -// the surface (e.g. fullscreen or maximized). -// -// seat: seat whose pointer is used -// serial: serial number of the implicit grab on the pointer -// edges: which edge or corner is being dragged -func (i *ShellSurface) Resize(seat *Seat, serial, edges uint32) error { - const opcode = 2 - const _reqBufLen = 8 + 4 + 4 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], seat.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(serial)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(edges)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// SetToplevel : make the surface a toplevel surface -// -// Map the surface as a toplevel surface. -// -// A toplevel surface is not fullscreen, maximized or transient. -func (i *ShellSurface) SetToplevel() error { - const opcode = 3 - const _reqBufLen = 8 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// SetTransient : make the surface a transient surface -// -// Map the surface relative to an existing surface. -// -// The x and y arguments specify the location of the upper left -// corner of the surface relative to the upper left corner of the -// parent surface, in surface-local coordinates. -// -// The flags argument controls details of the transient behaviour. -// -// parent: parent surface -// x: surface-local x coordinate -// y: surface-local y coordinate -// flags: transient surface behavior -func (i *ShellSurface) SetTransient(parent *Surface, x, y int32, flags uint32) error { - const opcode = 4 - const _reqBufLen = 8 + 4 + 4 + 4 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], parent.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(x)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(y)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(flags)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// SetFullscreen : make the surface a fullscreen surface -// -// Map the surface as a fullscreen surface. -// -// If an output parameter is given then the surface will be made -// fullscreen on that output. If the client does not specify the -// output then the compositor will apply its policy - usually -// choosing the output on which the surface has the biggest surface -// area. -// -// The client may specify a method to resolve a size conflict -// between the output size and the surface size - this is provided -// through the method parameter. -// -// The framerate parameter is used only when the method is set -// to "driver", to indicate the preferred framerate. A value of 0 -// indicates that the client does not care about framerate. The -// framerate is specified in mHz, that is framerate of 60000 is 60Hz. -// -// A method of "scale" or "driver" implies a scaling operation of -// the surface, either via a direct scaling operation or a change of -// the output mode. This will override any kind of output scaling, so -// that mapping a surface with a buffer size equal to the mode can -// fill the screen independent of buffer_scale. -// -// A method of "fill" means we don't scale up the buffer, however -// any output scale is applied. This means that you may run into -// an edge case where the application maps a buffer with the same -// size of the output mode but buffer_scale 1 (thus making a -// surface larger than the output). In this case it is allowed to -// downscale the results to fit the screen. -// -// The compositor must reply to this request with a configure event -// with the dimensions for the output on which the surface will -// be made fullscreen. -// -// method: method for resolving size conflict -// framerate: framerate in mHz -// output: output on which the surface is to be fullscreen -func (i *ShellSurface) SetFullscreen(method, framerate uint32, output *Output) error { - const opcode = 5 - const _reqBufLen = 8 + 4 + 4 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(method)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(framerate)) - l += 4 - if output == nil { - PutUint32(_reqBuf[l:l+4], 0) - l += 4 - } else { - PutUint32(_reqBuf[l:l+4], output.ID()) - l += 4 - } - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// SetPopup : make the surface a popup surface -// -// Map the surface as a popup. -// -// A popup surface is a transient surface with an added pointer -// grab. -// -// An existing implicit grab will be changed to owner-events mode, -// and the popup grab will continue after the implicit grab ends -// (i.e. releasing the mouse button does not cause the popup to -// be unmapped). -// -// The popup grab continues until the window is destroyed or a -// mouse button is pressed in any other client's window. A click -// in any of the client's surfaces is reported as normal, however, -// clicks in other clients' surfaces will be discarded and trigger -// the callback. -// -// The x and y arguments specify the location of the upper left -// corner of the surface relative to the upper left corner of the -// parent surface, in surface-local coordinates. -// -// seat: seat whose pointer is used -// serial: serial number of the implicit grab on the pointer -// parent: parent surface -// x: surface-local x coordinate -// y: surface-local y coordinate -// flags: transient surface behavior -func (i *ShellSurface) SetPopup(seat *Seat, serial uint32, parent *Surface, x, y int32, flags uint32) error { - const opcode = 6 - const _reqBufLen = 8 + 4 + 4 + 4 + 4 + 4 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], seat.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(serial)) - l += 4 - PutUint32(_reqBuf[l:l+4], parent.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(x)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(y)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(flags)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// SetMaximized : make the surface a maximized surface -// -// Map the surface as a maximized surface. -// -// If an output parameter is given then the surface will be -// maximized on that output. If the client does not specify the -// output then the compositor will apply its policy - usually -// choosing the output on which the surface has the biggest surface -// area. -// -// The compositor will reply with a configure event telling -// the expected new surface size. The operation is completed -// on the next buffer attach to this surface. -// -// A maximized surface typically fills the entire output it is -// bound to, except for desktop elements such as panels. This is -// the main difference between a maximized shell surface and a -// fullscreen shell surface. -// -// The details depend on the compositor implementation. -// -// output: output on which the surface is to be maximized -func (i *ShellSurface) SetMaximized(output *Output) error { - const opcode = 7 - const _reqBufLen = 8 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - if output == nil { - PutUint32(_reqBuf[l:l+4], 0) - l += 4 - } else { - PutUint32(_reqBuf[l:l+4], output.ID()) - l += 4 - } - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// SetTitle : set surface title -// -// Set a short title for the surface. -// -// This string may be used to identify the surface in a task bar, -// window list, or other user interface elements provided by the -// compositor. -// -// The string must be encoded in UTF-8. -// -// title: surface title -func (i *ShellSurface) SetTitle(title string) error { - const opcode = 8 - titleLen := PaddedLen(len(title) + 1) - _reqBufLen := 8 + (4 + titleLen) - _reqBuf := make([]byte, _reqBufLen) - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutString(_reqBuf[l:l+(4+titleLen)], title) - l += (4 + titleLen) - err := i.Context().WriteMsg(_reqBuf, nil) - return err -} - -// SetClass : set surface class -// -// Set a class for the surface. -// -// The surface class identifies the general class of applications -// to which the surface belongs. A common convention is to use the -// file name (or the full path if it is a non-standard location) of -// the application's .desktop file as the class. -// -// class: surface class -func (i *ShellSurface) SetClass(class string) error { - const opcode = 9 - classLen := PaddedLen(len(class) + 1) - _reqBufLen := 8 + (4 + classLen) - _reqBuf := make([]byte, _reqBufLen) - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutString(_reqBuf[l:l+(4+classLen)], class) - l += (4 + classLen) - err := i.Context().WriteMsg(_reqBuf, nil) - return err -} - -func (i *ShellSurface) Destroy() error { - i.MarkZombie() - return nil -} - -type ShellSurfaceResize uint32 - -// ShellSurfaceResize : edge values for resizing -// -// These values are used to indicate which edge of a surface -// is being dragged in a resize operation. The server may -// use this information to adapt its behavior, e.g. choose -// an appropriate cursor image. -const ( - // ShellSurfaceResizeNone : no edge - ShellSurfaceResizeNone ShellSurfaceResize = 0 - // ShellSurfaceResizeTop : top edge - ShellSurfaceResizeTop ShellSurfaceResize = 1 - // ShellSurfaceResizeBottom : bottom edge - ShellSurfaceResizeBottom ShellSurfaceResize = 2 - // ShellSurfaceResizeLeft : left edge - ShellSurfaceResizeLeft ShellSurfaceResize = 4 - // ShellSurfaceResizeTopLeft : top and left edges - ShellSurfaceResizeTopLeft ShellSurfaceResize = 5 - // ShellSurfaceResizeBottomLeft : bottom and left edges - ShellSurfaceResizeBottomLeft ShellSurfaceResize = 6 - // ShellSurfaceResizeRight : right edge - ShellSurfaceResizeRight ShellSurfaceResize = 8 - // ShellSurfaceResizeTopRight : top and right edges - ShellSurfaceResizeTopRight ShellSurfaceResize = 9 - // ShellSurfaceResizeBottomRight : bottom and right edges - ShellSurfaceResizeBottomRight ShellSurfaceResize = 10 -) - -func (e ShellSurfaceResize) Name() string { - switch e { - case ShellSurfaceResizeNone: - return "none" - case ShellSurfaceResizeTop: - return "top" - case ShellSurfaceResizeBottom: - return "bottom" - case ShellSurfaceResizeLeft: - return "left" - case ShellSurfaceResizeTopLeft: - return "top_left" - case ShellSurfaceResizeBottomLeft: - return "bottom_left" - case ShellSurfaceResizeRight: - return "right" - case ShellSurfaceResizeTopRight: - return "top_right" - case ShellSurfaceResizeBottomRight: - return "bottom_right" - default: - return "" - } -} - -func (e ShellSurfaceResize) Value() string { - switch e { - case ShellSurfaceResizeNone: - return "0" - case ShellSurfaceResizeTop: - return "1" - case ShellSurfaceResizeBottom: - return "2" - case ShellSurfaceResizeLeft: - return "4" - case ShellSurfaceResizeTopLeft: - return "5" - case ShellSurfaceResizeBottomLeft: - return "6" - case ShellSurfaceResizeRight: - return "8" - case ShellSurfaceResizeTopRight: - return "9" - case ShellSurfaceResizeBottomRight: - return "10" - default: - return "" - } -} - -func (e ShellSurfaceResize) String() string { - return e.Name() + "=" + e.Value() -} - -type ShellSurfaceTransient uint32 - -// ShellSurfaceTransient : details of transient behaviour -// -// These flags specify details of the expected behaviour -// of transient surfaces. Used in the set_transient request. -const ( - // ShellSurfaceTransientInactive : do not set keyboard focus - ShellSurfaceTransientInactive ShellSurfaceTransient = 0x1 -) - -func (e ShellSurfaceTransient) Name() string { - switch e { - case ShellSurfaceTransientInactive: - return "inactive" - default: - return "" - } -} - -func (e ShellSurfaceTransient) Value() string { - switch e { - case ShellSurfaceTransientInactive: - return "0x1" - default: - return "" - } -} - -func (e ShellSurfaceTransient) String() string { - return e.Name() + "=" + e.Value() -} - -type ShellSurfaceFullscreenMethod uint32 - -// ShellSurfaceFullscreenMethod : different method to set the surface fullscreen -// -// Hints to indicate to the compositor how to deal with a conflict -// between the dimensions of the surface and the dimensions of the -// output. The compositor is free to ignore this parameter. -const ( - // ShellSurfaceFullscreenMethodDefault : no preference, apply default policy - ShellSurfaceFullscreenMethodDefault ShellSurfaceFullscreenMethod = 0 - // ShellSurfaceFullscreenMethodScale : scale, preserve the surface's aspect ratio and center on output - ShellSurfaceFullscreenMethodScale ShellSurfaceFullscreenMethod = 1 - // ShellSurfaceFullscreenMethodDriver : switch output mode to the smallest mode that can fit the surface, add black borders to compensate size mismatch - ShellSurfaceFullscreenMethodDriver ShellSurfaceFullscreenMethod = 2 - // ShellSurfaceFullscreenMethodFill : no upscaling, center on output and add black borders to compensate size mismatch - ShellSurfaceFullscreenMethodFill ShellSurfaceFullscreenMethod = 3 -) - -func (e ShellSurfaceFullscreenMethod) Name() string { - switch e { - case ShellSurfaceFullscreenMethodDefault: - return "default" - case ShellSurfaceFullscreenMethodScale: - return "scale" - case ShellSurfaceFullscreenMethodDriver: - return "driver" - case ShellSurfaceFullscreenMethodFill: - return "fill" - default: - return "" - } -} - -func (e ShellSurfaceFullscreenMethod) Value() string { - switch e { - case ShellSurfaceFullscreenMethodDefault: - return "0" - case ShellSurfaceFullscreenMethodScale: - return "1" - case ShellSurfaceFullscreenMethodDriver: - return "2" - case ShellSurfaceFullscreenMethodFill: - return "3" - default: - return "" - } -} - -func (e ShellSurfaceFullscreenMethod) String() string { - return e.Name() + "=" + e.Value() -} - -// ShellSurfacePingEvent : ping client -// -// Ping a client to check if it is receiving events and sending -// requests. A client is expected to reply with a pong request. -type ShellSurfacePingEvent struct { - Serial uint32 -} -type ShellSurfacePingHandlerFunc func(ShellSurfacePingEvent) - -// SetPingHandler : sets handler for ShellSurfacePingEvent -func (i *ShellSurface) SetPingHandler(f ShellSurfacePingHandlerFunc) { - i.pingHandler = f -} - -// ShellSurfaceConfigureEvent : suggest resize -// -// The configure event asks the client to resize its surface. -// -// The size is a hint, in the sense that the client is free to -// ignore it if it doesn't resize, pick a smaller size (to -// satisfy aspect ratio or resize in steps of NxM pixels). -// -// The edges parameter provides a hint about how the surface -// was resized. The client may use this information to decide -// how to adjust its content to the new size (e.g. a scrolling -// area might adjust its content position to leave the viewable -// content unmoved). -// -// The client is free to dismiss all but the last configure -// event it received. -// -// The width and height arguments specify the size of the window -// in surface-local coordinates. -type ShellSurfaceConfigureEvent struct { - Edges uint32 - Width int32 - Height int32 -} -type ShellSurfaceConfigureHandlerFunc func(ShellSurfaceConfigureEvent) - -// SetConfigureHandler : sets handler for ShellSurfaceConfigureEvent -func (i *ShellSurface) SetConfigureHandler(f ShellSurfaceConfigureHandlerFunc) { - i.configureHandler = f -} - -// ShellSurfacePopupDoneEvent : popup interaction is done -// -// The popup_done event is sent out when a popup grab is broken, -// that is, when the user clicks a surface that doesn't belong -// to the client owning the popup surface. -type ShellSurfacePopupDoneEvent struct{} -type ShellSurfacePopupDoneHandlerFunc func(ShellSurfacePopupDoneEvent) - -// SetPopupDoneHandler : sets handler for ShellSurfacePopupDoneEvent -func (i *ShellSurface) SetPopupDoneHandler(f ShellSurfacePopupDoneHandlerFunc) { - i.popupDoneHandler = f -} - -func (i *ShellSurface) Dispatch(opcode uint32, fd int, data []byte) { - switch opcode { - case 0: - if i.pingHandler == nil { - return - } - var e ShellSurfacePingEvent - l := 0 - e.Serial = Uint32(data[l : l+4]) - l += 4 - - i.pingHandler(e) - case 1: - if i.configureHandler == nil { - return - } - var e ShellSurfaceConfigureEvent - l := 0 - e.Edges = Uint32(data[l : l+4]) - l += 4 - e.Width = int32(Uint32(data[l : l+4])) - l += 4 - e.Height = int32(Uint32(data[l : l+4])) - l += 4 - - i.configureHandler(e) - case 2: - if i.popupDoneHandler == nil { - return - } - var e ShellSurfacePopupDoneEvent - - i.popupDoneHandler(e) - } -} - -// SurfaceInterfaceName is the name of the interface as it appears in the [client.Registry]. -// It can be used to match the [client.RegistryGlobalEvent.Interface] in the -// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies. -const SurfaceInterfaceName = "wl_surface" - -// Surface : an onscreen surface -// -// A surface is a rectangular area that may be displayed on zero -// or more outputs, and shown any number of times at the compositor's -// discretion. They can present wl_buffers, receive user input, and -// define a local coordinate system. -// -// The size of a surface (and relative positions on it) is described -// in surface-local coordinates, which may differ from the buffer -// coordinates of the pixel content, in case a buffer_transform -// or a buffer_scale is used. -// -// A surface without a "role" is fairly useless: a compositor does -// not know where, when or how to present it. The role is the -// purpose of a wl_surface. Examples of roles are a cursor for a -// pointer (as set by wl_pointer.set_cursor), a drag icon -// (wl_data_device.start_drag), a sub-surface -// (wl_subcompositor.get_subsurface), and a window as defined by a -// shell protocol (e.g. wl_shell.get_shell_surface). -// -// A surface can have only one role at a time. Initially a -// wl_surface does not have a role. Once a wl_surface is given a -// role, it is set permanently for the whole lifetime of the -// wl_surface object. Giving the current role again is allowed, -// unless explicitly forbidden by the relevant interface -// specification. -// -// Surface roles are given by requests in other interfaces such as -// wl_pointer.set_cursor. The request should explicitly mention -// that this request gives a role to a wl_surface. Often, this -// request also creates a new protocol object that represents the -// role and adds additional functionality to wl_surface. When a -// client wants to destroy a wl_surface, they must destroy this role -// object before the wl_surface, otherwise a defunct_role_object error is -// sent. -// -// Destroying the role object does not remove the role from the -// wl_surface, but it may stop the wl_surface from "playing the role". -// For instance, if a wl_subsurface object is destroyed, the wl_surface -// it was created for will be unmapped and forget its position and -// z-order. It is allowed to create a wl_subsurface for the same -// wl_surface again, but it is not allowed to use the wl_surface as -// a cursor (cursor is a different role than sub-surface, and role -// switching is not allowed). -type Surface struct { - BaseProxy - enterHandler SurfaceEnterHandlerFunc - leaveHandler SurfaceLeaveHandlerFunc - preferredBufferScaleHandler SurfacePreferredBufferScaleHandlerFunc - preferredBufferTransformHandler SurfacePreferredBufferTransformHandlerFunc -} - -// NewSurface : an onscreen surface -// -// A surface is a rectangular area that may be displayed on zero -// or more outputs, and shown any number of times at the compositor's -// discretion. They can present wl_buffers, receive user input, and -// define a local coordinate system. -// -// The size of a surface (and relative positions on it) is described -// in surface-local coordinates, which may differ from the buffer -// coordinates of the pixel content, in case a buffer_transform -// or a buffer_scale is used. -// -// A surface without a "role" is fairly useless: a compositor does -// not know where, when or how to present it. The role is the -// purpose of a wl_surface. Examples of roles are a cursor for a -// pointer (as set by wl_pointer.set_cursor), a drag icon -// (wl_data_device.start_drag), a sub-surface -// (wl_subcompositor.get_subsurface), and a window as defined by a -// shell protocol (e.g. wl_shell.get_shell_surface). -// -// A surface can have only one role at a time. Initially a -// wl_surface does not have a role. Once a wl_surface is given a -// role, it is set permanently for the whole lifetime of the -// wl_surface object. Giving the current role again is allowed, -// unless explicitly forbidden by the relevant interface -// specification. -// -// Surface roles are given by requests in other interfaces such as -// wl_pointer.set_cursor. The request should explicitly mention -// that this request gives a role to a wl_surface. Often, this -// request also creates a new protocol object that represents the -// role and adds additional functionality to wl_surface. When a -// client wants to destroy a wl_surface, they must destroy this role -// object before the wl_surface, otherwise a defunct_role_object error is -// sent. -// -// Destroying the role object does not remove the role from the -// wl_surface, but it may stop the wl_surface from "playing the role". -// For instance, if a wl_subsurface object is destroyed, the wl_surface -// it was created for will be unmapped and forget its position and -// z-order. It is allowed to create a wl_subsurface for the same -// wl_surface again, but it is not allowed to use the wl_surface as -// a cursor (cursor is a different role than sub-surface, and role -// switching is not allowed). -func NewSurface(ctx *Context) *Surface { - wlSurface := &Surface{} - ctx.Register(wlSurface) - return wlSurface -} - -// Destroy : delete surface -// -// Deletes the surface and invalidates its object ID. -func (i *Surface) Destroy() error { - defer i.MarkZombie() - const opcode = 0 - const _reqBufLen = 8 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// Attach : set the surface contents -// -// Set a buffer as the content of this surface. -// -// The new size of the surface is calculated based on the buffer -// size transformed by the inverse buffer_transform and the -// inverse buffer_scale. This means that at commit time the supplied -// buffer size must be an integer multiple of the buffer_scale. If -// that's not the case, an invalid_size error is sent. -// -// The x and y arguments specify the location of the new pending -// buffer's upper left corner, relative to the current buffer's upper -// left corner, in surface-local coordinates. In other words, the -// x and y, combined with the new surface size define in which -// directions the surface's size changes. Setting anything other than 0 -// as x and y arguments is discouraged, and should instead be replaced -// with using the separate wl_surface.offset request. -// -// When the bound wl_surface version is 5 or higher, passing any -// non-zero x or y is a protocol violation, and will result in an -// 'invalid_offset' error being raised. The x and y arguments are ignored -// and do not change the pending state. To achieve equivalent semantics, -// use wl_surface.offset. -// -// Surface contents are double-buffered state, see wl_surface.commit. -// -// The initial surface contents are void; there is no content. -// wl_surface.attach assigns the given wl_buffer as the pending -// wl_buffer. wl_surface.commit makes the pending wl_buffer the new -// surface contents, and the size of the surface becomes the size -// calculated from the wl_buffer, as described above. After commit, -// there is no pending buffer until the next attach. -// -// Committing a pending wl_buffer allows the compositor to read the -// pixels in the wl_buffer. The compositor may access the pixels at -// any time after the wl_surface.commit request. When the compositor -// will not access the pixels anymore, it will send the -// wl_buffer.release event. Only after receiving wl_buffer.release, -// the client may reuse the wl_buffer. A wl_buffer that has been -// attached and then replaced by another attach instead of committed -// will not receive a release event, and is not used by the -// compositor. -// -// If a pending wl_buffer has been committed to more than one wl_surface, -// the delivery of wl_buffer.release events becomes undefined. A well -// behaved client should not rely on wl_buffer.release events in this -// case. Alternatively, a client could create multiple wl_buffer objects -// from the same backing storage or use a protocol extension providing -// per-commit release notifications. -// -// Destroying the wl_buffer after wl_buffer.release does not change -// the surface contents. Destroying the wl_buffer before wl_buffer.release -// is allowed as long as the underlying buffer storage isn't re-used (this -// can happen e.g. on client process termination). However, if the client -// destroys the wl_buffer before receiving the wl_buffer.release event and -// mutates the underlying buffer storage, the surface contents become -// undefined immediately. -// -// If wl_surface.attach is sent with a NULL wl_buffer, the -// following wl_surface.commit will remove the surface content. -// -// If a pending wl_buffer has been destroyed, the result is not specified. -// Many compositors are known to remove the surface content on the following -// wl_surface.commit, but this behaviour is not universal. Clients seeking to -// maximise compatibility should not destroy pending buffers and should -// ensure that they explicitly remove content from surfaces, even after -// destroying buffers. -// -// buffer: buffer of surface contents -// x: surface-local x coordinate -// y: surface-local y coordinate -func (i *Surface) Attach(buffer *Buffer, x, y int32) error { - const opcode = 1 - const _reqBufLen = 8 + 4 + 4 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - if buffer == nil { - PutUint32(_reqBuf[l:l+4], 0) - l += 4 - } else { - PutUint32(_reqBuf[l:l+4], buffer.ID()) - l += 4 - } - PutUint32(_reqBuf[l:l+4], uint32(x)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(y)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// Damage : mark part of the surface damaged -// -// This request is used to describe the regions where the pending -// buffer is different from the current surface contents, and where -// the surface therefore needs to be repainted. The compositor -// ignores the parts of the damage that fall outside of the surface. -// -// Damage is double-buffered state, see wl_surface.commit. -// -// The damage rectangle is specified in surface-local coordinates, -// where x and y specify the upper left corner of the damage rectangle. -// -// The initial value for pending damage is empty: no damage. -// wl_surface.damage adds pending damage: the new pending damage -// is the union of old pending damage and the given rectangle. -// -// wl_surface.commit assigns pending damage as the current damage, -// and clears pending damage. The server will clear the current -// damage as it repaints the surface. -// -// Note! New clients should not use this request. Instead damage can be -// posted with wl_surface.damage_buffer which uses buffer coordinates -// instead of surface coordinates. -// -// x: surface-local x coordinate -// y: surface-local y coordinate -// width: width of damage rectangle -// height: height of damage rectangle -func (i *Surface) Damage(x, y, width, height int32) error { - const opcode = 2 - const _reqBufLen = 8 + 4 + 4 + 4 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(x)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(y)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(width)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(height)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// Frame : request a frame throttling hint -// -// Request a notification when it is a good time to start drawing a new -// frame, by creating a frame callback. This is useful for throttling -// redrawing operations, and driving animations. -// -// When a client is animating on a wl_surface, it can use the 'frame' -// request to get notified when it is a good time to draw and commit the -// next frame of animation. If the client commits an update earlier than -// that, it is likely that some updates will not make it to the display, -// and the client is wasting resources by drawing too often. -// -// The frame request will take effect on the next wl_surface.commit. -// The notification will only be posted for one frame unless -// requested again. For a wl_surface, the notifications are posted in -// the order the frame requests were committed. -// -// The server must send the notifications so that a client -// will not send excessive updates, while still allowing -// the highest possible update rate for clients that wait for the reply -// before drawing again. The server should give some time for the client -// to draw and commit after sending the frame callback events to let it -// hit the next output refresh. -// -// A server should avoid signaling the frame callbacks if the -// surface is not visible in any way, e.g. the surface is off-screen, -// or completely obscured by other opaque surfaces. -// -// The object returned by this request will be destroyed by the -// compositor after the callback is fired and as such the client must not -// attempt to use it after that point. -// -// The callback_data passed in the callback is the current time, in -// milliseconds, with an undefined base. -func (i *Surface) Frame() (*Callback, error) { - callback := NewCallback(i.Context()) - const opcode = 3 - const _reqBufLen = 8 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], callback.ID()) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return callback, err -} - -// SetOpaqueRegion : set opaque region -// -// This request sets the region of the surface that contains -// opaque content. -// -// The opaque region is an optimization hint for the compositor -// that lets it optimize the redrawing of content behind opaque -// regions. Setting an opaque region is not required for correct -// behaviour, but marking transparent content as opaque will result -// in repaint artifacts. -// -// The opaque region is specified in surface-local coordinates. -// -// The compositor ignores the parts of the opaque region that fall -// outside of the surface. -// -// Opaque region is double-buffered state, see wl_surface.commit. -// -// wl_surface.set_opaque_region changes the pending opaque region. -// wl_surface.commit copies the pending region to the current region. -// Otherwise, the pending and current regions are never changed. -// -// The initial value for an opaque region is empty. Setting the pending -// opaque region has copy semantics, and the wl_region object can be -// destroyed immediately. A NULL wl_region causes the pending opaque -// region to be set to empty. -// -// region: opaque region of the surface -func (i *Surface) SetOpaqueRegion(region *Region) error { - const opcode = 4 - const _reqBufLen = 8 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - if region == nil { - PutUint32(_reqBuf[l:l+4], 0) - l += 4 - } else { - PutUint32(_reqBuf[l:l+4], region.ID()) - l += 4 - } - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// SetInputRegion : set input region -// -// This request sets the region of the surface that can receive -// pointer and touch events. -// -// Input events happening outside of this region will try the next -// surface in the server surface stack. The compositor ignores the -// parts of the input region that fall outside of the surface. -// -// The input region is specified in surface-local coordinates. -// -// Input region is double-buffered state, see wl_surface.commit. -// -// wl_surface.set_input_region changes the pending input region. -// wl_surface.commit copies the pending region to the current region. -// Otherwise the pending and current regions are never changed, -// except cursor and icon surfaces are special cases, see -// wl_pointer.set_cursor and wl_data_device.start_drag. -// -// The initial value for an input region is infinite. That means the -// whole surface will accept input. Setting the pending input region -// has copy semantics, and the wl_region object can be destroyed -// immediately. A NULL wl_region causes the input region to be set -// to infinite. -// -// region: input region of the surface -func (i *Surface) SetInputRegion(region *Region) error { - const opcode = 5 - const _reqBufLen = 8 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - if region == nil { - PutUint32(_reqBuf[l:l+4], 0) - l += 4 - } else { - PutUint32(_reqBuf[l:l+4], region.ID()) - l += 4 - } - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// Commit : commit pending surface state -// -// Surface state (input, opaque, and damage regions, attached buffers, -// etc.) is double-buffered. Protocol requests modify the pending state, -// as opposed to the active state in use by the compositor. -// -// A commit request atomically creates a content update from the pending -// state, even if the pending state has not been touched. The content -// update is placed in a queue until it becomes active. After commit, the -// new pending state is as documented for each related request. -// -// When the content update is applied, the wl_buffer is applied before all -// other state. This means that all coordinates in double-buffered state -// are relative to the newly attached wl_buffers, except for -// wl_surface.attach itself. If there is no newly attached wl_buffer, the -// coordinates are relative to the previous content update. -// -// All requests that need a commit to become effective are documented -// to affect double-buffered state. -// -// Other interfaces may add further double-buffered surface state. -func (i *Surface) Commit() error { - const opcode = 6 - const _reqBufLen = 8 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// SetBufferTransform : sets the buffer transformation -// -// This request sets the transformation that the client has already applied -// to the content of the buffer. The accepted values for the transform -// parameter are the values for wl_output.transform. -// -// The compositor applies the inverse of this transformation whenever it -// uses the buffer contents. -// -// Buffer transform is double-buffered state, see wl_surface.commit. -// -// A newly created surface has its buffer transformation set to normal. -// -// wl_surface.set_buffer_transform changes the pending buffer -// transformation. wl_surface.commit copies the pending buffer -// transformation to the current one. Otherwise, the pending and current -// values are never changed. -// -// The purpose of this request is to allow clients to render content -// according to the output transform, thus permitting the compositor to -// use certain optimizations even if the display is rotated. Using -// hardware overlays and scanning out a client buffer for fullscreen -// surfaces are examples of such optimizations. Those optimizations are -// highly dependent on the compositor implementation, so the use of this -// request should be considered on a case-by-case basis. -// -// Note that if the transform value includes 90 or 270 degree rotation, -// the width of the buffer will become the surface height and the height -// of the buffer will become the surface width. -// -// If transform is not one of the values from the -// wl_output.transform enum the invalid_transform protocol error -// is raised. -// -// transform: transform for interpreting buffer contents -func (i *Surface) SetBufferTransform(transform int32) error { - const opcode = 7 - const _reqBufLen = 8 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(transform)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// SetBufferScale : sets the buffer scaling factor -// -// This request sets an optional scaling factor on how the compositor -// interprets the contents of the buffer attached to the window. -// -// Buffer scale is double-buffered state, see wl_surface.commit. -// -// A newly created surface has its buffer scale set to 1. -// -// wl_surface.set_buffer_scale changes the pending buffer scale. -// wl_surface.commit copies the pending buffer scale to the current one. -// Otherwise, the pending and current values are never changed. -// -// The purpose of this request is to allow clients to supply higher -// resolution buffer data for use on high resolution outputs. It is -// intended that you pick the same buffer scale as the scale of the -// output that the surface is displayed on. This means the compositor -// can avoid scaling when rendering the surface on that output. -// -// Note that if the scale is larger than 1, then you have to attach -// a buffer that is larger (by a factor of scale in each dimension) -// than the desired surface size. -// -// If scale is not greater than 0 the invalid_scale protocol error is -// raised. -// -// scale: scale for interpreting buffer contents -func (i *Surface) SetBufferScale(scale int32) error { - const opcode = 8 - const _reqBufLen = 8 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(scale)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// DamageBuffer : mark part of the surface damaged using buffer coordinates -// -// This request is used to describe the regions where the pending -// buffer is different from the current surface contents, and where -// the surface therefore needs to be repainted. The compositor -// ignores the parts of the damage that fall outside of the surface. -// -// Damage is double-buffered state, see wl_surface.commit. -// -// The damage rectangle is specified in buffer coordinates, -// where x and y specify the upper left corner of the damage rectangle. -// -// The initial value for pending damage is empty: no damage. -// wl_surface.damage_buffer adds pending damage: the new pending -// damage is the union of old pending damage and the given rectangle. -// -// wl_surface.commit assigns pending damage as the current damage, -// and clears pending damage. The server will clear the current -// damage as it repaints the surface. -// -// This request differs from wl_surface.damage in only one way - it -// takes damage in buffer coordinates instead of surface-local -// coordinates. While this generally is more intuitive than surface -// coordinates, it is especially desirable when using wp_viewport -// or when a drawing library (like EGL) is unaware of buffer scale -// and buffer transform. -// -// Note: Because buffer transformation changes and damage requests may -// be interleaved in the protocol stream, it is impossible to determine -// the actual mapping between surface and buffer damage until -// wl_surface.commit time. Therefore, compositors wishing to take both -// kinds of damage into account will have to accumulate damage from the -// two requests separately and only transform from one to the other -// after receiving the wl_surface.commit. -// -// x: buffer-local x coordinate -// y: buffer-local y coordinate -// width: width of damage rectangle -// height: height of damage rectangle -func (i *Surface) DamageBuffer(x, y, width, height int32) error { - const opcode = 9 - const _reqBufLen = 8 + 4 + 4 + 4 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(x)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(y)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(width)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(height)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// Offset : set the surface contents offset -// -// The x and y arguments specify the location of the new pending -// buffer's upper left corner, relative to the current buffer's upper -// left corner, in surface-local coordinates. In other words, the -// x and y, combined with the new surface size define in which -// directions the surface's size changes. -// -// The exact semantics of wl_surface.offset are role-specific. Refer to -// the documentation of specific roles for more information. -// -// Surface location offset is double-buffered state, see -// wl_surface.commit. -// -// This request is semantically equivalent to and the replaces the x and y -// arguments in the wl_surface.attach request in wl_surface versions prior -// to 5. See wl_surface.attach for details. -// -// x: surface-local x coordinate -// y: surface-local y coordinate -func (i *Surface) Offset(x, y int32) error { - const opcode = 10 - const _reqBufLen = 8 + 4 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(x)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(y)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -type SurfaceError uint32 - -// SurfaceError : wl_surface error values -// -// These errors can be emitted in response to wl_surface requests. -const ( - // SurfaceErrorInvalidScale : buffer scale value is invalid - SurfaceErrorInvalidScale SurfaceError = 0 - // SurfaceErrorInvalidTransform : buffer transform value is invalid - SurfaceErrorInvalidTransform SurfaceError = 1 - // SurfaceErrorInvalidSize : buffer size is invalid - SurfaceErrorInvalidSize SurfaceError = 2 - // SurfaceErrorInvalidOffset : buffer offset is invalid - SurfaceErrorInvalidOffset SurfaceError = 3 - // SurfaceErrorDefunctRoleObject : surface was destroyed before its role object - SurfaceErrorDefunctRoleObject SurfaceError = 4 -) - -func (e SurfaceError) Name() string { - switch e { - case SurfaceErrorInvalidScale: - return "invalid_scale" - case SurfaceErrorInvalidTransform: - return "invalid_transform" - case SurfaceErrorInvalidSize: - return "invalid_size" - case SurfaceErrorInvalidOffset: - return "invalid_offset" - case SurfaceErrorDefunctRoleObject: - return "defunct_role_object" - default: - return "" - } -} - -func (e SurfaceError) Value() string { - switch e { - case SurfaceErrorInvalidScale: - return "0" - case SurfaceErrorInvalidTransform: - return "1" - case SurfaceErrorInvalidSize: - return "2" - case SurfaceErrorInvalidOffset: - return "3" - case SurfaceErrorDefunctRoleObject: - return "4" - default: - return "" - } -} - -func (e SurfaceError) String() string { - return e.Name() + "=" + e.Value() -} - -// SurfaceEnterEvent : surface enters an output -// -// This is emitted whenever a surface's creation, movement, or resizing -// results in some part of it being within the scanout region of an -// output. -// -// Note that a surface may be overlapping with zero or more outputs. -type SurfaceEnterEvent struct { - Output *Output -} -type SurfaceEnterHandlerFunc func(SurfaceEnterEvent) - -// SetEnterHandler : sets handler for SurfaceEnterEvent -func (i *Surface) SetEnterHandler(f SurfaceEnterHandlerFunc) { - i.enterHandler = f -} - -// SurfaceLeaveEvent : surface leaves an output -// -// This is emitted whenever a surface's creation, movement, or resizing -// results in it no longer having any part of it within the scanout region -// of an output. -// -// Clients should not use the number of outputs the surface is on for frame -// throttling purposes. The surface might be hidden even if no leave event -// has been sent, and the compositor might expect new surface content -// updates even if no enter event has been sent. The frame event should be -// used instead. -type SurfaceLeaveEvent struct { - Output *Output -} -type SurfaceLeaveHandlerFunc func(SurfaceLeaveEvent) - -// SetLeaveHandler : sets handler for SurfaceLeaveEvent -func (i *Surface) SetLeaveHandler(f SurfaceLeaveHandlerFunc) { - i.leaveHandler = f -} - -// SurfacePreferredBufferScaleEvent : preferred buffer scale for the surface -// -// This event indicates the preferred buffer scale for this surface. It is -// sent whenever the compositor's preference changes. -// -// Before receiving this event the preferred buffer scale for this surface -// is 1. -// -// It is intended that scaling aware clients use this event to scale their -// content and use wl_surface.set_buffer_scale to indicate the scale they -// have rendered with. This allows clients to supply a higher detail -// buffer. -// -// The compositor shall emit a scale value greater than 0. -type SurfacePreferredBufferScaleEvent struct { - Factor int32 -} -type SurfacePreferredBufferScaleHandlerFunc func(SurfacePreferredBufferScaleEvent) - -// SetPreferredBufferScaleHandler : sets handler for SurfacePreferredBufferScaleEvent -func (i *Surface) SetPreferredBufferScaleHandler(f SurfacePreferredBufferScaleHandlerFunc) { - i.preferredBufferScaleHandler = f -} - -// SurfacePreferredBufferTransformEvent : preferred buffer transform for the surface -// -// This event indicates the preferred buffer transform for this surface. -// It is sent whenever the compositor's preference changes. -// -// Before receiving this event the preferred buffer transform for this -// surface is normal. -// -// Applying this transformation to the surface buffer contents and using -// wl_surface.set_buffer_transform might allow the compositor to use the -// surface buffer more efficiently. -type SurfacePreferredBufferTransformEvent struct { - Transform uint32 -} -type SurfacePreferredBufferTransformHandlerFunc func(SurfacePreferredBufferTransformEvent) - -// SetPreferredBufferTransformHandler : sets handler for SurfacePreferredBufferTransformEvent -func (i *Surface) SetPreferredBufferTransformHandler(f SurfacePreferredBufferTransformHandlerFunc) { - i.preferredBufferTransformHandler = f -} - -func (i *Surface) Dispatch(opcode uint32, fd int, data []byte) { - switch opcode { - case 0: - if i.enterHandler == nil { - return - } - var e SurfaceEnterEvent - l := 0 - e.Output = i.Context().GetProxy(Uint32(data[l : l+4])).(*Output) - l += 4 - - i.enterHandler(e) - case 1: - if i.leaveHandler == nil { - return - } - var e SurfaceLeaveEvent - l := 0 - e.Output = i.Context().GetProxy(Uint32(data[l : l+4])).(*Output) - l += 4 - - i.leaveHandler(e) - case 2: - if i.preferredBufferScaleHandler == nil { - return - } - var e SurfacePreferredBufferScaleEvent - l := 0 - e.Factor = int32(Uint32(data[l : l+4])) - l += 4 - - i.preferredBufferScaleHandler(e) - case 3: - if i.preferredBufferTransformHandler == nil { - return - } - var e SurfacePreferredBufferTransformEvent - l := 0 - e.Transform = Uint32(data[l : l+4]) - l += 4 - - i.preferredBufferTransformHandler(e) - } -} - -// SeatInterfaceName is the name of the interface as it appears in the [client.Registry]. -// It can be used to match the [client.RegistryGlobalEvent.Interface] in the -// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies. -const SeatInterfaceName = "wl_seat" - -// Seat : group of input devices -// -// A seat is a group of keyboards, pointer and touch devices. This -// object is published as a global during start up, or when such a -// device is hot plugged. A seat typically has a pointer and -// maintains a keyboard focus and a pointer focus. -type Seat struct { - BaseProxy - capabilitiesHandler SeatCapabilitiesHandlerFunc - nameHandler SeatNameHandlerFunc -} - -// NewSeat : group of input devices -// -// A seat is a group of keyboards, pointer and touch devices. This -// object is published as a global during start up, or when such a -// device is hot plugged. A seat typically has a pointer and -// maintains a keyboard focus and a pointer focus. -func NewSeat(ctx *Context) *Seat { - wlSeat := &Seat{} - ctx.Register(wlSeat) - return wlSeat -} - -// GetPointer : return pointer object -// -// The ID provided will be initialized to the wl_pointer interface -// for this seat. -// -// This request only takes effect if the seat has the pointer -// capability, or has had the pointer capability in the past. -// It is a protocol violation to issue this request on a seat that has -// never had the pointer capability. The missing_capability error will -// be sent in this case. -func (i *Seat) GetPointer() (*Pointer, error) { - id := NewPointer(i.Context()) - const opcode = 0 - const _reqBufLen = 8 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], id.ID()) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return id, err -} - -// GetKeyboard : return keyboard object -// -// The ID provided will be initialized to the wl_keyboard interface -// for this seat. -// -// This request only takes effect if the seat has the keyboard -// capability, or has had the keyboard capability in the past. -// It is a protocol violation to issue this request on a seat that has -// never had the keyboard capability. The missing_capability error will -// be sent in this case. -func (i *Seat) GetKeyboard() (*Keyboard, error) { - id := NewKeyboard(i.Context()) - const opcode = 1 - const _reqBufLen = 8 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], id.ID()) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return id, err -} - -// GetTouch : return touch object -// -// The ID provided will be initialized to the wl_touch interface -// for this seat. -// -// This request only takes effect if the seat has the touch -// capability, or has had the touch capability in the past. -// It is a protocol violation to issue this request on a seat that has -// never had the touch capability. The missing_capability error will -// be sent in this case. -func (i *Seat) GetTouch() (*Touch, error) { - id := NewTouch(i.Context()) - const opcode = 2 - const _reqBufLen = 8 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], id.ID()) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return id, err -} - -// Release : release the seat object -// -// Using this request a client can tell the server that it is not going to -// use the seat object anymore. -func (i *Seat) Release() error { - defer i.MarkZombie() - const opcode = 3 - const _reqBufLen = 8 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -type SeatCapability uint32 - -// SeatCapability : seat capability bitmask -// -// This is a bitmask of capabilities this seat has; if a member is -// set, then it is present on the seat. -const ( - // SeatCapabilityPointer : the seat has pointer devices - SeatCapabilityPointer SeatCapability = 1 - // SeatCapabilityKeyboard : the seat has one or more keyboards - SeatCapabilityKeyboard SeatCapability = 2 - // SeatCapabilityTouch : the seat has touch devices - SeatCapabilityTouch SeatCapability = 4 -) - -func (e SeatCapability) Name() string { - switch e { - case SeatCapabilityPointer: - return "pointer" - case SeatCapabilityKeyboard: - return "keyboard" - case SeatCapabilityTouch: - return "touch" - default: - return "" - } -} - -func (e SeatCapability) Value() string { - switch e { - case SeatCapabilityPointer: - return "1" - case SeatCapabilityKeyboard: - return "2" - case SeatCapabilityTouch: - return "4" - default: - return "" - } -} - -func (e SeatCapability) String() string { - return e.Name() + "=" + e.Value() -} - -type SeatError uint32 - -// SeatError : wl_seat error values -// -// These errors can be emitted in response to wl_seat requests. -const ( - // SeatErrorMissingCapability : get_pointer, get_keyboard or get_touch called on seat without the matching capability - SeatErrorMissingCapability SeatError = 0 -) - -func (e SeatError) Name() string { - switch e { - case SeatErrorMissingCapability: - return "missing_capability" - default: - return "" - } -} - -func (e SeatError) Value() string { - switch e { - case SeatErrorMissingCapability: - return "0" - default: - return "" - } -} - -func (e SeatError) String() string { - return e.Name() + "=" + e.Value() -} - -// SeatCapabilitiesEvent : seat capabilities changed -// -// This is sent on binding to the seat global or whenever a seat gains -// or loses the pointer, keyboard or touch capabilities. -// The argument is a capability enum containing the complete set of -// capabilities this seat has. -// -// When the pointer capability is added, a client may create a -// wl_pointer object using the wl_seat.get_pointer request. This object -// will receive pointer events until the capability is removed in the -// future. -// -// When the pointer capability is removed, a client should destroy the -// wl_pointer objects associated with the seat where the capability was -// removed, using the wl_pointer.release request. No further pointer -// events will be received on these objects. -// -// In some compositors, if a seat regains the pointer capability and a -// client has a previously obtained wl_pointer object of version 4 or -// less, that object may start sending pointer events again. This -// behavior is considered a misinterpretation of the intended behavior -// and must not be relied upon by the client. wl_pointer objects of -// version 5 or later must not send events if created before the most -// recent event notifying the client of an added pointer capability. -// -// The above behavior also applies to wl_keyboard and wl_touch with the -// keyboard and touch capabilities, respectively. -type SeatCapabilitiesEvent struct { - Capabilities uint32 -} -type SeatCapabilitiesHandlerFunc func(SeatCapabilitiesEvent) - -// SetCapabilitiesHandler : sets handler for SeatCapabilitiesEvent -func (i *Seat) SetCapabilitiesHandler(f SeatCapabilitiesHandlerFunc) { - i.capabilitiesHandler = f -} - -// SeatNameEvent : unique identifier for this seat -// -// In a multi-seat configuration the seat name can be used by clients to -// help identify which physical devices the seat represents. -// -// The seat name is a UTF-8 string with no convention defined for its -// contents. Each name is unique among all wl_seat globals. The name is -// only guaranteed to be unique for the current compositor instance. -// -// The same seat names are used for all clients. Thus, the name can be -// shared across processes to refer to a specific wl_seat global. -// -// The name event is sent after binding to the seat global, and should be sent -// before announcing capabilities. This event only sent once per seat object, -// and the name does not change over the lifetime of the wl_seat global. -// -// Compositors may re-use the same seat name if the wl_seat global is -// destroyed and re-created later. -type SeatNameEvent struct { - Name string -} -type SeatNameHandlerFunc func(SeatNameEvent) - -// SetNameHandler : sets handler for SeatNameEvent -func (i *Seat) SetNameHandler(f SeatNameHandlerFunc) { - i.nameHandler = f -} - -func (i *Seat) Dispatch(opcode uint32, fd int, data []byte) { - switch opcode { - case 0: - if i.capabilitiesHandler == nil { - return - } - var e SeatCapabilitiesEvent - l := 0 - e.Capabilities = Uint32(data[l : l+4]) - l += 4 - - i.capabilitiesHandler(e) - case 1: - if i.nameHandler == nil { - return - } - var e SeatNameEvent - l := 0 - nameLen := PaddedLen(int(Uint32(data[l : l+4]))) - l += 4 - e.Name = String(data[l : l+nameLen]) - l += nameLen - - i.nameHandler(e) - } -} - -// PointerInterfaceName is the name of the interface as it appears in the [client.Registry]. -// It can be used to match the [client.RegistryGlobalEvent.Interface] in the -// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies. -const PointerInterfaceName = "wl_pointer" - -// Pointer : pointer input device -// -// The wl_pointer interface represents one or more input devices, -// such as mice, which control the pointer location and pointer_focus -// of a seat. -// -// The wl_pointer interface generates motion, enter and leave -// events for the surfaces that the pointer is located over, -// and button and axis events for button presses, button releases -// and scrolling. -type Pointer struct { - BaseProxy - enterHandler PointerEnterHandlerFunc - leaveHandler PointerLeaveHandlerFunc - motionHandler PointerMotionHandlerFunc - buttonHandler PointerButtonHandlerFunc - axisHandler PointerAxisHandlerFunc - frameHandler PointerFrameHandlerFunc - axisSourceHandler PointerAxisSourceHandlerFunc - axisStopHandler PointerAxisStopHandlerFunc - axisDiscreteHandler PointerAxisDiscreteHandlerFunc - axisValue120Handler PointerAxisValue120HandlerFunc - axisRelativeDirectionHandler PointerAxisRelativeDirectionHandlerFunc -} - -// NewPointer : pointer input device -// -// The wl_pointer interface represents one or more input devices, -// such as mice, which control the pointer location and pointer_focus -// of a seat. -// -// The wl_pointer interface generates motion, enter and leave -// events for the surfaces that the pointer is located over, -// and button and axis events for button presses, button releases -// and scrolling. -func NewPointer(ctx *Context) *Pointer { - wlPointer := &Pointer{} - ctx.Register(wlPointer) - return wlPointer -} - -// SetCursor : set the pointer surface -// -// Set the pointer surface, i.e., the surface that contains the -// pointer image (cursor). This request gives the surface the role -// of a cursor. If the surface already has another role, it raises -// a protocol error. -// -// The cursor actually changes only if the pointer -// focus for this device is one of the requesting client's surfaces -// or the surface parameter is the current pointer surface. If -// there was a previous surface set with this request it is -// replaced. If surface is NULL, the pointer image is hidden. -// -// The parameters hotspot_x and hotspot_y define the position of -// the pointer surface relative to the pointer location. Its -// top-left corner is always at (x, y) - (hotspot_x, hotspot_y), -// where (x, y) are the coordinates of the pointer location, in -// surface-local coordinates. -// -// On wl_surface.offset requests to the pointer surface, hotspot_x -// and hotspot_y are decremented by the x and y parameters -// passed to the request. The offset must be applied by -// wl_surface.commit as usual. -// -// The hotspot can also be updated by passing the currently set -// pointer surface to this request with new values for hotspot_x -// and hotspot_y. -// -// The input region is ignored for wl_surfaces with the role of -// a cursor. When the use as a cursor ends, the wl_surface is -// unmapped. -// -// The serial parameter must match the latest wl_pointer.enter -// serial number sent to the client. Otherwise the request will be -// ignored. -// -// serial: serial number of the enter event -// surface: pointer surface -// hotspotX: surface-local x coordinate -// hotspotY: surface-local y coordinate -func (i *Pointer) SetCursor(serial uint32, surface *Surface, hotspotX, hotspotY int32) error { - const opcode = 0 - const _reqBufLen = 8 + 4 + 4 + 4 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(serial)) - l += 4 - if surface == nil { - PutUint32(_reqBuf[l:l+4], 0) - l += 4 - } else { - PutUint32(_reqBuf[l:l+4], surface.ID()) - l += 4 - } - PutUint32(_reqBuf[l:l+4], uint32(hotspotX)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(hotspotY)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// Release : release the pointer object -// -// Using this request a client can tell the server that it is not going to -// use the pointer object anymore. -// -// This request destroys the pointer proxy object, so clients must not call -// wl_pointer_destroy() after using this request. -func (i *Pointer) Release() error { - defer i.MarkZombie() - const opcode = 1 - const _reqBufLen = 8 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -type PointerError uint32 - -// PointerError : -const ( - // PointerErrorRole : given wl_surface has another role - PointerErrorRole PointerError = 0 -) - -func (e PointerError) Name() string { - switch e { - case PointerErrorRole: - return "role" - default: - return "" - } -} - -func (e PointerError) Value() string { - switch e { - case PointerErrorRole: - return "0" - default: - return "" - } -} - -func (e PointerError) String() string { - return e.Name() + "=" + e.Value() -} - -type PointerButtonState uint32 - -// PointerButtonState : physical button state -// -// Describes the physical state of a button that produced the button -// event. -const ( - // PointerButtonStateReleased : the button is not pressed - PointerButtonStateReleased PointerButtonState = 0 - // PointerButtonStatePressed : the button is pressed - PointerButtonStatePressed PointerButtonState = 1 -) - -func (e PointerButtonState) Name() string { - switch e { - case PointerButtonStateReleased: - return "released" - case PointerButtonStatePressed: - return "pressed" - default: - return "" - } -} - -func (e PointerButtonState) Value() string { - switch e { - case PointerButtonStateReleased: - return "0" - case PointerButtonStatePressed: - return "1" - default: - return "" - } -} - -func (e PointerButtonState) String() string { - return e.Name() + "=" + e.Value() -} - -type PointerAxis uint32 - -// PointerAxis : axis types -// -// Describes the axis types of scroll events. -const ( - // PointerAxisVerticalScroll : vertical axis - PointerAxisVerticalScroll PointerAxis = 0 - // PointerAxisHorizontalScroll : horizontal axis - PointerAxisHorizontalScroll PointerAxis = 1 -) - -func (e PointerAxis) Name() string { - switch e { - case PointerAxisVerticalScroll: - return "vertical_scroll" - case PointerAxisHorizontalScroll: - return "horizontal_scroll" - default: - return "" - } -} - -func (e PointerAxis) Value() string { - switch e { - case PointerAxisVerticalScroll: - return "0" - case PointerAxisHorizontalScroll: - return "1" - default: - return "" - } -} - -func (e PointerAxis) String() string { - return e.Name() + "=" + e.Value() -} - -type PointerAxisSource uint32 - -// PointerAxisSource : axis source types -// -// Describes the source types for axis events. This indicates to the -// client how an axis event was physically generated; a client may -// adjust the user interface accordingly. For example, scroll events -// from a "finger" source may be in a smooth coordinate space with -// kinetic scrolling whereas a "wheel" source may be in discrete steps -// of a number of lines. -// -// The "continuous" axis source is a device generating events in a -// continuous coordinate space, but using something other than a -// finger. One example for this source is button-based scrolling where -// the vertical motion of a device is converted to scroll events while -// a button is held down. -// -// The "wheel tilt" axis source indicates that the actual device is a -// wheel but the scroll event is not caused by a rotation but a -// (usually sideways) tilt of the wheel. -const ( - // PointerAxisSourceWheel : a physical wheel rotation - PointerAxisSourceWheel PointerAxisSource = 0 - // PointerAxisSourceFinger : finger on a touch surface - PointerAxisSourceFinger PointerAxisSource = 1 - // PointerAxisSourceContinuous : continuous coordinate space - PointerAxisSourceContinuous PointerAxisSource = 2 - // PointerAxisSourceWheelTilt : a physical wheel tilt - PointerAxisSourceWheelTilt PointerAxisSource = 3 -) - -func (e PointerAxisSource) Name() string { - switch e { - case PointerAxisSourceWheel: - return "wheel" - case PointerAxisSourceFinger: - return "finger" - case PointerAxisSourceContinuous: - return "continuous" - case PointerAxisSourceWheelTilt: - return "wheel_tilt" - default: - return "" - } -} - -func (e PointerAxisSource) Value() string { - switch e { - case PointerAxisSourceWheel: - return "0" - case PointerAxisSourceFinger: - return "1" - case PointerAxisSourceContinuous: - return "2" - case PointerAxisSourceWheelTilt: - return "3" - default: - return "" - } -} - -func (e PointerAxisSource) String() string { - return e.Name() + "=" + e.Value() -} - -type PointerAxisRelativeDirection uint32 - -// PointerAxisRelativeDirection : axis relative direction -// -// This specifies the direction of the physical motion that caused a -// wl_pointer.axis event, relative to the wl_pointer.axis direction. -const ( - // PointerAxisRelativeDirectionIdentical : physical motion matches axis direction - PointerAxisRelativeDirectionIdentical PointerAxisRelativeDirection = 0 - // PointerAxisRelativeDirectionInverted : physical motion is the inverse of the axis direction - PointerAxisRelativeDirectionInverted PointerAxisRelativeDirection = 1 -) - -func (e PointerAxisRelativeDirection) Name() string { - switch e { - case PointerAxisRelativeDirectionIdentical: - return "identical" - case PointerAxisRelativeDirectionInverted: - return "inverted" - default: - return "" - } -} - -func (e PointerAxisRelativeDirection) Value() string { - switch e { - case PointerAxisRelativeDirectionIdentical: - return "0" - case PointerAxisRelativeDirectionInverted: - return "1" - default: - return "" - } -} - -func (e PointerAxisRelativeDirection) String() string { - return e.Name() + "=" + e.Value() -} - -// PointerEnterEvent : enter event -// -// Notification that this seat's pointer is focused on a certain -// surface. -// -// When a seat's focus enters a surface, the pointer image -// is undefined and a client should respond to this event by setting -// an appropriate pointer image with the set_cursor request. -type PointerEnterEvent struct { - Serial uint32 - Surface *Surface - SurfaceX float64 - SurfaceY float64 -} -type PointerEnterHandlerFunc func(PointerEnterEvent) - -// SetEnterHandler : sets handler for PointerEnterEvent -func (i *Pointer) SetEnterHandler(f PointerEnterHandlerFunc) { - i.enterHandler = f -} - -// PointerLeaveEvent : leave event -// -// Notification that this seat's pointer is no longer focused on -// a certain surface. -// -// The leave notification is sent before the enter notification -// for the new focus. -type PointerLeaveEvent struct { - Serial uint32 - Surface *Surface -} -type PointerLeaveHandlerFunc func(PointerLeaveEvent) - -// SetLeaveHandler : sets handler for PointerLeaveEvent -func (i *Pointer) SetLeaveHandler(f PointerLeaveHandlerFunc) { - i.leaveHandler = f -} - -// PointerMotionEvent : pointer motion event -// -// Notification of pointer location change. The arguments -// surface_x and surface_y are the location relative to the -// focused surface. -type PointerMotionEvent struct { - Time uint32 - SurfaceX float64 - SurfaceY float64 -} -type PointerMotionHandlerFunc func(PointerMotionEvent) - -// SetMotionHandler : sets handler for PointerMotionEvent -func (i *Pointer) SetMotionHandler(f PointerMotionHandlerFunc) { - i.motionHandler = f -} - -// PointerButtonEvent : pointer button event -// -// Mouse button click and release notifications. -// -// The location of the click is given by the last motion or -// enter event. -// The time argument is a timestamp with millisecond -// granularity, with an undefined base. -// -// The button is a button code as defined in the Linux kernel's -// linux/input-event-codes.h header file, e.g. BTN_LEFT. -// -// Any 16-bit button code value is reserved for future additions to the -// kernel's event code list. All other button codes above 0xFFFF are -// currently undefined but may be used in future versions of this -// protocol. -type PointerButtonEvent struct { - Serial uint32 - Time uint32 - Button uint32 - State uint32 -} -type PointerButtonHandlerFunc func(PointerButtonEvent) - -// SetButtonHandler : sets handler for PointerButtonEvent -func (i *Pointer) SetButtonHandler(f PointerButtonHandlerFunc) { - i.buttonHandler = f -} - -// PointerAxisEvent : axis event -// -// Scroll and other axis notifications. -// -// For scroll events (vertical and horizontal scroll axes), the -// value parameter is the length of a vector along the specified -// axis in a coordinate space identical to those of motion events, -// representing a relative movement along the specified axis. -// -// For devices that support movements non-parallel to axes multiple -// axis events will be emitted. -// -// When applicable, for example for touch pads, the server can -// choose to emit scroll events where the motion vector is -// equivalent to a motion event vector. -// -// When applicable, a client can transform its content relative to the -// scroll distance. -type PointerAxisEvent struct { - Time uint32 - Axis uint32 - Value float64 -} -type PointerAxisHandlerFunc func(PointerAxisEvent) - -// SetAxisHandler : sets handler for PointerAxisEvent -func (i *Pointer) SetAxisHandler(f PointerAxisHandlerFunc) { - i.axisHandler = f -} - -// PointerFrameEvent : end of a pointer event sequence -// -// Indicates the end of a set of events that logically belong together. -// A client is expected to accumulate the data in all events within the -// frame before proceeding. -// -// All wl_pointer events before a wl_pointer.frame event belong -// logically together. For example, in a diagonal scroll motion the -// compositor will send an optional wl_pointer.axis_source event, two -// wl_pointer.axis events (horizontal and vertical) and finally a -// wl_pointer.frame event. The client may use this information to -// calculate a diagonal vector for scrolling. -// -// When multiple wl_pointer.axis events occur within the same frame, -// the motion vector is the combined motion of all events. -// When a wl_pointer.axis and a wl_pointer.axis_stop event occur within -// the same frame, this indicates that axis movement in one axis has -// stopped but continues in the other axis. -// When multiple wl_pointer.axis_stop events occur within the same -// frame, this indicates that these axes stopped in the same instance. -// -// A wl_pointer.frame event is sent for every logical event group, -// even if the group only contains a single wl_pointer event. -// Specifically, a client may get a sequence: motion, frame, button, -// frame, axis, frame, axis_stop, frame. -// -// The wl_pointer.enter and wl_pointer.leave events are logical events -// generated by the compositor and not the hardware. These events are -// also grouped by a wl_pointer.frame. When a pointer moves from one -// surface to another, a compositor should group the -// wl_pointer.leave event within the same wl_pointer.frame. -// However, a client must not rely on wl_pointer.leave and -// wl_pointer.enter being in the same wl_pointer.frame. -// Compositor-specific policies may require the wl_pointer.leave and -// wl_pointer.enter event being split across multiple wl_pointer.frame -// groups. -type PointerFrameEvent struct{} -type PointerFrameHandlerFunc func(PointerFrameEvent) - -// SetFrameHandler : sets handler for PointerFrameEvent -func (i *Pointer) SetFrameHandler(f PointerFrameHandlerFunc) { - i.frameHandler = f -} - -// PointerAxisSourceEvent : axis source event -// -// Source information for scroll and other axes. -// -// This event does not occur on its own. It is sent before a -// wl_pointer.frame event and carries the source information for -// all events within that frame. -// -// The source specifies how this event was generated. If the source is -// wl_pointer.axis_source.finger, a wl_pointer.axis_stop event will be -// sent when the user lifts the finger off the device. -// -// If the source is wl_pointer.axis_source.wheel, -// wl_pointer.axis_source.wheel_tilt or -// wl_pointer.axis_source.continuous, a wl_pointer.axis_stop event may -// or may not be sent. Whether a compositor sends an axis_stop event -// for these sources is hardware-specific and implementation-dependent; -// clients must not rely on receiving an axis_stop event for these -// scroll sources and should treat scroll sequences from these scroll -// sources as unterminated by default. -// -// This event is optional. If the source is unknown for a particular -// axis event sequence, no event is sent. -// Only one wl_pointer.axis_source event is permitted per frame. -// -// The order of wl_pointer.axis_discrete and wl_pointer.axis_source is -// not guaranteed. -type PointerAxisSourceEvent struct { - AxisSource uint32 -} -type PointerAxisSourceHandlerFunc func(PointerAxisSourceEvent) - -// SetAxisSourceHandler : sets handler for PointerAxisSourceEvent -func (i *Pointer) SetAxisSourceHandler(f PointerAxisSourceHandlerFunc) { - i.axisSourceHandler = f -} - -// PointerAxisStopEvent : axis stop event -// -// Stop notification for scroll and other axes. -// -// For some wl_pointer.axis_source types, a wl_pointer.axis_stop event -// is sent to notify a client that the axis sequence has terminated. -// This enables the client to implement kinetic scrolling. -// See the wl_pointer.axis_source documentation for information on when -// this event may be generated. -// -// Any wl_pointer.axis events with the same axis_source after this -// event should be considered as the start of a new axis motion. -// -// The timestamp is to be interpreted identical to the timestamp in the -// wl_pointer.axis event. The timestamp value may be the same as a -// preceding wl_pointer.axis event. -type PointerAxisStopEvent struct { - Time uint32 - Axis uint32 -} -type PointerAxisStopHandlerFunc func(PointerAxisStopEvent) - -// SetAxisStopHandler : sets handler for PointerAxisStopEvent -func (i *Pointer) SetAxisStopHandler(f PointerAxisStopHandlerFunc) { - i.axisStopHandler = f -} - -// PointerAxisDiscreteEvent : axis click event -// -// Discrete step information for scroll and other axes. -// -// This event carries the axis value of the wl_pointer.axis event in -// discrete steps (e.g. mouse wheel clicks). -// -// This event is deprecated with wl_pointer version 8 - this event is not -// sent to clients supporting version 8 or later. -// -// This event does not occur on its own, it is coupled with a -// wl_pointer.axis event that represents this axis value on a -// continuous scale. The protocol guarantees that each axis_discrete -// event is always followed by exactly one axis event with the same -// axis number within the same wl_pointer.frame. Note that the protocol -// allows for other events to occur between the axis_discrete and -// its coupled axis event, including other axis_discrete or axis -// events. A wl_pointer.frame must not contain more than one axis_discrete -// event per axis type. -// -// This event is optional; continuous scrolling devices -// like two-finger scrolling on touchpads do not have discrete -// steps and do not generate this event. -// -// The discrete value carries the directional information. e.g. a value -// of -2 is two steps towards the negative direction of this axis. -// -// The axis number is identical to the axis number in the associated -// axis event. -// -// The order of wl_pointer.axis_discrete and wl_pointer.axis_source is -// not guaranteed. -type PointerAxisDiscreteEvent struct { - Axis uint32 - Discrete int32 -} -type PointerAxisDiscreteHandlerFunc func(PointerAxisDiscreteEvent) - -// SetAxisDiscreteHandler : sets handler for PointerAxisDiscreteEvent -func (i *Pointer) SetAxisDiscreteHandler(f PointerAxisDiscreteHandlerFunc) { - i.axisDiscreteHandler = f -} - -// PointerAxisValue120Event : axis high-resolution scroll event -// -// Discrete high-resolution scroll information. -// -// This event carries high-resolution wheel scroll information, -// with each multiple of 120 representing one logical scroll step -// (a wheel detent). For example, an axis_value120 of 30 is one quarter of -// a logical scroll step in the positive direction, a value120 of -// -240 are two logical scroll steps in the negative direction within the -// same hardware event. -// Clients that rely on discrete scrolling should accumulate the -// value120 to multiples of 120 before processing the event. -// -// The value120 must not be zero. -// -// This event replaces the wl_pointer.axis_discrete event in clients -// supporting wl_pointer version 8 or later. -// -// Where a wl_pointer.axis_source event occurs in the same -// wl_pointer.frame, the axis source applies to this event. -// -// The order of wl_pointer.axis_value120 and wl_pointer.axis_source is -// not guaranteed. -type PointerAxisValue120Event struct { - Axis uint32 - Value120 int32 -} -type PointerAxisValue120HandlerFunc func(PointerAxisValue120Event) - -// SetAxisValue120Handler : sets handler for PointerAxisValue120Event -func (i *Pointer) SetAxisValue120Handler(f PointerAxisValue120HandlerFunc) { - i.axisValue120Handler = f -} - -// PointerAxisRelativeDirectionEvent : axis relative physical direction event -// -// Relative directional information of the entity causing the axis -// motion. -// -// For a wl_pointer.axis event, the wl_pointer.axis_relative_direction -// event specifies the movement direction of the entity causing the -// wl_pointer.axis event. For example: -// - if a user's fingers on a touchpad move down and this -// causes a wl_pointer.axis vertical_scroll down event, the physical -// direction is 'identical' -// - if a user's fingers on a touchpad move down and this causes a -// wl_pointer.axis vertical_scroll up scroll up event ('natural -// scrolling'), the physical direction is 'inverted'. -// -// A client may use this information to adjust scroll motion of -// components. Specifically, enabling natural scrolling causes the -// content to change direction compared to traditional scrolling. -// Some widgets like volume control sliders should usually match the -// physical direction regardless of whether natural scrolling is -// active. This event enables clients to match the scroll direction of -// a widget to the physical direction. -// -// This event does not occur on its own, it is coupled with a -// wl_pointer.axis event that represents this axis value. -// The protocol guarantees that each axis_relative_direction event is -// always followed by exactly one axis event with the same -// axis number within the same wl_pointer.frame. Note that the protocol -// allows for other events to occur between the axis_relative_direction -// and its coupled axis event. -// -// The axis number is identical to the axis number in the associated -// axis event. -// -// The order of wl_pointer.axis_relative_direction, -// wl_pointer.axis_discrete and wl_pointer.axis_source is not -// guaranteed. -type PointerAxisRelativeDirectionEvent struct { - Axis uint32 - Direction uint32 -} -type PointerAxisRelativeDirectionHandlerFunc func(PointerAxisRelativeDirectionEvent) - -// SetAxisRelativeDirectionHandler : sets handler for PointerAxisRelativeDirectionEvent -func (i *Pointer) SetAxisRelativeDirectionHandler(f PointerAxisRelativeDirectionHandlerFunc) { - i.axisRelativeDirectionHandler = f -} - -func (i *Pointer) Dispatch(opcode uint32, fd int, data []byte) { - switch opcode { - case 0: - if i.enterHandler == nil { - return - } - var e PointerEnterEvent - l := 0 - e.Serial = Uint32(data[l : l+4]) - l += 4 - e.Surface = i.Context().GetProxy(Uint32(data[l : l+4])).(*Surface) - l += 4 - e.SurfaceX = Fixed(data[l : l+4]) - l += 4 - e.SurfaceY = Fixed(data[l : l+4]) - l += 4 - - i.enterHandler(e) - case 1: - if i.leaveHandler == nil { - return - } - var e PointerLeaveEvent - l := 0 - e.Serial = Uint32(data[l : l+4]) - l += 4 - e.Surface = i.Context().GetProxy(Uint32(data[l : l+4])).(*Surface) - l += 4 - - i.leaveHandler(e) - case 2: - if i.motionHandler == nil { - return - } - var e PointerMotionEvent - l := 0 - e.Time = Uint32(data[l : l+4]) - l += 4 - e.SurfaceX = Fixed(data[l : l+4]) - l += 4 - e.SurfaceY = Fixed(data[l : l+4]) - l += 4 - - i.motionHandler(e) - case 3: - if i.buttonHandler == nil { - return - } - var e PointerButtonEvent - l := 0 - e.Serial = Uint32(data[l : l+4]) - l += 4 - e.Time = Uint32(data[l : l+4]) - l += 4 - e.Button = Uint32(data[l : l+4]) - l += 4 - e.State = Uint32(data[l : l+4]) - l += 4 - - i.buttonHandler(e) - case 4: - if i.axisHandler == nil { - return - } - var e PointerAxisEvent - l := 0 - e.Time = Uint32(data[l : l+4]) - l += 4 - e.Axis = Uint32(data[l : l+4]) - l += 4 - e.Value = Fixed(data[l : l+4]) - l += 4 - - i.axisHandler(e) - case 5: - if i.frameHandler == nil { - return - } - var e PointerFrameEvent - - i.frameHandler(e) - case 6: - if i.axisSourceHandler == nil { - return - } - var e PointerAxisSourceEvent - l := 0 - e.AxisSource = Uint32(data[l : l+4]) - l += 4 - - i.axisSourceHandler(e) - case 7: - if i.axisStopHandler == nil { - return - } - var e PointerAxisStopEvent - l := 0 - e.Time = Uint32(data[l : l+4]) - l += 4 - e.Axis = Uint32(data[l : l+4]) - l += 4 - - i.axisStopHandler(e) - case 8: - if i.axisDiscreteHandler == nil { - return - } - var e PointerAxisDiscreteEvent - l := 0 - e.Axis = Uint32(data[l : l+4]) - l += 4 - e.Discrete = int32(Uint32(data[l : l+4])) - l += 4 - - i.axisDiscreteHandler(e) - case 9: - if i.axisValue120Handler == nil { - return - } - var e PointerAxisValue120Event - l := 0 - e.Axis = Uint32(data[l : l+4]) - l += 4 - e.Value120 = int32(Uint32(data[l : l+4])) - l += 4 - - i.axisValue120Handler(e) - case 10: - if i.axisRelativeDirectionHandler == nil { - return - } - var e PointerAxisRelativeDirectionEvent - l := 0 - e.Axis = Uint32(data[l : l+4]) - l += 4 - e.Direction = Uint32(data[l : l+4]) - l += 4 - - i.axisRelativeDirectionHandler(e) - } -} - -// KeyboardInterfaceName is the name of the interface as it appears in the [client.Registry]. -// It can be used to match the [client.RegistryGlobalEvent.Interface] in the -// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies. -const KeyboardInterfaceName = "wl_keyboard" - -// Keyboard : keyboard input device -// -// The wl_keyboard interface represents one or more keyboards -// associated with a seat. -// -// Each wl_keyboard has the following logical state: -// -// - an active surface (possibly null), -// - the keys currently logically down, -// - the active modifiers, -// - the active group. -// -// By default, the active surface is null, the keys currently logically down -// are empty, the active modifiers and the active group are 0. -type Keyboard struct { - BaseProxy - keymapHandler KeyboardKeymapHandlerFunc - enterHandler KeyboardEnterHandlerFunc - leaveHandler KeyboardLeaveHandlerFunc - keyHandler KeyboardKeyHandlerFunc - modifiersHandler KeyboardModifiersHandlerFunc - repeatInfoHandler KeyboardRepeatInfoHandlerFunc -} - -// NewKeyboard : keyboard input device -// -// The wl_keyboard interface represents one or more keyboards -// associated with a seat. -// -// Each wl_keyboard has the following logical state: -// -// - an active surface (possibly null), -// - the keys currently logically down, -// - the active modifiers, -// - the active group. -// -// By default, the active surface is null, the keys currently logically down -// are empty, the active modifiers and the active group are 0. -func NewKeyboard(ctx *Context) *Keyboard { - wlKeyboard := &Keyboard{} - ctx.Register(wlKeyboard) - return wlKeyboard -} - -// Release : release the keyboard object -func (i *Keyboard) Release() error { - defer i.MarkZombie() - const opcode = 0 - const _reqBufLen = 8 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -type KeyboardKeymapFormat uint32 - -// KeyboardKeymapFormat : keyboard mapping format -// -// This specifies the format of the keymap provided to the -// client with the wl_keyboard.keymap event. -const ( - // KeyboardKeymapFormatNoKeymap : no keymap; client must understand how to interpret the raw keycode - KeyboardKeymapFormatNoKeymap KeyboardKeymapFormat = 0 - // KeyboardKeymapFormatXkbV1 : libxkbcommon compatible, null-terminated string; to determine the xkb keycode, clients must add 8 to the key event keycode - KeyboardKeymapFormatXkbV1 KeyboardKeymapFormat = 1 -) - -func (e KeyboardKeymapFormat) Name() string { - switch e { - case KeyboardKeymapFormatNoKeymap: - return "no_keymap" - case KeyboardKeymapFormatXkbV1: - return "xkb_v1" - default: - return "" - } -} - -func (e KeyboardKeymapFormat) Value() string { - switch e { - case KeyboardKeymapFormatNoKeymap: - return "0" - case KeyboardKeymapFormatXkbV1: - return "1" - default: - return "" - } -} - -func (e KeyboardKeymapFormat) String() string { - return e.Name() + "=" + e.Value() -} - -type KeyboardKeyState uint32 - -// KeyboardKeyState : physical key state -// -// Describes the physical state of a key that produced the key event. -// -// Since version 10, the key can be in a "repeated" pseudo-state which -// means the same as "pressed", but is used to signal repetition in the -// key event. -// -// The key may only enter the repeated state after entering the pressed -// state and before entering the released state. This event may be -// generated multiple times while the key is down. -const ( - // KeyboardKeyStateReleased : key is not pressed - KeyboardKeyStateReleased KeyboardKeyState = 0 - // KeyboardKeyStatePressed : key is pressed - KeyboardKeyStatePressed KeyboardKeyState = 1 - // KeyboardKeyStateRepeated : key was repeated - KeyboardKeyStateRepeated KeyboardKeyState = 2 -) - -func (e KeyboardKeyState) Name() string { - switch e { - case KeyboardKeyStateReleased: - return "released" - case KeyboardKeyStatePressed: - return "pressed" - case KeyboardKeyStateRepeated: - return "repeated" - default: - return "" - } -} - -func (e KeyboardKeyState) Value() string { - switch e { - case KeyboardKeyStateReleased: - return "0" - case KeyboardKeyStatePressed: - return "1" - case KeyboardKeyStateRepeated: - return "2" - default: - return "" - } -} - -func (e KeyboardKeyState) String() string { - return e.Name() + "=" + e.Value() -} - -// KeyboardKeymapEvent : keyboard mapping -// -// This event provides a file descriptor to the client which can be -// memory-mapped in read-only mode to provide a keyboard mapping -// description. -// -// From version 7 onwards, the fd must be mapped with MAP_PRIVATE by -// the recipient, as MAP_SHARED may fail. -type KeyboardKeymapEvent struct { - Format uint32 - Fd int - Size uint32 -} -type KeyboardKeymapHandlerFunc func(KeyboardKeymapEvent) - -// SetKeymapHandler : sets handler for KeyboardKeymapEvent -func (i *Keyboard) SetKeymapHandler(f KeyboardKeymapHandlerFunc) { - i.keymapHandler = f -} - -// KeyboardEnterEvent : enter event -// -// Notification that this seat's keyboard focus is on a certain -// surface. -// -// The compositor must send the wl_keyboard.modifiers event after this -// event. -// -// In the wl_keyboard logical state, this event sets the active surface to -// the surface argument and the keys currently logically down to the keys -// in the keys argument. The compositor must not send this event if the -// wl_keyboard already had an active surface immediately before this event. -// -// Clients should not use the list of pressed keys to emulate key-press -// events. The order of keys in the list is unspecified. -type KeyboardEnterEvent struct { - Serial uint32 - Surface *Surface - Keys []byte -} -type KeyboardEnterHandlerFunc func(KeyboardEnterEvent) - -// SetEnterHandler : sets handler for KeyboardEnterEvent -func (i *Keyboard) SetEnterHandler(f KeyboardEnterHandlerFunc) { - i.enterHandler = f -} - -// KeyboardLeaveEvent : leave event -// -// Notification that this seat's keyboard focus is no longer on -// a certain surface. -// -// The leave notification is sent before the enter notification -// for the new focus. -// -// In the wl_keyboard logical state, this event resets all values to their -// defaults. The compositor must not send this event if the active surface -// of the wl_keyboard was not equal to the surface argument immediately -// before this event. -type KeyboardLeaveEvent struct { - Serial uint32 - Surface *Surface -} -type KeyboardLeaveHandlerFunc func(KeyboardLeaveEvent) - -// SetLeaveHandler : sets handler for KeyboardLeaveEvent -func (i *Keyboard) SetLeaveHandler(f KeyboardLeaveHandlerFunc) { - i.leaveHandler = f -} - -// KeyboardKeyEvent : key event -// -// A key was pressed or released. -// The time argument is a timestamp with millisecond -// granularity, with an undefined base. -// -// The key is a platform-specific key code that can be interpreted -// by feeding it to the keyboard mapping (see the keymap event). -// -// If this event produces a change in modifiers, then the resulting -// wl_keyboard.modifiers event must be sent after this event. -// -// In the wl_keyboard logical state, this event adds the key to the keys -// currently logically down (if the state argument is pressed) or removes -// the key from the keys currently logically down (if the state argument is -// released). The compositor must not send this event if the wl_keyboard -// did not have an active surface immediately before this event. The -// compositor must not send this event if state is pressed (resp. released) -// and the key was already logically down (resp. was not logically down) -// immediately before this event. -// -// Since version 10, compositors may send key events with the "repeated" -// key state when a wl_keyboard.repeat_info event with a rate argument of -// 0 has been received. This allows the compositor to take over the -// responsibility of key repetition. -type KeyboardKeyEvent struct { - Serial uint32 - Time uint32 - Key uint32 - State uint32 -} -type KeyboardKeyHandlerFunc func(KeyboardKeyEvent) - -// SetKeyHandler : sets handler for KeyboardKeyEvent -func (i *Keyboard) SetKeyHandler(f KeyboardKeyHandlerFunc) { - i.keyHandler = f -} - -// KeyboardModifiersEvent : modifier and group state -// -// Notifies clients that the modifier and/or group state has -// changed, and it should update its local state. -// -// The compositor may send this event without a surface of the client -// having keyboard focus, for example to tie modifier information to -// pointer focus instead. If a modifier event with pressed modifiers is sent -// without a prior enter event, the client can assume the modifier state is -// valid until it receives the next wl_keyboard.modifiers event. In order to -// reset the modifier state again, the compositor can send a -// wl_keyboard.modifiers event with no pressed modifiers. -// -// In the wl_keyboard logical state, this event updates the modifiers and -// group. -type KeyboardModifiersEvent struct { - Serial uint32 - ModsDepressed uint32 - ModsLatched uint32 - ModsLocked uint32 - Group uint32 -} -type KeyboardModifiersHandlerFunc func(KeyboardModifiersEvent) - -// SetModifiersHandler : sets handler for KeyboardModifiersEvent -func (i *Keyboard) SetModifiersHandler(f KeyboardModifiersHandlerFunc) { - i.modifiersHandler = f -} - -// KeyboardRepeatInfoEvent : repeat rate and delay -// -// Informs the client about the keyboard's repeat rate and delay. -// -// This event is sent as soon as the wl_keyboard object has been created, -// and is guaranteed to be received by the client before any key press -// event. -// -// Negative values for either rate or delay are illegal. A rate of zero -// will disable any repeating (regardless of the value of delay). -// -// This event can be sent later on as well with a new value if necessary, -// so clients should continue listening for the event past the creation -// of wl_keyboard. -type KeyboardRepeatInfoEvent struct { - Rate int32 - Delay int32 -} -type KeyboardRepeatInfoHandlerFunc func(KeyboardRepeatInfoEvent) - -// SetRepeatInfoHandler : sets handler for KeyboardRepeatInfoEvent -func (i *Keyboard) SetRepeatInfoHandler(f KeyboardRepeatInfoHandlerFunc) { - i.repeatInfoHandler = f -} - -func (i *Keyboard) Dispatch(opcode uint32, fd int, data []byte) { - switch opcode { - case 0: - if i.keymapHandler == nil { - if fd != -1 { - unix.Close(fd) - } - return - } - var e KeyboardKeymapEvent - l := 0 - e.Format = Uint32(data[l : l+4]) - l += 4 - e.Fd = fd - e.Size = Uint32(data[l : l+4]) - l += 4 - - i.keymapHandler(e) - case 1: - if i.enterHandler == nil { - return - } - var e KeyboardEnterEvent - l := 0 - e.Serial = Uint32(data[l : l+4]) - l += 4 - e.Surface = i.Context().GetProxy(Uint32(data[l : l+4])).(*Surface) - l += 4 - keysLen := int(Uint32(data[l : l+4])) - l += 4 - e.Keys = make([]byte, keysLen) - copy(e.Keys, data[l:l+keysLen]) - l += keysLen - - i.enterHandler(e) - case 2: - if i.leaveHandler == nil { - return - } - var e KeyboardLeaveEvent - l := 0 - e.Serial = Uint32(data[l : l+4]) - l += 4 - e.Surface = i.Context().GetProxy(Uint32(data[l : l+4])).(*Surface) - l += 4 - - i.leaveHandler(e) - case 3: - if i.keyHandler == nil { - return - } - var e KeyboardKeyEvent - l := 0 - e.Serial = Uint32(data[l : l+4]) - l += 4 - e.Time = Uint32(data[l : l+4]) - l += 4 - e.Key = Uint32(data[l : l+4]) - l += 4 - e.State = Uint32(data[l : l+4]) - l += 4 - - i.keyHandler(e) - case 4: - if i.modifiersHandler == nil { - return - } - var e KeyboardModifiersEvent - l := 0 - e.Serial = Uint32(data[l : l+4]) - l += 4 - e.ModsDepressed = Uint32(data[l : l+4]) - l += 4 - e.ModsLatched = Uint32(data[l : l+4]) - l += 4 - e.ModsLocked = Uint32(data[l : l+4]) - l += 4 - e.Group = Uint32(data[l : l+4]) - l += 4 - - i.modifiersHandler(e) - case 5: - if i.repeatInfoHandler == nil { - return - } - var e KeyboardRepeatInfoEvent - l := 0 - e.Rate = int32(Uint32(data[l : l+4])) - l += 4 - e.Delay = int32(Uint32(data[l : l+4])) - l += 4 - - i.repeatInfoHandler(e) - } -} - -// TouchInterfaceName is the name of the interface as it appears in the [client.Registry]. -// It can be used to match the [client.RegistryGlobalEvent.Interface] in the -// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies. -const TouchInterfaceName = "wl_touch" - -// Touch : touchscreen input device -// -// The wl_touch interface represents a touchscreen -// associated with a seat. -// -// Touch interactions can consist of one or more contacts. -// For each contact, a series of events is generated, starting -// with a down event, followed by zero or more motion events, -// and ending with an up event. Events relating to the same -// contact point can be identified by the ID of the sequence. -type Touch struct { - BaseProxy - downHandler TouchDownHandlerFunc - upHandler TouchUpHandlerFunc - motionHandler TouchMotionHandlerFunc - frameHandler TouchFrameHandlerFunc - cancelHandler TouchCancelHandlerFunc - shapeHandler TouchShapeHandlerFunc - orientationHandler TouchOrientationHandlerFunc -} - -// NewTouch : touchscreen input device -// -// The wl_touch interface represents a touchscreen -// associated with a seat. -// -// Touch interactions can consist of one or more contacts. -// For each contact, a series of events is generated, starting -// with a down event, followed by zero or more motion events, -// and ending with an up event. Events relating to the same -// contact point can be identified by the ID of the sequence. -func NewTouch(ctx *Context) *Touch { - wlTouch := &Touch{} - ctx.Register(wlTouch) - return wlTouch -} - -// Release : release the touch object -func (i *Touch) Release() error { - defer i.MarkZombie() - const opcode = 0 - const _reqBufLen = 8 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// TouchDownEvent : touch down event and beginning of a touch sequence -// -// A new touch point has appeared on the surface. This touch point is -// assigned a unique ID. Future events from this touch point reference -// this ID. The ID ceases to be valid after a touch up event and may be -// reused in the future. -type TouchDownEvent struct { - Serial uint32 - Time uint32 - Surface *Surface - Id int32 - X float64 - Y float64 -} -type TouchDownHandlerFunc func(TouchDownEvent) - -// SetDownHandler : sets handler for TouchDownEvent -func (i *Touch) SetDownHandler(f TouchDownHandlerFunc) { - i.downHandler = f -} - -// TouchUpEvent : end of a touch event sequence -// -// The touch point has disappeared. No further events will be sent for -// this touch point and the touch point's ID is released and may be -// reused in a future touch down event. -type TouchUpEvent struct { - Serial uint32 - Time uint32 - Id int32 -} -type TouchUpHandlerFunc func(TouchUpEvent) - -// SetUpHandler : sets handler for TouchUpEvent -func (i *Touch) SetUpHandler(f TouchUpHandlerFunc) { - i.upHandler = f -} - -// TouchMotionEvent : update of touch point coordinates -// -// A touch point has changed coordinates. -type TouchMotionEvent struct { - Time uint32 - Id int32 - X float64 - Y float64 -} -type TouchMotionHandlerFunc func(TouchMotionEvent) - -// SetMotionHandler : sets handler for TouchMotionEvent -func (i *Touch) SetMotionHandler(f TouchMotionHandlerFunc) { - i.motionHandler = f -} - -// TouchFrameEvent : end of touch frame event -// -// Indicates the end of a set of events that logically belong together. -// A client is expected to accumulate the data in all events within the -// frame before proceeding. -// -// A wl_touch.frame terminates at least one event but otherwise no -// guarantee is provided about the set of events within a frame. A client -// must assume that any state not updated in a frame is unchanged from the -// previously known state. -type TouchFrameEvent struct{} -type TouchFrameHandlerFunc func(TouchFrameEvent) - -// SetFrameHandler : sets handler for TouchFrameEvent -func (i *Touch) SetFrameHandler(f TouchFrameHandlerFunc) { - i.frameHandler = f -} - -// TouchCancelEvent : touch session cancelled -// -// Sent if the compositor decides the touch stream is a global -// gesture. No further events are sent to the clients from that -// particular gesture. Touch cancellation applies to all touch points -// currently active on this client's surface. The client is -// responsible for finalizing the touch points, future touch points on -// this surface may reuse the touch point ID. -// -// No frame event is required after the cancel event. -type TouchCancelEvent struct{} -type TouchCancelHandlerFunc func(TouchCancelEvent) - -// SetCancelHandler : sets handler for TouchCancelEvent -func (i *Touch) SetCancelHandler(f TouchCancelHandlerFunc) { - i.cancelHandler = f -} - -// TouchShapeEvent : update shape of touch point -// -// Sent when a touchpoint has changed its shape. -// -// This event does not occur on its own. It is sent before a -// wl_touch.frame event and carries the new shape information for -// any previously reported, or new touch points of that frame. -// -// Other events describing the touch point such as wl_touch.down, -// wl_touch.motion or wl_touch.orientation may be sent within the -// same wl_touch.frame. A client should treat these events as a single -// logical touch point update. The order of wl_touch.shape, -// wl_touch.orientation and wl_touch.motion is not guaranteed. -// A wl_touch.down event is guaranteed to occur before the first -// wl_touch.shape event for this touch ID but both events may occur within -// the same wl_touch.frame. -// -// A touchpoint shape is approximated by an ellipse through the major and -// minor axis length. The major axis length describes the longer diameter -// of the ellipse, while the minor axis length describes the shorter -// diameter. Major and minor are orthogonal and both are specified in -// surface-local coordinates. The center of the ellipse is always at the -// touchpoint location as reported by wl_touch.down or wl_touch.move. -// -// This event is only sent by the compositor if the touch device supports -// shape reports. The client has to make reasonable assumptions about the -// shape if it did not receive this event. -type TouchShapeEvent struct { - Id int32 - Major float64 - Minor float64 -} -type TouchShapeHandlerFunc func(TouchShapeEvent) - -// SetShapeHandler : sets handler for TouchShapeEvent -func (i *Touch) SetShapeHandler(f TouchShapeHandlerFunc) { - i.shapeHandler = f -} - -// TouchOrientationEvent : update orientation of touch point -// -// Sent when a touchpoint has changed its orientation. -// -// This event does not occur on its own. It is sent before a -// wl_touch.frame event and carries the new shape information for -// any previously reported, or new touch points of that frame. -// -// Other events describing the touch point such as wl_touch.down, -// wl_touch.motion or wl_touch.shape may be sent within the -// same wl_touch.frame. A client should treat these events as a single -// logical touch point update. The order of wl_touch.shape, -// wl_touch.orientation and wl_touch.motion is not guaranteed. -// A wl_touch.down event is guaranteed to occur before the first -// wl_touch.orientation event for this touch ID but both events may occur -// within the same wl_touch.frame. -// -// The orientation describes the clockwise angle of a touchpoint's major -// axis to the positive surface y-axis and is normalized to the -180 to -// +180 degree range. The granularity of orientation depends on the touch -// device, some devices only support binary rotation values between 0 and -// 90 degrees. -// -// This event is only sent by the compositor if the touch device supports -// orientation reports. -type TouchOrientationEvent struct { - Id int32 - Orientation float64 -} -type TouchOrientationHandlerFunc func(TouchOrientationEvent) - -// SetOrientationHandler : sets handler for TouchOrientationEvent -func (i *Touch) SetOrientationHandler(f TouchOrientationHandlerFunc) { - i.orientationHandler = f -} - -func (i *Touch) Dispatch(opcode uint32, fd int, data []byte) { - switch opcode { - case 0: - if i.downHandler == nil { - return - } - var e TouchDownEvent - l := 0 - e.Serial = Uint32(data[l : l+4]) - l += 4 - e.Time = Uint32(data[l : l+4]) - l += 4 - e.Surface = i.Context().GetProxy(Uint32(data[l : l+4])).(*Surface) - l += 4 - e.Id = int32(Uint32(data[l : l+4])) - l += 4 - e.X = Fixed(data[l : l+4]) - l += 4 - e.Y = Fixed(data[l : l+4]) - l += 4 - - i.downHandler(e) - case 1: - if i.upHandler == nil { - return - } - var e TouchUpEvent - l := 0 - e.Serial = Uint32(data[l : l+4]) - l += 4 - e.Time = Uint32(data[l : l+4]) - l += 4 - e.Id = int32(Uint32(data[l : l+4])) - l += 4 - - i.upHandler(e) - case 2: - if i.motionHandler == nil { - return - } - var e TouchMotionEvent - l := 0 - e.Time = Uint32(data[l : l+4]) - l += 4 - e.Id = int32(Uint32(data[l : l+4])) - l += 4 - e.X = Fixed(data[l : l+4]) - l += 4 - e.Y = Fixed(data[l : l+4]) - l += 4 - - i.motionHandler(e) - case 3: - if i.frameHandler == nil { - return - } - var e TouchFrameEvent - - i.frameHandler(e) - case 4: - if i.cancelHandler == nil { - return - } - var e TouchCancelEvent - - i.cancelHandler(e) - case 5: - if i.shapeHandler == nil { - return - } - var e TouchShapeEvent - l := 0 - e.Id = int32(Uint32(data[l : l+4])) - l += 4 - e.Major = Fixed(data[l : l+4]) - l += 4 - e.Minor = Fixed(data[l : l+4]) - l += 4 - - i.shapeHandler(e) - case 6: - if i.orientationHandler == nil { - return - } - var e TouchOrientationEvent - l := 0 - e.Id = int32(Uint32(data[l : l+4])) - l += 4 - e.Orientation = Fixed(data[l : l+4]) - l += 4 - - i.orientationHandler(e) - } -} - -// OutputInterfaceName is the name of the interface as it appears in the [client.Registry]. -// It can be used to match the [client.RegistryGlobalEvent.Interface] in the -// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies. -const OutputInterfaceName = "wl_output" - -// Output : compositor output region -// -// An output describes part of the compositor geometry. The -// compositor works in the 'compositor coordinate system' and an -// output corresponds to a rectangular area in that space that is -// actually visible. This typically corresponds to a monitor that -// displays part of the compositor space. This object is published -// as global during start up, or when a monitor is hotplugged. -type Output struct { - BaseProxy - geometryHandler OutputGeometryHandlerFunc - modeHandler OutputModeHandlerFunc - doneHandler OutputDoneHandlerFunc - scaleHandler OutputScaleHandlerFunc - nameHandler OutputNameHandlerFunc - descriptionHandler OutputDescriptionHandlerFunc -} - -// NewOutput : compositor output region -// -// An output describes part of the compositor geometry. The -// compositor works in the 'compositor coordinate system' and an -// output corresponds to a rectangular area in that space that is -// actually visible. This typically corresponds to a monitor that -// displays part of the compositor space. This object is published -// as global during start up, or when a monitor is hotplugged. -func NewOutput(ctx *Context) *Output { - wlOutput := &Output{} - ctx.Register(wlOutput) - return wlOutput -} - -// Release : release the output object -// -// Using this request a client can tell the server that it is not going to -// use the output object anymore. -func (i *Output) Release() error { - defer i.MarkZombie() - const opcode = 0 - const _reqBufLen = 8 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -type OutputSubpixel uint32 - -// OutputSubpixel : subpixel geometry information -// -// This enumeration describes how the physical -// pixels on an output are laid out. -const ( - // OutputSubpixelUnknown : unknown geometry - OutputSubpixelUnknown OutputSubpixel = 0 - // OutputSubpixelNone : no geometry - OutputSubpixelNone OutputSubpixel = 1 - // OutputSubpixelHorizontalRgb : horizontal RGB - OutputSubpixelHorizontalRgb OutputSubpixel = 2 - // OutputSubpixelHorizontalBgr : horizontal BGR - OutputSubpixelHorizontalBgr OutputSubpixel = 3 - // OutputSubpixelVerticalRgb : vertical RGB - OutputSubpixelVerticalRgb OutputSubpixel = 4 - // OutputSubpixelVerticalBgr : vertical BGR - OutputSubpixelVerticalBgr OutputSubpixel = 5 -) - -func (e OutputSubpixel) Name() string { - switch e { - case OutputSubpixelUnknown: - return "unknown" - case OutputSubpixelNone: - return "none" - case OutputSubpixelHorizontalRgb: - return "horizontal_rgb" - case OutputSubpixelHorizontalBgr: - return "horizontal_bgr" - case OutputSubpixelVerticalRgb: - return "vertical_rgb" - case OutputSubpixelVerticalBgr: - return "vertical_bgr" - default: - return "" - } -} - -func (e OutputSubpixel) Value() string { - switch e { - case OutputSubpixelUnknown: - return "0" - case OutputSubpixelNone: - return "1" - case OutputSubpixelHorizontalRgb: - return "2" - case OutputSubpixelHorizontalBgr: - return "3" - case OutputSubpixelVerticalRgb: - return "4" - case OutputSubpixelVerticalBgr: - return "5" - default: - return "" - } -} - -func (e OutputSubpixel) String() string { - return e.Name() + "=" + e.Value() -} - -type OutputTransform uint32 - -// OutputTransform : transformation applied to buffer contents -// -// This describes transformations that clients and compositors apply to -// buffer contents. -// -// The flipped values correspond to an initial flip around a -// vertical axis followed by rotation. -// -// The purpose is mainly to allow clients to render accordingly and -// tell the compositor, so that for fullscreen surfaces, the -// compositor will still be able to scan out directly from client -// surfaces. -const ( - // OutputTransformNormal : no transform - OutputTransformNormal OutputTransform = 0 - // OutputTransform90 : 90 degrees counter-clockwise - OutputTransform90 OutputTransform = 1 - // OutputTransform180 : 180 degrees counter-clockwise - OutputTransform180 OutputTransform = 2 - // OutputTransform270 : 270 degrees counter-clockwise - OutputTransform270 OutputTransform = 3 - // OutputTransformFlipped : 180 degree flip around a vertical axis - OutputTransformFlipped OutputTransform = 4 - // OutputTransformFlipped90 : flip and rotate 90 degrees counter-clockwise - OutputTransformFlipped90 OutputTransform = 5 - // OutputTransformFlipped180 : flip and rotate 180 degrees counter-clockwise - OutputTransformFlipped180 OutputTransform = 6 - // OutputTransformFlipped270 : flip and rotate 270 degrees counter-clockwise - OutputTransformFlipped270 OutputTransform = 7 -) - -func (e OutputTransform) Name() string { - switch e { - case OutputTransformNormal: - return "normal" - case OutputTransform90: - return "90" - case OutputTransform180: - return "180" - case OutputTransform270: - return "270" - case OutputTransformFlipped: - return "flipped" - case OutputTransformFlipped90: - return "flipped_90" - case OutputTransformFlipped180: - return "flipped_180" - case OutputTransformFlipped270: - return "flipped_270" - default: - return "" - } -} - -func (e OutputTransform) Value() string { - switch e { - case OutputTransformNormal: - return "0" - case OutputTransform90: - return "1" - case OutputTransform180: - return "2" - case OutputTransform270: - return "3" - case OutputTransformFlipped: - return "4" - case OutputTransformFlipped90: - return "5" - case OutputTransformFlipped180: - return "6" - case OutputTransformFlipped270: - return "7" - default: - return "" - } -} - -func (e OutputTransform) String() string { - return e.Name() + "=" + e.Value() -} - -type OutputMode uint32 - -// OutputMode : mode information -// -// These flags describe properties of an output mode. -// They are used in the flags bitfield of the mode event. -const ( - // OutputModeCurrent : indicates this is the current mode - OutputModeCurrent OutputMode = 0x1 - // OutputModePreferred : indicates this is the preferred mode - OutputModePreferred OutputMode = 0x2 -) - -func (e OutputMode) Name() string { - switch e { - case OutputModeCurrent: - return "current" - case OutputModePreferred: - return "preferred" - default: - return "" - } -} - -func (e OutputMode) Value() string { - switch e { - case OutputModeCurrent: - return "0x1" - case OutputModePreferred: - return "0x2" - default: - return "" - } -} - -func (e OutputMode) String() string { - return e.Name() + "=" + e.Value() -} - -// OutputGeometryEvent : properties of the output -// -// The geometry event describes geometric properties of the output. -// The event is sent when binding to the output object and whenever -// any of the properties change. -// -// The physical size can be set to zero if it doesn't make sense for this -// output (e.g. for projectors or virtual outputs). -// -// The geometry event will be followed by a done event (starting from -// version 2). -// -// Clients should use wl_surface.preferred_buffer_transform instead of the -// transform advertised by this event to find the preferred buffer -// transform to use for a surface. -// -// Note: wl_output only advertises partial information about the output -// position and identification. Some compositors, for instance those not -// implementing a desktop-style output layout or those exposing virtual -// outputs, might fake this information. Instead of using x and y, clients -// should use xdg_output.logical_position. Instead of using make and model, -// clients should use name and description. -type OutputGeometryEvent struct { - X int32 - Y int32 - PhysicalWidth int32 - PhysicalHeight int32 - Subpixel int32 - Make string - Model string - Transform int32 -} -type OutputGeometryHandlerFunc func(OutputGeometryEvent) - -// SetGeometryHandler : sets handler for OutputGeometryEvent -func (i *Output) SetGeometryHandler(f OutputGeometryHandlerFunc) { - i.geometryHandler = f -} - -// OutputModeEvent : advertise available modes for the output -// -// The mode event describes an available mode for the output. -// -// The event is sent when binding to the output object and there -// will always be one mode, the current mode. The event is sent -// again if an output changes mode, for the mode that is now -// current. In other words, the current mode is always the last -// mode that was received with the current flag set. -// -// Non-current modes are deprecated. A compositor can decide to only -// advertise the current mode and never send other modes. Clients -// should not rely on non-current modes. -// -// The size of a mode is given in physical hardware units of -// the output device. This is not necessarily the same as -// the output size in the global compositor space. For instance, -// the output may be scaled, as described in wl_output.scale, -// or transformed, as described in wl_output.transform. Clients -// willing to retrieve the output size in the global compositor -// space should use xdg_output.logical_size instead. -// -// The vertical refresh rate can be set to zero if it doesn't make -// sense for this output (e.g. for virtual outputs). -// -// The mode event will be followed by a done event (starting from -// version 2). -// -// Clients should not use the refresh rate to schedule frames. Instead, -// they should use the wl_surface.frame event or the presentation-time -// protocol. -// -// Note: this information is not always meaningful for all outputs. Some -// compositors, such as those exposing virtual outputs, might fake the -// refresh rate or the size. -type OutputModeEvent struct { - Flags uint32 - Width int32 - Height int32 - Refresh int32 -} -type OutputModeHandlerFunc func(OutputModeEvent) - -// SetModeHandler : sets handler for OutputModeEvent -func (i *Output) SetModeHandler(f OutputModeHandlerFunc) { - i.modeHandler = f -} - -// OutputDoneEvent : sent all information about output -// -// This event is sent after all other properties have been -// sent after binding to the output object and after any -// other property changes done after that. This allows -// changes to the output properties to be seen as -// atomic, even if they happen via multiple events. -type OutputDoneEvent struct{} -type OutputDoneHandlerFunc func(OutputDoneEvent) - -// SetDoneHandler : sets handler for OutputDoneEvent -func (i *Output) SetDoneHandler(f OutputDoneHandlerFunc) { - i.doneHandler = f -} - -// OutputScaleEvent : output scaling properties -// -// This event contains scaling geometry information -// that is not in the geometry event. It may be sent after -// binding the output object or if the output scale changes -// later. The compositor will emit a non-zero, positive -// value for scale. If it is not sent, the client should -// assume a scale of 1. -// -// A scale larger than 1 means that the compositor will -// automatically scale surface buffers by this amount -// when rendering. This is used for very high resolution -// displays where applications rendering at the native -// resolution would be too small to be legible. -// -// Clients should use wl_surface.preferred_buffer_scale -// instead of this event to find the preferred buffer -// scale to use for a surface. -// -// The scale event will be followed by a done event. -type OutputScaleEvent struct { - Factor int32 -} -type OutputScaleHandlerFunc func(OutputScaleEvent) - -// SetScaleHandler : sets handler for OutputScaleEvent -func (i *Output) SetScaleHandler(f OutputScaleHandlerFunc) { - i.scaleHandler = f -} - -// OutputNameEvent : name of this output -// -// Many compositors will assign user-friendly names to their outputs, show -// them to the user, allow the user to refer to an output, etc. The client -// may wish to know this name as well to offer the user similar behaviors. -// -// The name is a UTF-8 string with no convention defined for its contents. -// Each name is unique among all wl_output globals. The name is only -// guaranteed to be unique for the compositor instance. -// -// The same output name is used for all clients for a given wl_output -// global. Thus, the name can be shared across processes to refer to a -// specific wl_output global. -// -// The name is not guaranteed to be persistent across sessions, thus cannot -// be used to reliably identify an output in e.g. configuration files. -// -// Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc. However, do -// not assume that the name is a reflection of an underlying DRM connector, -// X11 connection, etc. -// -// The name event is sent after binding the output object. This event is -// only sent once per output object, and the name does not change over the -// lifetime of the wl_output global. -// -// Compositors may re-use the same output name if the wl_output global is -// destroyed and re-created later. Compositors should avoid re-using the -// same name if possible. -// -// The name event will be followed by a done event. -type OutputNameEvent struct { - Name string -} -type OutputNameHandlerFunc func(OutputNameEvent) - -// SetNameHandler : sets handler for OutputNameEvent -func (i *Output) SetNameHandler(f OutputNameHandlerFunc) { - i.nameHandler = f -} - -// OutputDescriptionEvent : human-readable description of this output -// -// Many compositors can produce human-readable descriptions of their -// outputs. The client may wish to know this description as well, e.g. for -// output selection purposes. -// -// The description is a UTF-8 string with no convention defined for its -// contents. The description is not guaranteed to be unique among all -// wl_output globals. Examples might include 'Foocorp 11" Display' or -// 'Virtual X11 output via :1'. -// -// The description event is sent after binding the output object and -// whenever the description changes. The description is optional, and may -// not be sent at all. -// -// The description event will be followed by a done event. -type OutputDescriptionEvent struct { - Description string -} -type OutputDescriptionHandlerFunc func(OutputDescriptionEvent) - -// SetDescriptionHandler : sets handler for OutputDescriptionEvent -func (i *Output) SetDescriptionHandler(f OutputDescriptionHandlerFunc) { - i.descriptionHandler = f -} - -func (i *Output) Dispatch(opcode uint32, fd int, data []byte) { - switch opcode { - case 0: - if i.geometryHandler == nil { - return - } - var e OutputGeometryEvent - l := 0 - e.X = int32(Uint32(data[l : l+4])) - l += 4 - e.Y = int32(Uint32(data[l : l+4])) - l += 4 - e.PhysicalWidth = int32(Uint32(data[l : l+4])) - l += 4 - e.PhysicalHeight = int32(Uint32(data[l : l+4])) - l += 4 - e.Subpixel = int32(Uint32(data[l : l+4])) - l += 4 - makeLen := PaddedLen(int(Uint32(data[l : l+4]))) - l += 4 - e.Make = String(data[l : l+makeLen]) - l += makeLen - modelLen := PaddedLen(int(Uint32(data[l : l+4]))) - l += 4 - e.Model = String(data[l : l+modelLen]) - l += modelLen - e.Transform = int32(Uint32(data[l : l+4])) - l += 4 - - i.geometryHandler(e) - case 1: - if i.modeHandler == nil { - return - } - var e OutputModeEvent - l := 0 - e.Flags = Uint32(data[l : l+4]) - l += 4 - e.Width = int32(Uint32(data[l : l+4])) - l += 4 - e.Height = int32(Uint32(data[l : l+4])) - l += 4 - e.Refresh = int32(Uint32(data[l : l+4])) - l += 4 - - i.modeHandler(e) - case 2: - if i.doneHandler == nil { - return - } - var e OutputDoneEvent - - i.doneHandler(e) - case 3: - if i.scaleHandler == nil { - return - } - var e OutputScaleEvent - l := 0 - e.Factor = int32(Uint32(data[l : l+4])) - l += 4 - - i.scaleHandler(e) - case 4: - if i.nameHandler == nil { - return - } - var e OutputNameEvent - l := 0 - nameLen := PaddedLen(int(Uint32(data[l : l+4]))) - l += 4 - e.Name = String(data[l : l+nameLen]) - l += nameLen - - i.nameHandler(e) - case 5: - if i.descriptionHandler == nil { - return - } - var e OutputDescriptionEvent - l := 0 - descriptionLen := PaddedLen(int(Uint32(data[l : l+4]))) - l += 4 - e.Description = String(data[l : l+descriptionLen]) - l += descriptionLen - - i.descriptionHandler(e) - } -} - -// RegionInterfaceName is the name of the interface as it appears in the [client.Registry]. -// It can be used to match the [client.RegistryGlobalEvent.Interface] in the -// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies. -const RegionInterfaceName = "wl_region" - -// Region : region interface -// -// A region object describes an area. -// -// Region objects are used to describe the opaque and input -// regions of a surface. -type Region struct { - BaseProxy -} - -// NewRegion : region interface -// -// A region object describes an area. -// -// Region objects are used to describe the opaque and input -// regions of a surface. -func NewRegion(ctx *Context) *Region { - wlRegion := &Region{} - ctx.Register(wlRegion) - return wlRegion -} - -// Destroy : destroy region -// -// Destroy the region. This will invalidate the object ID. -func (i *Region) Destroy() error { - defer i.MarkZombie() - const opcode = 0 - const _reqBufLen = 8 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// Add : add rectangle to region -// -// Add the specified rectangle to the region. -// -// x: region-local x coordinate -// y: region-local y coordinate -// width: rectangle width -// height: rectangle height -func (i *Region) Add(x, y, width, height int32) error { - const opcode = 1 - const _reqBufLen = 8 + 4 + 4 + 4 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(x)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(y)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(width)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(height)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// Subtract : subtract rectangle from region -// -// Subtract the specified rectangle from the region. -// -// x: region-local x coordinate -// y: region-local y coordinate -// width: rectangle width -// height: rectangle height -func (i *Region) Subtract(x, y, width, height int32) error { - const opcode = 2 - const _reqBufLen = 8 + 4 + 4 + 4 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(x)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(y)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(width)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(height)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// SubcompositorInterfaceName is the name of the interface as it appears in the [client.Registry]. -// It can be used to match the [client.RegistryGlobalEvent.Interface] in the -// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies. -const SubcompositorInterfaceName = "wl_subcompositor" - -// Subcompositor : sub-surface compositing -// -// The global interface exposing sub-surface compositing capabilities. -// A wl_surface, that has sub-surfaces associated, is called the -// parent surface. Sub-surfaces can be arbitrarily nested and create -// a tree of sub-surfaces. -// -// The root surface in a tree of sub-surfaces is the main -// surface. The main surface cannot be a sub-surface, because -// sub-surfaces must always have a parent. -// -// A main surface with its sub-surfaces forms a (compound) window. -// For window management purposes, this set of wl_surface objects is -// to be considered as a single window, and it should also behave as -// such. -// -// The aim of sub-surfaces is to offload some of the compositing work -// within a window from clients to the compositor. A prime example is -// a video player with decorations and video in separate wl_surface -// objects. This should allow the compositor to pass YUV video buffer -// processing to dedicated overlay hardware when possible. -type Subcompositor struct { - BaseProxy -} - -// NewSubcompositor : sub-surface compositing -// -// The global interface exposing sub-surface compositing capabilities. -// A wl_surface, that has sub-surfaces associated, is called the -// parent surface. Sub-surfaces can be arbitrarily nested and create -// a tree of sub-surfaces. -// -// The root surface in a tree of sub-surfaces is the main -// surface. The main surface cannot be a sub-surface, because -// sub-surfaces must always have a parent. -// -// A main surface with its sub-surfaces forms a (compound) window. -// For window management purposes, this set of wl_surface objects is -// to be considered as a single window, and it should also behave as -// such. -// -// The aim of sub-surfaces is to offload some of the compositing work -// within a window from clients to the compositor. A prime example is -// a video player with decorations and video in separate wl_surface -// objects. This should allow the compositor to pass YUV video buffer -// processing to dedicated overlay hardware when possible. -func NewSubcompositor(ctx *Context) *Subcompositor { - wlSubcompositor := &Subcompositor{} - ctx.Register(wlSubcompositor) - return wlSubcompositor -} - -// Destroy : unbind from the subcompositor interface -// -// Informs the server that the client will not be using this -// protocol object anymore. This does not affect any other -// objects, wl_subsurface objects included. -func (i *Subcompositor) Destroy() error { - defer i.MarkZombie() - const opcode = 0 - const _reqBufLen = 8 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// GetSubsurface : give a surface the role sub-surface -// -// Create a sub-surface interface for the given surface, and -// associate it with the given parent surface. This turns a -// plain wl_surface into a sub-surface. -// -// The to-be sub-surface must not already have another role, and it -// must not have an existing wl_subsurface object. Otherwise the -// bad_surface protocol error is raised. -// -// Adding sub-surfaces to a parent is a double-buffered operation on the -// parent (see wl_surface.commit). The effect of adding a sub-surface -// becomes visible on the next time the state of the parent surface is -// applied. -// -// The parent surface must not be one of the child surface's descendants, -// and the parent must be different from the child surface, otherwise the -// bad_parent protocol error is raised. -// -// This request modifies the behaviour of wl_surface.commit request on -// the sub-surface, see the documentation on wl_subsurface interface. -// -// surface: the surface to be turned into a sub-surface -// parent: the parent surface -func (i *Subcompositor) GetSubsurface(surface, parent *Surface) (*Subsurface, error) { - id := NewSubsurface(i.Context()) - const opcode = 1 - const _reqBufLen = 8 + 4 + 4 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], id.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], surface.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], parent.ID()) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return id, err -} - -type SubcompositorError uint32 - -// SubcompositorError : -const ( - // SubcompositorErrorBadSurface : the to-be sub-surface is invalid - SubcompositorErrorBadSurface SubcompositorError = 0 - // SubcompositorErrorBadParent : the to-be sub-surface parent is invalid - SubcompositorErrorBadParent SubcompositorError = 1 -) - -func (e SubcompositorError) Name() string { - switch e { - case SubcompositorErrorBadSurface: - return "bad_surface" - case SubcompositorErrorBadParent: - return "bad_parent" - default: - return "" - } -} - -func (e SubcompositorError) Value() string { - switch e { - case SubcompositorErrorBadSurface: - return "0" - case SubcompositorErrorBadParent: - return "1" - default: - return "" - } -} - -func (e SubcompositorError) String() string { - return e.Name() + "=" + e.Value() -} - -// SubsurfaceInterfaceName is the name of the interface as it appears in the [client.Registry]. -// It can be used to match the [client.RegistryGlobalEvent.Interface] in the -// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies. -const SubsurfaceInterfaceName = "wl_subsurface" - -// Subsurface : sub-surface interface to a wl_surface -// -// An additional interface to a wl_surface object, which has been -// made a sub-surface. A sub-surface has one parent surface. A -// sub-surface's size and position are not limited to that of the parent. -// Particularly, a sub-surface is not automatically clipped to its -// parent's area. -// -// A sub-surface becomes mapped, when a non-NULL wl_buffer is applied -// and the parent surface is mapped. The order of which one happens -// first is irrelevant. A sub-surface is hidden if the parent becomes -// hidden, or if a NULL wl_buffer is applied. These rules apply -// recursively through the tree of surfaces. -// -// The behaviour of a wl_surface.commit request on a sub-surface -// depends on the sub-surface's mode. The possible modes are -// synchronized and desynchronized, see methods -// wl_subsurface.set_sync and wl_subsurface.set_desync. Synchronized -// mode caches the wl_surface state to be applied when the parent's -// state gets applied, and desynchronized mode applies the pending -// wl_surface state directly. A sub-surface is initially in the -// synchronized mode. -// -// Sub-surfaces also have another kind of state, which is managed by -// wl_subsurface requests, as opposed to wl_surface requests. This -// state includes the sub-surface position relative to the parent -// surface (wl_subsurface.set_position), and the stacking order of -// the parent and its sub-surfaces (wl_subsurface.place_above and -// .place_below). This state is applied when the parent surface's -// wl_surface state is applied, regardless of the sub-surface's mode. -// As the exception, set_sync and set_desync are effective immediately. -// -// The main surface can be thought to be always in desynchronized mode, -// since it does not have a parent in the sub-surfaces sense. -// -// Even if a sub-surface is in desynchronized mode, it will behave as -// in synchronized mode, if its parent surface behaves as in -// synchronized mode. This rule is applied recursively throughout the -// tree of surfaces. This means, that one can set a sub-surface into -// synchronized mode, and then assume that all its child and grand-child -// sub-surfaces are synchronized, too, without explicitly setting them. -// -// Destroying a sub-surface takes effect immediately. If you need to -// synchronize the removal of a sub-surface to the parent surface update, -// unmap the sub-surface first by attaching a NULL wl_buffer, update parent, -// and then destroy the sub-surface. -// -// If the parent wl_surface object is destroyed, the sub-surface is -// unmapped. -// -// A sub-surface never has the keyboard focus of any seat. -// -// The wl_surface.offset request is ignored: clients must use set_position -// instead to move the sub-surface. -type Subsurface struct { - BaseProxy -} - -// NewSubsurface : sub-surface interface to a wl_surface -// -// An additional interface to a wl_surface object, which has been -// made a sub-surface. A sub-surface has one parent surface. A -// sub-surface's size and position are not limited to that of the parent. -// Particularly, a sub-surface is not automatically clipped to its -// parent's area. -// -// A sub-surface becomes mapped, when a non-NULL wl_buffer is applied -// and the parent surface is mapped. The order of which one happens -// first is irrelevant. A sub-surface is hidden if the parent becomes -// hidden, or if a NULL wl_buffer is applied. These rules apply -// recursively through the tree of surfaces. -// -// The behaviour of a wl_surface.commit request on a sub-surface -// depends on the sub-surface's mode. The possible modes are -// synchronized and desynchronized, see methods -// wl_subsurface.set_sync and wl_subsurface.set_desync. Synchronized -// mode caches the wl_surface state to be applied when the parent's -// state gets applied, and desynchronized mode applies the pending -// wl_surface state directly. A sub-surface is initially in the -// synchronized mode. -// -// Sub-surfaces also have another kind of state, which is managed by -// wl_subsurface requests, as opposed to wl_surface requests. This -// state includes the sub-surface position relative to the parent -// surface (wl_subsurface.set_position), and the stacking order of -// the parent and its sub-surfaces (wl_subsurface.place_above and -// .place_below). This state is applied when the parent surface's -// wl_surface state is applied, regardless of the sub-surface's mode. -// As the exception, set_sync and set_desync are effective immediately. -// -// The main surface can be thought to be always in desynchronized mode, -// since it does not have a parent in the sub-surfaces sense. -// -// Even if a sub-surface is in desynchronized mode, it will behave as -// in synchronized mode, if its parent surface behaves as in -// synchronized mode. This rule is applied recursively throughout the -// tree of surfaces. This means, that one can set a sub-surface into -// synchronized mode, and then assume that all its child and grand-child -// sub-surfaces are synchronized, too, without explicitly setting them. -// -// Destroying a sub-surface takes effect immediately. If you need to -// synchronize the removal of a sub-surface to the parent surface update, -// unmap the sub-surface first by attaching a NULL wl_buffer, update parent, -// and then destroy the sub-surface. -// -// If the parent wl_surface object is destroyed, the sub-surface is -// unmapped. -// -// A sub-surface never has the keyboard focus of any seat. -// -// The wl_surface.offset request is ignored: clients must use set_position -// instead to move the sub-surface. -func NewSubsurface(ctx *Context) *Subsurface { - wlSubsurface := &Subsurface{} - ctx.Register(wlSubsurface) - return wlSubsurface -} - -// Destroy : remove sub-surface interface -// -// The sub-surface interface is removed from the wl_surface object -// that was turned into a sub-surface with a -// wl_subcompositor.get_subsurface request. The wl_surface's association -// to the parent is deleted. The wl_surface is unmapped immediately. -func (i *Subsurface) Destroy() error { - defer i.MarkZombie() - const opcode = 0 - const _reqBufLen = 8 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// SetPosition : reposition the sub-surface -// -// This schedules a sub-surface position change. -// The sub-surface will be moved so that its origin (top left -// corner pixel) will be at the location x, y of the parent surface -// coordinate system. The coordinates are not restricted to the parent -// surface area. Negative values are allowed. -// -// The scheduled coordinates will take effect whenever the state of the -// parent surface is applied. -// -// If more than one set_position request is invoked by the client before -// the commit of the parent surface, the position of a new request always -// replaces the scheduled position from any previous request. -// -// The initial position is 0, 0. -// -// x: x coordinate in the parent surface -// y: y coordinate in the parent surface -func (i *Subsurface) SetPosition(x, y int32) error { - const opcode = 1 - const _reqBufLen = 8 + 4 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(x)) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(y)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// PlaceAbove : restack the sub-surface -// -// This sub-surface is taken from the stack, and put back just -// above the reference surface, changing the z-order of the sub-surfaces. -// The reference surface must be one of the sibling surfaces, or the -// parent surface. Using any other surface, including this sub-surface, -// will cause a protocol error. -// -// The z-order is double-buffered. Requests are handled in order and -// applied immediately to a pending state. The final pending state is -// copied to the active state the next time the state of the parent -// surface is applied. -// -// A new sub-surface is initially added as the top-most in the stack -// of its siblings and parent. -// -// sibling: the reference surface -func (i *Subsurface) PlaceAbove(sibling *Surface) error { - const opcode = 2 - const _reqBufLen = 8 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], sibling.ID()) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// PlaceBelow : restack the sub-surface -// -// The sub-surface is placed just below the reference surface. -// See wl_subsurface.place_above. -// -// sibling: the reference surface -func (i *Subsurface) PlaceBelow(sibling *Surface) error { - const opcode = 3 - const _reqBufLen = 8 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], sibling.ID()) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// SetSync : set sub-surface to synchronized mode -// -// Change the commit behaviour of the sub-surface to synchronized -// mode, also described as the parent dependent mode. -// -// In synchronized mode, wl_surface.commit on a sub-surface will -// accumulate the committed state in a cache, but the state will -// not be applied and hence will not change the compositor output. -// The cached state is applied to the sub-surface immediately after -// the parent surface's state is applied. This ensures atomic -// updates of the parent and all its synchronized sub-surfaces. -// Applying the cached state will invalidate the cache, so further -// parent surface commits do not (re-)apply old state. -// -// See wl_subsurface for the recursive effect of this mode. -func (i *Subsurface) SetSync() error { - const opcode = 4 - const _reqBufLen = 8 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// SetDesync : set sub-surface to desynchronized mode -// -// Change the commit behaviour of the sub-surface to desynchronized -// mode, also described as independent or freely running mode. -// -// In desynchronized mode, wl_surface.commit on a sub-surface will -// apply the pending state directly, without caching, as happens -// normally with a wl_surface. Calling wl_surface.commit on the -// parent surface has no effect on the sub-surface's wl_surface -// state. This mode allows a sub-surface to be updated on its own. -// -// If cached state exists when wl_surface.commit is called in -// desynchronized mode, the pending state is added to the cached -// state, and applied as a whole. This invalidates the cache. -// -// Note: even if a sub-surface is set to desynchronized, a parent -// sub-surface may override it to behave as synchronized. For details, -// see wl_subsurface. -// -// If a surface's parent surface behaves as desynchronized, then -// the cached state is applied on set_desync. -func (i *Subsurface) SetDesync() error { - const opcode = 5 - const _reqBufLen = 8 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -type SubsurfaceError uint32 - -// SubsurfaceError : -const ( - // SubsurfaceErrorBadSurface : wl_surface is not a sibling or the parent - SubsurfaceErrorBadSurface SubsurfaceError = 0 -) - -func (e SubsurfaceError) Name() string { - switch e { - case SubsurfaceErrorBadSurface: - return "bad_surface" - default: - return "" - } -} - -func (e SubsurfaceError) Value() string { - switch e { - case SubsurfaceErrorBadSurface: - return "0" - default: - return "" - } -} - -func (e SubsurfaceError) String() string { - return e.Name() + "=" + e.Value() -} - -// FixesInterfaceName is the name of the interface as it appears in the [client.Registry]. -// It can be used to match the [client.RegistryGlobalEvent.Interface] in the -// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies. -const FixesInterfaceName = "wl_fixes" - -// Fixes : wayland protocol fixes -// -// This global fixes problems with other core-protocol interfaces that -// cannot be fixed in these interfaces themselves. -type Fixes struct { - BaseProxy -} - -// NewFixes : wayland protocol fixes -// -// This global fixes problems with other core-protocol interfaces that -// cannot be fixed in these interfaces themselves. -func NewFixes(ctx *Context) *Fixes { - wlFixes := &Fixes{} - ctx.Register(wlFixes) - return wlFixes -} - -// Destroy : destroys this object -func (i *Fixes) Destroy() error { - defer i.MarkZombie() - const opcode = 0 - const _reqBufLen = 8 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} - -// DestroyRegistry : destroy a wl_registry -// -// This request destroys a wl_registry object. -// -// The client should no longer use the wl_registry after making this -// request. -// -// The compositor will emit a wl_display.delete_id event with the object ID -// of the registry and will no longer emit any events on the registry. The -// client should re-use the object ID once it receives the -// wl_display.delete_id event. -// -// registry: the registry to destroy -func (i *Fixes) DestroyRegistry(registry *Registry) error { - const opcode = 1 - const _reqBufLen = 8 + 4 - var _reqBuf [_reqBufLen]byte - l := 0 - PutUint32(_reqBuf[l:4], i.ID()) - l += 4 - PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff)) - l += 4 - PutUint32(_reqBuf[l:l+4], registry.ID()) - l += 4 - err := i.Context().WriteMsg(_reqBuf[:], nil) - return err -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/common.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/common.go deleted file mode 100644 index b97d1b8..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/common.go +++ /dev/null @@ -1,55 +0,0 @@ -package client - -import "sync/atomic" - -type Dispatcher interface { - Dispatch(opcode uint32, fd int, data []byte) -} - -type Proxy interface { - Context() *Context - SetContext(ctx *Context) - ID() uint32 - SetID(id uint32) - IsZombie() bool - MarkZombie() -} - -type WaylandDisplay interface { - Context() *Context - GetRegistry() (*Registry, error) - Roundtrip() error - Destroy() error -} - -var _ WaylandDisplay = (*Display)(nil) - -type BaseProxy struct { - ctx *Context - id uint32 - zombie atomic.Bool -} - -func (p *BaseProxy) ID() uint32 { - return p.id -} - -func (p *BaseProxy) SetID(id uint32) { - p.id = id -} - -func (p *BaseProxy) Context() *Context { - return p.ctx -} - -func (p *BaseProxy) SetContext(ctx *Context) { - p.ctx = ctx -} - -func (p *BaseProxy) IsZombie() bool { - return p.zombie.Load() -} - -func (p *BaseProxy) MarkZombie() { - p.zombie.Store(true) -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/context.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/context.go deleted file mode 100644 index 4eee2cb..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/context.go +++ /dev/null @@ -1,143 +0,0 @@ -package client - -import ( - "errors" - "fmt" - "net" - "os" - "sync" - "time" - - "github.com/AvengeMedia/DankMaterialShell/core/pkg/syncmap" -) - -type Context struct { - conn *net.UnixConn - objects syncmap.Map[uint32, Proxy] // map[uint32]Proxy - thread-safe concurrent map - currentID uint32 - idMu sync.Mutex // protects currentID increment -} - -func (ctx *Context) Register(p Proxy) { - ctx.idMu.Lock() - ctx.currentID++ - id := ctx.currentID - ctx.idMu.Unlock() - - p.SetID(id) - p.SetContext(ctx) - ctx.objects.Store(id, p) -} - -func (ctx *Context) RegisterWithID(p Proxy, id uint32) { - p.SetID(id) - p.SetContext(ctx) - ctx.objects.Store(id, p) -} - -func (ctx *Context) Unregister(p Proxy) { - ctx.objects.Delete(p.ID()) -} - -func (ctx *Context) DeleteID(id uint32) { - ctx.objects.Delete(id) -} - -func (ctx *Context) GetProxy(id uint32) Proxy { - if val, ok := ctx.objects.Load(id); ok { - return val - } - return nil -} - -func (ctx *Context) Close() error { - return ctx.conn.Close() -} - -func (ctx *Context) SetReadDeadline(t time.Time) error { - return ctx.conn.SetReadDeadline(t) -} - -func (ctx *Context) Fd() int { - rawConn, err := ctx.conn.SyscallConn() - if err != nil { - return -1 - } - var fd int - rawConn.Control(func(f uintptr) { - fd = int(f) - }) - return fd -} - -// Dispatch reads and processes incoming messages and calls [client.Dispatcher.Dispatch] on the -// respective wayland protocol. -// Dispatch must be called on the same goroutine as other interactions with the Context. -// If a multi goroutine approach is desired, use [Context.GetDispatch] instead. -// Dispatch blocks if there are no incoming messages. -// A Dispatch loop is usually used to handle incoming messages. -func (ctx *Context) Dispatch() error { - return ctx.GetDispatch()() -} - -var ErrDispatchSenderNotFound = errors.New("dispatch: unable to find sender") -var ErrDispatchSenderUnsupported = errors.New("dispatch: sender does not implement Dispatch method") -var ErrDispatchUnableToReadMsg = errors.New("dispatch: unable to read msg") - -// GetDispatch reads incoming messages and returns the dispatch function which calls -// [client.Dispatcher.Dispatch] on the respective wayland protocol. -// This function is now thread-safe and can be called from multiple goroutines. -// GetDispatch blocks if there are no incoming messages. -func (ctx *Context) GetDispatch() func() error { - senderID, opcode, fd, data, err := ctx.ReadMsg() // Blocks if there are no incoming messages - if err != nil { - return func() error { - return fmt.Errorf("%w: %w", ErrDispatchUnableToReadMsg, err) - } - } - - return func() error { - proxy, ok := ctx.objects.Load(senderID) - if !ok { - return nil // Proxy already deleted via delete_id, silently ignore - } - - if proxy.IsZombie() { - return nil // Zombie proxy, discard late events - } - - sender, ok := proxy.(Dispatcher) - if !ok { - return fmt.Errorf("%w (senderID=%d)", ErrDispatchSenderUnsupported, senderID) - } - - sender.Dispatch(opcode, fd, data) - return nil - } -} - -func Connect(addr string) (*Display, error) { - if addr == "" { - runtimeDir := os.Getenv("XDG_RUNTIME_DIR") - if runtimeDir == "" { - return nil, errors.New("env XDG_RUNTIME_DIR not set") - } - if addr == "" { - addr = os.Getenv("WAYLAND_DISPLAY") - } - if addr == "" { - addr = "wayland-0" - } - addr = runtimeDir + "/" + addr - } - - ctx := &Context{} - - conn, err := net.DialUnix("unix", nil, &net.UnixAddr{Name: addr, Net: "unix"}) - if err != nil { - return nil, err - } - ctx.conn = conn - - return NewDisplay(ctx), nil -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/context_test.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/context_test.go deleted file mode 100644 index 380d7da..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/context_test.go +++ /dev/null @@ -1,111 +0,0 @@ -package client_test - -import ( - "errors" - "fmt" - "log" - - "github.com/AvengeMedia/DankMaterialShell/core/pkg/go-wayland/wayland/client" -) - -// Shows a dispatch loop that will block the goroutine. -// This approach has no risk of data races but the loop blocks the goroutine when no messages are -// received. This can be a valid approach if there are no more changes that need to be made after -// setting up and starting the loop. -// For a multi goroutine approach, use [client.Context.GetDispatch]. -func ExampleContext_Dispatch() { - display, err := client.Connect("") - if err != nil { - log.Fatalf("Error connecting to Wayland server: %v", err) - } - - registry, err := display.GetRegistry() - if err != nil { - log.Fatalf("Error getting Wayland registry: %v", err) - } - - var seat *client.Seat - registry.SetGlobalHandler(func(e client.RegistryGlobalEvent) { - switch e.Interface { - case client.SeatInterfaceName: - seat = client.NewSeat(display.Context()) - err := registry.Bind(e.Name, e.Interface, e.Version, seat) - if err != nil { - log.Fatalf("unable to bind %s interface: %v", client.SeatInterfaceName, err) - } - } - }) - display.Roundtrip() - display.Roundtrip() - - keyboard, err := seat.GetKeyboard() - if err != nil { - log.Printf("Error getting keyboard: %v", err) - } - log.Printf("Got keyboard: %v\n", keyboard) - - for { - err := display.Context().Dispatch() - if err != nil { - log.Printf("Dispatch error: %v\n", err) - } - } -} - -// Shows how the dispatch loop can be done in another goroutine. -// This prevents the goroutine from being blocked and allows making changes to wayland objects while -// the dispatch loop is blocking another goroutine. -func ExampleContext_GetDispatch() { - display, err := client.Connect("") - if err != nil { - log.Fatalf("Error connecting to Wayland server: %v", err) - } - - registry, err := display.GetRegistry() - if err != nil { - log.Fatalf("Error getting Wayland registry: %v", err) - } - - var seat *client.Seat - registry.SetGlobalHandler(func(e client.RegistryGlobalEvent) { - switch e.Interface { - case client.SeatInterfaceName: - seat = client.NewSeat(display.Context()) - err := registry.Bind(e.Name, e.Interface, e.Version, seat) - if err != nil { - log.Fatalf("unable to bind %s interface: %v", client.SeatInterfaceName, err) - } - } - }) - display.Roundtrip() - display.Roundtrip() - dispatchQueue := make(chan func() error) - - go func() { - for { - dispatchQueue <- display.Context().GetDispatch() - } - }() - - keyboard, err := seat.GetKeyboard() - if err != nil { - log.Printf("Error getting keyboard: %v", err) - } - log.Printf("Got keyboard: %v\n", keyboard) - - err = errors.Join(keyboard.Release(), seat.Release(), display.Context().Close()) - if err != nil { - fmt.Printf("Error cleaning up: %v\n", err) - } - - for { - select { - // Add other cases here to do other things - case dispatchFunc := <-dispatchQueue: - err := dispatchFunc() - if err != nil { - log.Printf("Dispatch error: %v\n", err) - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/display.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/display.go deleted file mode 100644 index fa2af6f..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/display.go +++ /dev/null @@ -1,37 +0,0 @@ -package client - -import ( - "fmt" - "log" -) - -// Roundtrip blocks until all pending request are processed by the server. -// It is the implementation of [wl_display_roundtrip]. -// -// [wl_display_roundtrip]: https://wayland.freedesktop.org/docs/html/apb.html#Client-classwl__display_1ab60f38c2f80980ac84f347e932793390 -func (i *Display) Roundtrip() error { - callback, err := i.Sync() - if err != nil { - return fmt.Errorf("unable to get sync callback: %w", err) - } - defer func() { - if err2 := callback.Destroy(); err2 != nil { - log.Printf("unable to destroy callback: %v\n", err2) - } - }() - - done := false - callback.SetDoneHandler(func(_ CallbackDoneEvent) { - done = true - }) - - // Wait for callback to return - for !done { - err := i.Context().GetDispatch()() - if err != nil { - return fmt.Errorf("roundtrip: failed to dispatch: %w", err) - } - } - - return nil -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/doc.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/doc.go deleted file mode 100644 index 91137f9..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// Package client is Go port of wayland-client library -// for writing pure Go GUI software for wayland supported -// platforms. -package client - -//go:generate go run github.com/yaslama/go-wayland/cmd/go-wayland-scanner -pkg client -prefix wl -o client.go -i https://gitlab.freedesktop.org/wayland/wayland/-/raw/1.23.0/protocol/wayland.xml?ref_type=tags diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/event.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/event.go deleted file mode 100644 index e7b5cb8..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/event.go +++ /dev/null @@ -1,120 +0,0 @@ -package client - -import ( - "bytes" - "fmt" - "unsafe" - - "golang.org/x/sys/unix" - - _ "unsafe" -) - -var oobSpace = unix.CmsgSpace(4) - -func (ctx *Context) ReadMsg() (senderID uint32, opcode uint32, fd int, msg []byte, err error) { - fd = -1 - - oob := make([]byte, oobSpace) - header := make([]byte, 8) - - n, oobn, _, _, err := ctx.conn.ReadMsgUnix(header, oob) - if err != nil { - return senderID, opcode, fd, msg, err - } - if n != 8 { - return senderID, opcode, fd, msg, fmt.Errorf("ctx.ReadMsg: incorrect number of bytes read for header (n=%d)", n) - } - - if oobn > 0 { - fds, err := getFdsFromOob(oob, oobn, "header") - if err != nil { - return senderID, opcode, fd, msg, fmt.Errorf("ctx.ReadMsg: %w", err) - } - - if len(fds) > 0 { - fd = fds[0] - } - } - - senderID = Uint32(header[:4]) - opcodeAndSize := Uint32(header[4:8]) - opcode = opcodeAndSize & 0xffff - size := opcodeAndSize >> 16 - - msgSize := int(size) - 8 - if msgSize == 0 { - return senderID, opcode, fd, nil, nil - } - - msg = make([]byte, msgSize) - - if fd == -1 { - // if something was read before, then zero it out - if oobn > 0 { - oob = make([]byte, oobSpace) - } - - n, oobn, _, _, err = ctx.conn.ReadMsgUnix(msg, oob) - } else { - n, err = ctx.conn.Read(msg) - } - if err != nil { - return senderID, opcode, fd, msg, fmt.Errorf("ctx.ReadMsg: %w", err) - } - if n != msgSize { - return senderID, opcode, fd, msg, fmt.Errorf("ctx.ReadMsg: incorrect number of bytes read for msg (n=%d, msgSize=%d)", n, msgSize) - } - - if fd == -1 && oobn > 0 { - fds, err := getFdsFromOob(oob, oobn, "msg") - if err != nil { - return senderID, opcode, fd, msg, fmt.Errorf("ctx.ReadMsg: %w", err) - } - - if len(fds) > 0 { - fd = fds[0] - } - } - - return senderID, opcode, fd, msg, nil -} - -func getFdsFromOob(oob []byte, oobn int, source string) ([]int, error) { - if oobn > len(oob) { - return nil, fmt.Errorf("getFdsFromOob: incorrect number of bytes read from %s for oob (oobn=%d)", source, oobn) - } - scms, err := unix.ParseSocketControlMessage(oob) - if err != nil { - return nil, fmt.Errorf("getFdsFromOob: unable to parse control message from %s: %w", source, err) - } - - var fdsRet []int - for _, scm := range scms { - fds, err := unix.ParseUnixRights(&scm) - if err != nil { - return nil, fmt.Errorf("getFdsFromOob: unable to parse unix rights from %s: %w", source, err) - } - - fdsRet = append(fdsRet, fds...) - } - - return fdsRet, nil -} - -func Uint32(src []byte) uint32 { - _ = src[3] - return *(*uint32)(unsafe.Pointer(&src[0])) -} - -func String(src []byte) string { - idx := bytes.IndexByte(src, 0) - src = src[:idx:idx] - return *(*string)(unsafe.Pointer(&src)) -} - -func Fixed(src []byte) float64 { - _ = src[3] - fx := *(*int32)(unsafe.Pointer(&src[0])) - return fixedToFloat64(fx) -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/request.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/request.go deleted file mode 100644 index 3ca2317..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/request.go +++ /dev/null @@ -1,44 +0,0 @@ -package client - -import ( - "fmt" - "unsafe" -) - -func (ctx *Context) WriteMsg(b []byte, oob []byte) error { - n, oobn, err := ctx.conn.WriteMsgUnix(b, oob, nil) - if err != nil { - return err - } - if n != len(b) || oobn != len(oob) { - return fmt.Errorf("ctx.WriteMsg: incorrect number of bytes written (n=%d oobn=%d)", n, oobn) - } - - return nil -} - -func PutUint32(dst []byte, v uint32) { - _ = dst[3] - *(*uint32)(unsafe.Pointer(&dst[0])) = v -} - -func PutFixed(dst []byte, f float64) { - fx := fixedFromfloat64(f) - _ = dst[3] - *(*int32)(unsafe.Pointer(&dst[0])) = fx -} - -// PutString places a string in Wayland's wire format on the destination buffer. -// It first places the length of the string (plus one for the null terminator) and then the string -// followed by a null byte. -// The length of dst must be equal to, or greater than, len(v) + 5. -func PutString(dst []byte, v string) { - PutUint32(dst[:4], uint32(len(v)+1)) - copy(dst[4:], v) - dst[4+len(v)] = '\x00' // To cause panic if dst is not large enough -} - -func PutArray(dst []byte, a []byte) { - PutUint32(dst[:4], uint32(len(a))) - copy(dst[4:], a) -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/util.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/util.go deleted file mode 100644 index ba3d43a..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/client/util.go +++ /dev/null @@ -1,24 +0,0 @@ -package client - -import "math" - -// From wayland/wayland-util.h - -func fixedToFloat64(f int32) float64 { - u_i := (1023+44)<<52 + (1 << 51) + int64(f) - u_d := math.Float64frombits(uint64(u_i)) - return u_d - (3 << 43) -} - -func fixedFromfloat64(d float64) int32 { - u_d := d + (3 << (51 - 8)) - u_i := int64(math.Float64bits(u_d)) - return int32(u_i) -} - -func PaddedLen(l int) int { - if (l & 0x3) != 0 { - return l + (4 - (l & 0x3)) - } - return l -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/stable/xdg-shell/xdg_shell.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/stable/xdg-shell/xdg_shell.go deleted file mode 100644 index 19a203b..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/go-wayland/wayland/stable/xdg-shell/xdg_shell.go +++ /dev/null @@ -1,13 +0,0 @@ -package xdg_shell - -import "github.com/AvengeMedia/DankMaterialShell/core/pkg/go-wayland/wayland/client" - -type Popup struct { - client.BaseProxy -} - -func NewPopup(ctx *client.Context) *Popup { - p := &Popup{} - ctx.Register(p) - return p -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/CREDITS.MD b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/CREDITS.MD deleted file mode 100644 index b7d28cc..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/CREDITS.MD +++ /dev/null @@ -1,5 +0,0 @@ -# Credits - -* Original socket adapter code is mostly taken from [korylprince/printer-manager-cups](https://github.com/korylprince/printer-manager-cups) -([MIT](https://github.com/korylprince/printer-manager-cups/blob/v1.0.9/LICENSE) licensed): -[conn.go](https://github.com/korylprince/printer-manager-cups/blob/v1.0.9/cups/conn.go) diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/LICENSE b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/LICENSE deleted file mode 100644 index 261eeb9..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/adapter-http.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/adapter-http.go deleted file mode 100644 index 56ababb..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/adapter-http.go +++ /dev/null @@ -1,132 +0,0 @@ -package ipp - -import ( - "bytes" - "crypto/tls" - "fmt" - "io" - "net" - "net/http" - "strconv" - "time" -) - -type HttpAdapter struct { - host string - port int - username string - password string - useTLS bool - client *http.Client -} - -func NewHttpAdapter(host string, port int, username, password string, useTLS bool) *HttpAdapter { - httpClient := http.Client{ - Timeout: 0, - Transport: &http.Transport{ - TLSClientConfig: &tls.Config{ - InsecureSkipVerify: true, - }, - ResponseHeaderTimeout: 90 * time.Second, - IdleConnTimeout: 120 * time.Second, - }, - } - - return &HttpAdapter{ - host: host, - port: port, - username: username, - password: password, - useTLS: useTLS, - client: &httpClient, - } -} - -func (h *HttpAdapter) SendRequest(url string, req *Request, additionalResponseData io.Writer) (*Response, error) { - payload, err := req.Encode() - if err != nil { - return nil, err - } - - size := len(payload) - var body io.Reader - if req.File != nil && req.FileSize != -1 { - size += req.FileSize - body = io.MultiReader(bytes.NewBuffer(payload), req.File) - } else { - body = bytes.NewBuffer(payload) - } - - httpReq, err := http.NewRequest("POST", url, body) - if err != nil { - return nil, err - } - - httpReq.Header.Set("Content-Length", strconv.Itoa(size)) - httpReq.Header.Set("Content-Type", ContentTypeIPP) - - if h.username != "" && h.password != "" { - httpReq.SetBasicAuth(h.username, h.password) - } - - httpResp, err := h.client.Do(httpReq) - if err != nil { - return nil, err - } - defer httpResp.Body.Close() - - if httpResp.StatusCode != 200 { - return nil, HTTPError{ - Code: httpResp.StatusCode, - } - } - - // buffer response to avoid read issues - buf := new(bytes.Buffer) - if httpResp.ContentLength > 0 { - buf.Grow(int(httpResp.ContentLength)) - } - if _, err := io.Copy(buf, httpResp.Body); err != nil { - return nil, fmt.Errorf("unable to buffer response: %w", err) - } - - ippResp, err := NewResponseDecoder(buf).Decode(additionalResponseData) - if err != nil { - return nil, err - } - - if err = ippResp.CheckForErrors(); err != nil { - return nil, fmt.Errorf("received error IPP response: %w", err) - } - - return ippResp, nil -} - -func (h *HttpAdapter) GetHttpUri(namespace string, object any) string { - proto := "http" - if h.useTLS { - proto = "https" - } - - uri := fmt.Sprintf("%s://%s:%d", proto, h.host, h.port) - - if namespace != "" { - uri = fmt.Sprintf("%s/%s", uri, namespace) - } - - if object != nil { - uri = fmt.Sprintf("%s/%v", uri, object) - } - - return uri -} - -func (h *HttpAdapter) TestConnection() error { - conn, err := net.Dial("tcp", net.JoinHostPort(h.host, fmt.Sprintf("%d", h.port))) - if err != nil { - return err - } - conn.Close() - - return nil -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/adapter.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/adapter.go deleted file mode 100644 index 8af0520..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/adapter.go +++ /dev/null @@ -1,9 +0,0 @@ -package ipp - -import "io" - -type Adapter interface { - SendRequest(url string, req *Request, additionalResponseData io.Writer) (*Response, error) - GetHttpUri(namespace string, object any) string - TestConnection() error -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/attribute.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/attribute.go deleted file mode 100644 index 295f521..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/attribute.go +++ /dev/null @@ -1,528 +0,0 @@ -package ipp - -import ( - "encoding/binary" - "fmt" - "io" -) - -const ( - sizeInteger = int16(4) - sizeBoolean = int16(1) -) - -// AttributeEncoder encodes attribute to a io.Writer -type AttributeEncoder struct { - writer io.Writer -} - -// NewAttributeEncoder returns a new encoder that writes to w -func NewAttributeEncoder(w io.Writer) *AttributeEncoder { - return &AttributeEncoder{w} -} - -// Encode encodes a attribute and its value to a io.Writer -// the tag is determined by the AttributeTagMapping map -func (e *AttributeEncoder) Encode(attribute string, value any) error { - tag, ok := AttributeTagMapping[attribute] - if !ok { - return fmt.Errorf("cannot get tag of attribute %s", attribute) - } - - switch v := value.(type) { - case int: - if tag != TagInteger && tag != TagEnum { - return fmt.Errorf("tag for attribute %s does not match with value type", attribute) - } - - if err := e.encodeTag(tag); err != nil { - return err - } - - if err := e.encodeString(attribute); err != nil { - return err - } - - if err := e.encodeInteger(int32(v)); err != nil { - return err - } - case int16: - if tag != TagInteger && tag != TagEnum { - return fmt.Errorf("tag for attribute %s does not match with value type", attribute) - } - - if err := e.encodeTag(tag); err != nil { - return err - } - - if err := e.encodeString(attribute); err != nil { - return err - } - - if err := e.encodeInteger(int32(v)); err != nil { - return err - } - case int8: - if tag != TagInteger && tag != TagEnum { - return fmt.Errorf("tag for attribute %s does not match with value type", attribute) - } - - if err := e.encodeTag(tag); err != nil { - return err - } - - if err := e.encodeString(attribute); err != nil { - return err - } - - if err := e.encodeInteger(int32(v)); err != nil { - return err - } - case int32: - if tag != TagInteger && tag != TagEnum { - return fmt.Errorf("tag for attribute %s does not match with value type", attribute) - } - - if err := e.encodeTag(tag); err != nil { - return err - } - - if err := e.encodeString(attribute); err != nil { - return err - } - - if err := e.encodeInteger(v); err != nil { - return err - } - case int64: - if tag != TagInteger && tag != TagEnum { - return fmt.Errorf("tag for attribute %s does not match with value type", attribute) - } - - if err := e.encodeTag(tag); err != nil { - return err - } - - if err := e.encodeString(attribute); err != nil { - return err - } - - if err := e.encodeInteger(int32(v)); err != nil { - return err - } - case []int: - if tag != TagInteger && tag != TagEnum { - return fmt.Errorf("tag for attribute %s does not match with value type", attribute) - } - - for index, val := range v { - if err := e.encodeTag(tag); err != nil { - return err - } - - if index == 0 { - if err := e.encodeString(attribute); err != nil { - return err - } - } else { - if err := e.writeNullByte(); err != nil { - return err - } - } - - if err := e.encodeInteger(int32(val)); err != nil { - return err - } - } - case []int16: - if tag != TagInteger && tag != TagEnum { - return fmt.Errorf("tag for attribute %s does not match with value type", attribute) - } - - for index, val := range v { - if err := e.encodeTag(tag); err != nil { - return err - } - - if index == 0 { - if err := e.encodeString(attribute); err != nil { - return err - } - } else { - if err := e.writeNullByte(); err != nil { - return err - } - } - - if err := e.encodeInteger(int32(val)); err != nil { - return err - } - } - case []int8: - if tag != TagInteger && tag != TagEnum { - return fmt.Errorf("tag for attribute %s does not match with value type", attribute) - } - - for index, val := range v { - if err := e.encodeTag(tag); err != nil { - return err - } - - if index == 0 { - if err := e.encodeString(attribute); err != nil { - return err - } - } else { - if err := e.writeNullByte(); err != nil { - return err - } - } - - if err := e.encodeInteger(int32(val)); err != nil { - return err - } - } - case []int32: - if tag != TagInteger && tag != TagEnum { - return fmt.Errorf("tag for attribute %s does not match with value type", attribute) - } - - for index, val := range v { - if err := e.encodeTag(tag); err != nil { - return err - } - - if index == 0 { - if err := e.encodeString(attribute); err != nil { - return err - } - } else { - if err := e.writeNullByte(); err != nil { - return err - } - } - - if err := e.encodeInteger(val); err != nil { - return err - } - } - case []int64: - if tag != TagInteger && tag != TagEnum { - return fmt.Errorf("tag for attribute %s does not match with value type", attribute) - } - - for index, val := range v { - if err := e.encodeTag(tag); err != nil { - return err - } - - if index == 0 { - if err := e.encodeString(attribute); err != nil { - return err - } - } else { - if err := e.writeNullByte(); err != nil { - return err - } - } - - if err := e.encodeInteger(int32(val)); err != nil { - return err - } - } - case bool: - if tag != TagBoolean { - return fmt.Errorf("tag for attribute %s does not match with value type", attribute) - } - - if err := e.encodeTag(tag); err != nil { - return err - } - - if err := e.encodeString(attribute); err != nil { - return err - } - - if err := e.encodeBoolean(v); err != nil { - return err - } - case []bool: - if tag != TagBoolean { - return fmt.Errorf("tag for attribute %s does not match with value type", attribute) - } - - for index, val := range v { - if err := e.encodeTag(tag); err != nil { - return err - } - - if index == 0 { - if err := e.encodeString(attribute); err != nil { - return err - } - } else { - if err := e.writeNullByte(); err != nil { - return err - } - } - - if err := e.encodeBoolean(val); err != nil { - return err - } - } - case string: - if err := e.encodeTag(tag); err != nil { - return err - } - - if err := e.encodeString(attribute); err != nil { - return err - } - - if err := e.encodeString(v); err != nil { - return err - } - case []string: - for index, val := range v { - if err := e.encodeTag(tag); err != nil { - return err - } - - if index == 0 { - if err := e.encodeString(attribute); err != nil { - return err - } - } else { - if err := e.writeNullByte(); err != nil { - return err - } - } - - if err := e.encodeString(val); err != nil { - return err - } - } - default: - return fmt.Errorf("type %T is not supported", value) - } - - return nil -} - -func (e *AttributeEncoder) encodeString(s string) error { - if err := binary.Write(e.writer, binary.BigEndian, int16(len(s))); err != nil { - return err - } - - _, err := e.writer.Write([]byte(s)) - return err -} - -func (e *AttributeEncoder) encodeInteger(i int32) error { - if err := binary.Write(e.writer, binary.BigEndian, sizeInteger); err != nil { - return err - } - - return binary.Write(e.writer, binary.BigEndian, i) -} - -func (e *AttributeEncoder) encodeBoolean(b bool) error { - if err := binary.Write(e.writer, binary.BigEndian, sizeBoolean); err != nil { - return err - } - - return binary.Write(e.writer, binary.BigEndian, b) -} - -func (e *AttributeEncoder) encodeTag(t int8) error { - return binary.Write(e.writer, binary.BigEndian, t) -} - -func (e *AttributeEncoder) writeNullByte() error { - return binary.Write(e.writer, binary.BigEndian, int16(0)) -} - -// Attribute defines an ipp attribute -type Attribute struct { - Tag int8 - Name string - Value any -} - -// Resolution defines the resolution attribute -type Resolution struct { - Height int32 - Width int32 - Depth int8 -} - -// AttributeDecoder reads and decodes ipp from an input stream -type AttributeDecoder struct { - reader io.Reader -} - -// NewAttributeDecoder returns a new decoder that reads from r -func NewAttributeDecoder(r io.Reader) *AttributeDecoder { - return &AttributeDecoder{r} -} - -// Decode reads the next ipp attribute into a attribute struct. the type is identified by a tag passed as an argument -func (d *AttributeDecoder) Decode(tag int8) (*Attribute, error) { - attr := Attribute{Tag: tag} - - name, err := d.decodeString() - if err != nil { - return nil, err - } - attr.Name = name - - switch attr.Tag { - case TagEnum, TagInteger: - val, err := d.decodeInteger() - if err != nil { - return nil, err - } - attr.Value = val - case TagBoolean: - val, err := d.decodeBool() - if err != nil { - return nil, err - } - attr.Value = val - case TagDate: - val, err := d.decodeDate() - if err != nil { - return nil, err - } - attr.Value = val - case TagRange: - val, err := d.decodeRange() - if err != nil { - return nil, err - } - attr.Value = val - case TagResolution: - val, err := d.decodeResolution() - if err != nil { - return nil, err - } - attr.Value = val - default: - val, err := d.decodeString() - if err != nil { - return nil, err - } - attr.Value = val - } - - return &attr, nil -} - -func (d *AttributeDecoder) decodeBool() (b bool, err error) { - if _, err = d.readValueLength(); err != nil { - return - } - - if err = binary.Read(d.reader, binary.BigEndian, &b); err != nil { - return - } - - return -} - -func (d *AttributeDecoder) decodeInteger() (i int, err error) { - if _, err = d.readValueLength(); err != nil { - return - } - - var reti int32 - if err = binary.Read(d.reader, binary.BigEndian, &reti); err != nil { - return - } - - return int(reti), nil -} - -func (d *AttributeDecoder) decodeString() (string, error) { - length, err := d.readValueLength() - if err != nil { - return "", err - } - - if length == 0 { - return "", nil - } - - bs := make([]byte, length) - if _, err := d.reader.Read(bs); err != nil { - return "", nil - } - - return string(bs), nil -} - -func (d *AttributeDecoder) decodeDate() ([]int, error) { - length, err := d.readValueLength() - if err != nil { - return nil, err - } - - is := make([]int, length) - var ti int8 - - for i := int16(0); i < length; i++ { - if err = binary.Read(d.reader, binary.BigEndian, &ti); err != nil { - return nil, err - } - is[i] = int(ti) - } - - return is, nil -} - -func (d *AttributeDecoder) decodeRange() ([]int32, error) { - length, err := d.readValueLength() - if err != nil { - return nil, err - } - - // initialize range element count (c) and range slice (r) - c := length / 4 - r := make([]int32, c) - - for i := int16(0); i < c; i++ { - var ti int32 - if err = binary.Read(d.reader, binary.BigEndian, &ti); err != nil { - return nil, err - } - r[i] = ti - } - - return r, nil -} - -func (d *AttributeDecoder) decodeResolution() (res Resolution, err error) { - _, err = d.readValueLength() - if err != nil { - return - } - - if err = binary.Read(d.reader, binary.BigEndian, &res.Height); err != nil { - return - } - - if err = binary.Read(d.reader, binary.BigEndian, &res.Width); err != nil { - return - } - - if err = binary.Read(d.reader, binary.BigEndian, &res.Depth); err != nil { - return - } - - return -} - -func (d *AttributeDecoder) readValueLength() (length int16, err error) { - err = binary.Read(d.reader, binary.BigEndian, &length) - return -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/constants.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/constants.go deleted file mode 100644 index 83bf41b..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/constants.go +++ /dev/null @@ -1,450 +0,0 @@ -package ipp - -// ipp status codes -const ( - StatusCupsInvalid int16 = -1 - StatusOk int16 = 0x0000 - StatusOkIgnoredOrSubstituted int16 = 0x0001 - StatusOkConflicting int16 = 0x0002 - StatusOkIgnoredSubscriptions int16 = 0x0003 - StatusOkIgnoredNotifications int16 = 0x0004 - StatusOkTooManyEvents int16 = 0x0005 - StatusOkButCancelSubscription int16 = 0x0006 - StatusOkEventsComplete int16 = 0x0007 - StatusRedirectionOtherSite int16 = 0x0200 - StatusCupsSeeOther int16 = 0x0280 - StatusErrorBadRequest int16 = 0x0400 - StatusErrorForbidden int16 = 0x0401 - StatusErrorNotAuthenticated int16 = 0x0402 - StatusErrorNotAuthorized int16 = 0x0403 - StatusErrorNotPossible int16 = 0x0404 - StatusErrorTimeout int16 = 0x0405 - StatusErrorNotFound int16 = 0x0406 - StatusErrorGone int16 = 0x0407 - StatusErrorRequestEntity int16 = 0x0408 - StatusErrorRequestValue int16 = 0x0409 - StatusErrorDocumentFormatNotSupported int16 = 0x040a - StatusErrorAttributesOrValues int16 = 0x040b - StatusErrorUriScheme int16 = 0x040c - StatusErrorCharset int16 = 0x040d - StatusErrorConflicting int16 = 0x040e - StatusErrorCompressionError int16 = 0x040f - StatusErrorDocumentFormatError int16 = 0x0410 - StatusErrorDocumentAccess int16 = 0x0411 - StatusErrorAttributesNotSettable int16 = 0x0412 - StatusErrorIgnoredAllSubscriptions int16 = 0x0413 - StatusErrorTooManySubscriptions int16 = 0x0414 - StatusErrorIgnoredAllNotifications int16 = 0x0415 - StatusErrorPrintSupportFileNotFound int16 = 0x0416 - StatusErrorDocumentPassword int16 = 0x0417 - StatusErrorDocumentPermission int16 = 0x0418 - StatusErrorDocumentSecurity int16 = 0x0419 - StatusErrorDocumentUnprintable int16 = 0x041a - StatusErrorAccountInfoNeeded int16 = 0x041b - StatusErrorAccountClosed int16 = 0x041c - StatusErrorAccountLimitReached int16 = 0x041d - StatusErrorAccountAuthorizationFailed int16 = 0x041e - StatusErrorNotFetchable int16 = 0x041f - StatusErrorCupsAccountInfoNeeded int16 = 0x049C - StatusErrorCupsAccountClosed int16 = 0x049d - StatusErrorCupsAccountLimitReached int16 = 0x049e - StatusErrorCupsAccountAuthorizationFailed int16 = 0x049f - StatusErrorInternal int16 = 0x0500 - StatusErrorOperationNotSupported int16 = 0x0501 - StatusErrorServiceUnavailable int16 = 0x0502 - StatusErrorVersionNotSupported int16 = 0x0503 - StatusErrorDevice int16 = 0x0504 - StatusErrorTemporary int16 = 0x0505 - StatusErrorNotAcceptingJobs int16 = 0x0506 - StatusErrorBusy int16 = 0x0507 - StatusErrorJobCanceled int16 = 0x0508 - StatusErrorMultipleJobsNotSupported int16 = 0x0509 - StatusErrorPrinterIsDeactivated int16 = 0x050a - StatusErrorTooManyJobs int16 = 0x050b - StatusErrorTooManyDocuments int16 = 0x050c - StatusErrorCupsAuthenticationCanceled int16 = 0x1000 - StatusErrorCupsPki int16 = 0x1001 - StatusErrorCupsUpgradeRequired int16 = 0x1002 -) - -// ipp operations -const ( - OperationCupsInvalid int16 = -0x0001 - OperationCupsNone int16 = 0x0000 - OperationPrintJob int16 = 0x0002 - OperationPrintUri int16 = 0x0003 - OperationValidateJob int16 = 0x0004 - OperationCreateJob int16 = 0x0005 - OperationSendDocument int16 = 0x0006 - OperationSendUri int16 = 0x0007 - OperationCancelJob int16 = 0x0008 - OperationGetJobAttributes int16 = 0x0009 - OperationGetJobs int16 = 0x000a - OperationGetPrinterAttributes int16 = 0x000b - OperationHoldJob int16 = 0x000c - OperationReleaseJob int16 = 0x000d - OperationRestartJob int16 = 0x000e - OperationPausePrinter int16 = 0x0010 - OperationResumePrinter int16 = 0x0011 - OperationPurgeJobs int16 = 0x0012 - OperationSetPrinterAttributes int16 = 0x0013 - OperationSetJobAttributes int16 = 0x0014 - OperationGetPrinterSupportedValues int16 = 0x0015 - OperationCreatePrinterSubscriptions int16 = 0x0016 - OperationCreateJobSubscriptions int16 = 0x0017 - OperationGetSubscriptionAttributes int16 = 0x0018 - OperationGetSubscriptions int16 = 0x0019 - OperationRenewSubscription int16 = 0x001a - OperationCancelSubscription int16 = 0x001b - OperationGetNotifications int16 = 0x001c - OperationSendNotifications int16 = 0x001d - OperationGetResourceAttributes int16 = 0x001e - OperationGetResourceData int16 = 0x001f - OperationGetResources int16 = 0x0020 - OperationGetPrintSupportFiles int16 = 0x0021 - OperationEnablePrinter int16 = 0x0022 - OperationDisablePrinter int16 = 0x0023 - OperationPausePrinterAfterCurrentJob int16 = 0x0024 - OperationHoldNewJobs int16 = 0x0025 - OperationReleaseHeldNewJobs int16 = 0x0026 - OperationDeactivatePrinter int16 = 0x0027 - OperationActivatePrinter int16 = 0x0028 - OperationRestartPrinter int16 = 0x0029 - OperationShutdownPrinter int16 = 0x002a - OperationStartupPrinter int16 = 0x002b - OperationReprocessJob int16 = 0x002c - OperationCancelCurrentJob int16 = 0x002d - OperationSuspendCurrentJob int16 = 0x002e - OperationResumeJob int16 = 0x002f - OperationOperationPromoteJob int16 = 0x0030 - OperationScheduleJobAfter int16 = 0x0031 - OperationCancelDocument int16 = 0x0033 - OperationGetDocumentAttributes int16 = 0x0034 - OperationGetDocuments int16 = 0x0035 - OperationDeleteDocument int16 = 0x0036 - OperationSetDocumentAttributes int16 = 0x0037 - OperationCancelJobs int16 = 0x0038 - OperationCancelMyJobs int16 = 0x0039 - OperationResubmitJob int16 = 0x003a - OperationCloseJob int16 = 0x003b - OperationIdentifyPrinter int16 = 0x003c - OperationValidateDocument int16 = 0x003d - OperationAddDocumentImages int16 = 0x003e - OperationAcknowledgeDocument int16 = 0x003f - OperationAcknowledgeIdentifyPrinter int16 = 0x0040 - OperationAcknowledgeJob int16 = 0x0041 - OperationFetchDocument int16 = 0x0042 - OperationFetchJob int16 = 0x0043 - OperationGetOutputDeviceAttributes int16 = 0x0044 - OperationUpdateActiveJobs int16 = 0x0045 - OperationDeregisterOutputDevice int16 = 0x0046 - OperationUpdateDocumentStatus int16 = 0x0047 - OperationUpdateJobStatus int16 = 0x0048 - OperationUpdateOutputDeviceAttributes int16 = 0x0049 - OperationGetNextDocumentData int16 = 0x004a - OperationAllocatePrinterResources int16 = 0x004b - OperationCreatePrinter int16 = 0x004c - OperationDeallocatePrinterResources int16 = 0x004d - OperationDeletePrinter int16 = 0x004e - OperationGetPrinters int16 = 0x004f - OperationShutdownOnePrinter int16 = 0x0050 - OperationStartupOnePrinter int16 = 0x0051 - OperationCancelResource int16 = 0x0052 - OperationCreateResource int16 = 0x0053 - OperationInstallResource int16 = 0x0054 - OperationSendResourceData int16 = 0x0055 - OperationSetResourceAttributes int16 = 0x0056 - OperationCreateResourceSubscriptions int16 = 0x0057 - OperationCreateSystemSubscriptions int16 = 0x0058 - OperationDisableAllPrinters int16 = 0x0059 - OperationEnableAllPrinters int16 = 0x005a - OperationGetSystemAttributes int16 = 0x005b - OperationGetSystemSupportedValues int16 = 0x005c - OperationPauseAllPrinters int16 = 0x005d - OperationPauseAllPrintersAfterCurrentJob int16 = 0x005e - OperationRegisterOutputDevice int16 = 0x005f - OperationRestartSystem int16 = 0x0060 - OperationResumeAllPrinters int16 = 0x0061 - OperationSetSystemAttributes int16 = 0x0062 - OperationShutdownAllPrinter int16 = 0x0063 - OperationStartupAllPrinters int16 = 0x0064 - OperationPrivate int16 = 0x4000 - OperationCupsGetDefault int16 = 0x4001 - OperationCupsGetPrinters int16 = 0x4002 - OperationCupsAddModifyPrinter int16 = 0x4003 - OperationCupsDeletePrinter int16 = 0x4004 - OperationCupsGetClasses int16 = 0x4005 - OperationCupsAddModifyClass int16 = 0x4006 - OperationCupsDeleteClass int16 = 0x4007 - OperationCupsAcceptJobs int16 = 0x4008 - OperationCupsRejectJobs int16 = 0x4009 - OperationCupsSetDefault int16 = 0x400a - OperationCupsGetDevices int16 = 0x400b - OperationCupsGetPPDs int16 = 0x400c - OperationCupsMoveJob int16 = 0x400d - OperationCupsAuthenticateJob int16 = 0x400e - OperationCupsGetPpd int16 = 0x400f - OperationCupsGetDocument int16 = 0x4027 - OperationCupsCreateLocalPrinter int16 = 0x4028 -) - -// ipp tags -const ( - TagCupsInvalid int8 = -1 - TagZero int8 = 0x00 - TagOperation int8 = 0x01 - TagJob int8 = 0x02 - TagEnd int8 = 0x03 - TagPrinter int8 = 0x04 - TagUnsupportedGroup int8 = 0x05 - TagSubscription int8 = 0x06 - TagEventNotification int8 = 0x07 - TagResource int8 = 0x08 - TagDocument int8 = 0x09 - TagSystem int8 = 0x0a - TagUnsupportedValue int8 = 0x10 - TagDefault int8 = 0x11 - TagUnknown int8 = 0x12 - TagNoValue int8 = 0x13 - TagNotSettable int8 = 0x15 - TagDeleteAttr int8 = 0x16 - TagAdminDefine int8 = 0x17 - TagInteger int8 = 0x21 - TagBoolean int8 = 0x22 - TagEnum int8 = 0x23 - TagString int8 = 0x30 - TagDate int8 = 0x31 - TagResolution int8 = 0x32 - TagRange int8 = 0x33 - TagBeginCollection int8 = 0x34 - TagTextLang int8 = 0x35 - TagNameLang int8 = 0x36 - TagEndCollection int8 = 0x37 - TagText int8 = 0x41 - TagName int8 = 0x42 - TagReservedString int8 = 0x43 - TagKeyword int8 = 0x44 - TagUri int8 = 0x45 - TagUriScheme int8 = 0x46 - TagCharset int8 = 0x47 - TagLanguage int8 = 0x48 - TagMimeType int8 = 0x49 - TagMemberName int8 = 0x4a - TagExtension int8 = 0x7f -) - -// job states -const ( - JobStatePending int8 = 0x03 - JobStateHeld int8 = 0x04 - JobStateProcessing int8 = 0x05 - JobStateStopped int8 = 0x06 - JobStateCanceled int8 = 0x07 - JobStateAborted int8 = 0x08 - JobStateCompleted int8 = 0x09 -) - -// document states -const ( - DocumentStatePending int8 = 0x03 - DocumentStateProcessing int8 = 0x05 - DocumentStateCanceled int8 = 0x07 - DocumentStateAborted int8 = 0x08 - DocumentStateCompleted int8 = 0x08 -) - -// printer states -const ( - PrinterStateIdle int8 = 0x0003 - PrinterStateProcessing int8 = 0x0004 - PrinterStateStopped int8 = 0x0005 -) - -// job state filter -const ( - JobStateFilterNotCompleted = "not-completed" - JobStateFilterCompleted = "completed" - JobStateFilterAll = "all" -) - -// error policies -const ( - ErrorPolicyRetryJob = "retry-job" - ErrorPolicyAbortJob = "abort-job" - ErrorPolicyRetryCurrentJob = "retry-current-job" - ErrorPolicyStopPrinter = "stop-printer" -) - -// ipp defaults -const ( - CharsetLanguage = "en-US" - Charset = "utf-8" - ProtocolVersionMajor = int8(2) - ProtocolVersionMinor = int8(0) - - DefaultJobPriority = 50 -) - -// useful mime types for ipp -const ( - MimeTypePostscript = "application/postscript" - MimeTypePDF = "application/pdf" - MimeTypeOctetStream = "application/octet-stream" -) - -// ipp content types -const ( - ContentTypeIPP = "application/ipp" -) - -// known ipp attributes -const ( - AttributeCopies = "copies" - AttributeDocumentFormat = "document-format" - AttributeDocumentName = "document-name" - AttributeJobID = "job-id" - AttributeJobName = "job-name" - AttributeJobPriority = "job-priority" - AttributeJobURI = "job-uri" - AttributeLastDocument = "last-document" - AttributeMyJobs = "my-jobs" - AttributePPDName = "ppd-name" - AttributePPDMakeAndModel = "ppd-make-and-model" - AttributePrinterIsShared = "printer-is-shared" - AttributePrinterIsTemporary = "printer-is-temporary" - AttributePrinterURI = "printer-uri" - AttributePurgeJobs = "purge-jobs" - AttributeRequestedAttributes = "requested-attributes" - AttributeRequestingUserName = "requesting-user-name" - AttributeWhichJobs = "which-jobs" - AttributeFirstJobID = "first-job-id" - AttributeLimit = "limit" - AttributeStatusMessage = "status-message" - AttributeCharset = "attributes-charset" - AttributeNaturalLanguage = "attributes-natural-language" - AttributeDeviceURI = "device-uri" - AttributeHoldJobUntil = "job-hold-until" - AttributePrinterErrorPolicy = "printer-error-policy" - AttributePrinterInfo = "printer-info" - AttributePrinterLocation = "printer-location" - AttributePrinterName = "printer-name" - AttributePrinterStateReasons = "printer-state-reasons" - AttributeJobPrinterURI = "job-printer-uri" - AttributeMemberURIs = "member-uris" - AttributeDocumentNumber = "document-number" - AttributeDocumentState = "document-state" - AttributeFinishings = "finishings" - AttributeJobHoldUntil = "hold-job-until" - AttributeJobSheets = "job-sheets" - AttributeJobState = "job-state" - AttributeJobStateReason = "job-state-reason" - AttributeMedia = "media" - AttributeSides = "sides" - AttributeNumberUp = "number-up" - AttributeOrientationRequested = "orientation-requested" - AttributePrintQuality = "print-quality" - AttributePrinterIsAcceptingJobs = "printer-is-accepting-jobs" - AttributePrinterResolution = "printer-resolution" - AttributePrinterState = "printer-state" - AttributeMemberNames = "member-names" - AttributePrinterType = "printer-type" - AttributePrinterMakeAndModel = "printer-make-and-model" - AttributePrinterStateMessage = "printer-state-message" - AttributePrinterUriSupported = "printer-uri-supported" - AttributeJobMediaProgress = "job-media-progress" - AttributeJobKilobyteOctets = "job-k-octets" - AttributeNumberOfDocuments = "number-of-documents" - AttributeJobOriginatingUserName = "job-originating-user-name" - AttributeOutputOrder = "outputorder" - AttributeJobStateReasons = "job-state-reasons" - AttributeJobStateMessage = "job-state-message" - AttributeJobPrinterStateReasons = "job-printer-state-reasons" - AttributeJobPrinterStateMessage = "job-printer-state-message" - AttributeJobImpressionsCompleted = "job-impressions-completed" - AttributePrintScaling = "print-scaling" -) - -// Default attributes -var ( - DefaultClassAttributes = []string{AttributePrinterName, AttributeMemberNames} - DefaultPrinterAttributes = []string{ - AttributePrinterName, AttributePrinterType, AttributePrinterLocation, AttributePrinterInfo, - AttributePrinterMakeAndModel, AttributePrinterState, AttributePrinterStateMessage, AttributePrinterStateReasons, - AttributePrinterUriSupported, AttributeDeviceURI, AttributePrinterIsShared, - } - DefaultJobAttributes = []string{ - AttributeJobID, AttributeJobName, AttributePrinterURI, AttributeJobState, AttributeJobStateReason, - AttributeJobHoldUntil, AttributeJobMediaProgress, AttributeJobKilobyteOctets, AttributeNumberOfDocuments, AttributeCopies, - AttributeJobOriginatingUserName, - } -) - -// Attribute to tag mapping -var ( - AttributeTagMapping = map[string]int8{ - AttributeCharset: TagCharset, - AttributeNaturalLanguage: TagLanguage, - AttributeCopies: TagInteger, - AttributeDeviceURI: TagUri, - AttributeDocumentFormat: TagMimeType, - AttributeDocumentName: TagName, - AttributeDocumentNumber: TagInteger, - AttributeDocumentState: TagEnum, - AttributeFinishings: TagEnum, - AttributeJobHoldUntil: TagKeyword, - AttributeHoldJobUntil: TagKeyword, - AttributeJobID: TagInteger, - AttributeJobName: TagName, - AttributeJobPrinterURI: TagUri, - AttributeJobPriority: TagInteger, - AttributeJobSheets: TagName, - AttributeJobState: TagEnum, - AttributeJobStateReason: TagKeyword, - AttributeJobURI: TagUri, - AttributeLastDocument: TagBoolean, - AttributeMedia: TagKeyword, - AttributeSides: TagKeyword, - AttributeMemberURIs: TagUri, - AttributeMyJobs: TagBoolean, - AttributeNumberUp: TagInteger, - AttributeOrientationRequested: TagEnum, - AttributePPDName: TagName, - AttributePPDMakeAndModel: TagText, - AttributeNumberOfDocuments: TagInteger, - AttributePrintQuality: TagEnum, - AttributePrinterErrorPolicy: TagName, - AttributePrinterInfo: TagText, - AttributePrinterIsAcceptingJobs: TagBoolean, - AttributePrinterIsShared: TagBoolean, - AttributePrinterIsTemporary: TagBoolean, - AttributePrinterName: TagName, - AttributePrinterLocation: TagText, - AttributePrinterResolution: TagResolution, - AttributePrinterState: TagEnum, - AttributePrinterStateReasons: TagKeyword, - AttributePrinterURI: TagUri, - AttributePurgeJobs: TagBoolean, - AttributeRequestedAttributes: TagKeyword, - AttributeRequestingUserName: TagName, - AttributeWhichJobs: TagKeyword, - AttributeFirstJobID: TagInteger, - AttributeStatusMessage: TagText, - AttributeLimit: TagInteger, - AttributeOutputOrder: TagName, - AttributeJobStateReasons: TagString, - AttributeJobStateMessage: TagString, - AttributeJobPrinterStateReasons: TagString, - AttributeJobPrinterStateMessage: TagString, - AttributeJobImpressionsCompleted: TagInteger, - AttributePrintScaling: TagKeyword, - // IPP Subscription/Notification attributes (added for dankdots) - "notify-events": TagKeyword, - "notify-pull-method": TagKeyword, - "notify-lease-duration": TagInteger, - "notify-subscription-id": TagInteger, - "notify-subscription-ids": TagInteger, - "notify-sequence-numbers": TagInteger, - "notify-wait": TagBoolean, - "notify-recipient-uri": TagUri, - } -) diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/cups-client.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/cups-client.go deleted file mode 100644 index 68d60ce..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/cups-client.go +++ /dev/null @@ -1,313 +0,0 @@ -package ipp - -import ( - "io" - "strings" -) - -// CUPSClient implements a ipp client with specific cups operations -type CUPSClient struct { - *IPPClient -} - -// NewCUPSClient creates a new cups ipp client (used HttpAdapter internally) -func NewCUPSClient(host string, port int, username, password string, useTLS bool) *CUPSClient { - ippClient := NewIPPClient(host, port, username, password, useTLS) - return &CUPSClient{ippClient} -} - -// NewCUPSClientWithAdapter creates a new cups ipp client with given Adapter -func NewCUPSClientWithAdapter(username string, adapter Adapter) *CUPSClient { - ippClient := NewIPPClientWithAdapter(username, adapter) - return &CUPSClient{ippClient} -} - -// GetDevices returns a map of device uris and printer attributes -func (c *CUPSClient) GetDevices() (map[string]Attributes, error) { - req := NewRequest(OperationCupsGetDevices, 1) - - resp, err := c.SendRequest(c.adapter.GetHttpUri("", nil), req, nil) - if err != nil { - return nil, err - } - - printerNameMap := make(map[string]Attributes) - - for _, printerAttributes := range resp.PrinterAttributes { - printerNameMap[printerAttributes[AttributeDeviceURI][0].Value.(string)] = printerAttributes - } - - return printerNameMap, nil -} - -// MoveJob moves a job to a other printer -func (c *CUPSClient) MoveJob(jobID int, destPrinter string) error { - req := NewRequest(OperationCupsMoveJob, 1) - req.OperationAttributes[AttributeJobURI] = c.getJobUri(jobID) - req.PrinterAttributes[AttributeJobPrinterURI] = c.getPrinterUri(destPrinter) - - _, err := c.SendRequest(c.adapter.GetHttpUri("jobs", ""), req, nil) - return err -} - -// MoveAllJob moves all job from a printer to a other printer -func (c *CUPSClient) MoveAllJob(srcPrinter, destPrinter string) error { - req := NewRequest(OperationCupsMoveJob, 1) - req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(srcPrinter) - req.PrinterAttributes[AttributeJobPrinterURI] = c.getPrinterUri(destPrinter) - - _, err := c.SendRequest(c.adapter.GetHttpUri("jobs", ""), req, nil) - return err -} - -// GetPPDs returns a map of ppd names and attributes -func (c *CUPSClient) GetPPDs() (map[string]Attributes, error) { - req := NewRequest(OperationCupsGetPPDs, 1) - - resp, err := c.SendRequest(c.adapter.GetHttpUri("", nil), req, nil) - if err != nil { - return nil, err - } - - ppdNameMap := make(map[string]Attributes) - - for _, printerAttributes := range resp.PrinterAttributes { - ppdNameMap[printerAttributes[AttributePPDName][0].Value.(string)] = printerAttributes - } - - return ppdNameMap, nil -} - -// AcceptJobs lets a printer accept jobs again -func (c *CUPSClient) AcceptJobs(printer string) error { - req := NewRequest(OperationCupsAcceptJobs, 1) - req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(printer) - - _, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil) - return err -} - -// RejectJobs does not let a printer accept jobs -func (c *CUPSClient) RejectJobs(printer string) error { - req := NewRequest(OperationCupsRejectJobs, 1) - req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(printer) - - _, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil) - return err -} - -// AddPrinterToClass adds a printer to a class, if the class does not exists it will be created -func (c *CUPSClient) AddPrinterToClass(class, printer string) error { - attributes, err := c.GetPrinterAttributes(class, []string{AttributeMemberURIs}) - if err != nil && !IsNotExistsError(err) { - return err - } - - memberURIList := make([]string, 0) - - if !IsNotExistsError(err) { - for _, member := range attributes[AttributeMemberURIs] { - memberString := strings.Split(member.Value.(string), "/") - printerName := memberString[len(memberString)-1] - - if printerName == printer { - return nil - } - - memberURIList = append(memberURIList, member.Value.(string)) - } - } - - memberURIList = append(memberURIList, c.getPrinterUri(printer)) - - req := NewRequest(OperationCupsAddModifyClass, 1) - req.OperationAttributes[AttributePrinterURI] = c.getClassUri(class) - req.PrinterAttributes[AttributeMemberURIs] = memberURIList - - _, err = c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil) - return err -} - -// DeletePrinterFromClass removes a printer from a class, if a class has no more printer it will be deleted -func (c *CUPSClient) DeletePrinterFromClass(class, printer string) error { - attributes, err := c.GetPrinterAttributes(class, []string{AttributeMemberURIs}) - if err != nil { - return err - } - - memberURIList := make([]string, 0) - - for _, member := range attributes[AttributeMemberURIs] { - memberString := strings.Split(member.Value.(string), "/") - printerName := memberString[len(memberString)-1] - - if printerName != printer { - memberURIList = append(memberURIList, member.Value.(string)) - } - } - - if len(memberURIList) == 0 { - return c.DeleteClass(class) - } - - req := NewRequest(OperationCupsAddModifyClass, 1) - req.OperationAttributes[AttributePrinterURI] = c.getClassUri(class) - req.PrinterAttributes[AttributeMemberURIs] = memberURIList - - _, err = c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil) - return err -} - -// DeleteClass deletes a class -func (c *CUPSClient) DeleteClass(class string) error { - req := NewRequest(OperationCupsDeleteClass, 1) - req.OperationAttributes[AttributePrinterURI] = c.getClassUri(class) - - _, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil) - return err -} - -// CreatePrinter creates a new printer -func (c *CUPSClient) CreatePrinter(name, deviceURI, ppd string, shared bool, errorPolicy string, information, location string) error { - req := NewRequest(OperationCupsAddModifyPrinter, 1) - req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(name) - req.OperationAttributes[AttributePPDName] = ppd - req.OperationAttributes[AttributePrinterIsShared] = shared - req.PrinterAttributes[AttributePrinterStateReasons] = "none" - req.PrinterAttributes[AttributeDeviceURI] = deviceURI - req.PrinterAttributes[AttributePrinterInfo] = information - req.PrinterAttributes[AttributePrinterLocation] = location - req.PrinterAttributes[AttributePrinterErrorPolicy] = errorPolicy - - _, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil) - return err -} - -// SetPrinterPPD sets the ppd for a printer -func (c *CUPSClient) SetPrinterPPD(printer, ppd string) error { - req := NewRequest(OperationCupsAddModifyPrinter, 1) - req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(printer) - req.OperationAttributes[AttributePPDName] = ppd - - _, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil) - return err -} - -// SetPrinterDeviceURI sets the device uri for a printer -func (c *CUPSClient) SetPrinterDeviceURI(printer, deviceURI string) error { - req := NewRequest(OperationCupsAddModifyPrinter, 1) - req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(printer) - req.PrinterAttributes[AttributeDeviceURI] = deviceURI - - _, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil) - return err -} - -// SetPrinterIsShared shares or unshares a printer in the network -func (c *CUPSClient) SetPrinterIsShared(printer string, shared bool) error { - req := NewRequest(OperationCupsAddModifyPrinter, 1) - req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(printer) - req.OperationAttributes[AttributePrinterIsShared] = shared - - _, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil) - return err -} - -// SetPrinterErrorPolicy sets the error policy for a printer -func (c *CUPSClient) SetPrinterErrorPolicy(printer string, errorPolicy string) error { - req := NewRequest(OperationCupsAddModifyPrinter, 1) - req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(printer) - req.PrinterAttributes[AttributePrinterErrorPolicy] = errorPolicy - - _, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil) - return err -} - -// SetPrinterInformation sets general printer information -func (c *CUPSClient) SetPrinterInformation(printer, information string) error { - req := NewRequest(OperationCupsAddModifyPrinter, 1) - req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(printer) - req.PrinterAttributes[AttributePrinterInfo] = information - - _, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil) - return err -} - -// SetPrinterLocation sets the printer location -func (c *CUPSClient) SetPrinterLocation(printer, location string) error { - req := NewRequest(OperationCupsAddModifyPrinter, 1) - req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(printer) - req.PrinterAttributes[AttributePrinterLocation] = location - - _, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil) - return err -} - -// DeletePrinter deletes a printer -func (c *CUPSClient) DeletePrinter(printer string) error { - req := NewRequest(OperationCupsDeletePrinter, 1) - req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(printer) - - _, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil) - return err -} - -// GetPrinters returns a map of printer names and attributes -func (c *CUPSClient) GetPrinters(attributes []string) (map[string]Attributes, error) { - req := NewRequest(OperationCupsGetPrinters, 1) - - if attributes == nil { - req.OperationAttributes[AttributeRequestedAttributes] = DefaultPrinterAttributes - } else { - req.OperationAttributes[AttributeRequestedAttributes] = append(attributes, AttributePrinterName) - } - - resp, err := c.SendRequest(c.adapter.GetHttpUri("", nil), req, nil) - if err != nil { - return nil, err - } - - printerNameMap := make(map[string]Attributes) - - for _, printerAttributes := range resp.PrinterAttributes { - printerNameMap[printerAttributes[AttributePrinterName][0].Value.(string)] = printerAttributes - } - - return printerNameMap, nil -} - -// GetClasses returns a map of class names and attributes -func (c *CUPSClient) GetClasses(attributes []string) (map[string]Attributes, error) { - req := NewRequest(OperationCupsGetClasses, 1) - - if attributes == nil { - req.OperationAttributes[AttributeRequestedAttributes] = DefaultClassAttributes - } else { - req.OperationAttributes[AttributeRequestedAttributes] = append(attributes, AttributePrinterName) - } - - resp, err := c.SendRequest(c.adapter.GetHttpUri("", nil), req, nil) - if err != nil { - return nil, err - } - - printerNameMap := make(map[string]Attributes) - - for _, printerAttributes := range resp.PrinterAttributes { - printerNameMap[printerAttributes[AttributePrinterName][0].Value.(string)] = printerAttributes - } - - return printerNameMap, nil -} - -// PrintTestPage prints a test page using the provided PDF data -func (c *CUPSClient) PrintTestPage(printer string, testPageData io.Reader, size int) (int, error) { - return c.PrintJob(Document{ - Document: testPageData, - Name: "Test Page", - Size: size, - MimeType: MimeTypePDF, - }, printer, map[string]any{ - AttributeJobName: "Test Page", - }) -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/error.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/error.go deleted file mode 100644 index e4edf5e..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/error.go +++ /dev/null @@ -1,31 +0,0 @@ -package ipp - -import "fmt" - -// IsNotExistsError checks a given error whether a printer or class does not exist -func IsNotExistsError(err error) bool { - if err == nil { - return false - } - - return err.Error() == "The printer or class does not exist." -} - -// IPPError used for non ok ipp status codes -type IPPError struct { - Status int16 - Message string -} - -func (e IPPError) Error() string { - return fmt.Sprintf("ipp status: %d, message: %s", e.Status, e.Message) -} - -// HTTPError used for non 200 http codes -type HTTPError struct { - Code int -} - -func (e HTTPError) Error() string { - return fmt.Sprintf("got http code %d", e.Code) -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/ipp-client.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/ipp-client.go deleted file mode 100644 index a21dd54..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/ipp-client.go +++ /dev/null @@ -1,329 +0,0 @@ -package ipp - -import ( - "errors" - "fmt" - "io" - "os" - "path" -) - -// Document wraps an io.Reader with more information, needed for encoding -type Document struct { - Document io.Reader - Size int - Name string - MimeType string -} - -// IPPClient implements a generic ipp client -type IPPClient struct { - username string - adapter Adapter -} - -// NewIPPClient creates a new generic ipp client (used HttpAdapter internally) -func NewIPPClient(host string, port int, username, password string, useTLS bool) *IPPClient { - adapter := NewHttpAdapter(host, port, username, password, useTLS) - - return &IPPClient{ - username: username, - adapter: adapter, - } -} - -// NewIPPClientWithAdapter creates a new generic ipp client with given Adapter -func NewIPPClientWithAdapter(username string, adapter Adapter) *IPPClient { - return &IPPClient{ - username: username, - adapter: adapter, - } -} - -func (c *IPPClient) getPrinterUri(printer string) string { - return fmt.Sprintf("ipp://localhost/printers/%s", printer) -} - -func (c *IPPClient) getJobUri(jobID int) string { - return fmt.Sprintf("ipp://localhost/jobs/%d", jobID) -} - -func (c *IPPClient) getClassUri(printer string) string { - return fmt.Sprintf("ipp://localhost/classes/%s", printer) -} - -// SendRequest sends a request to a remote uri end returns the response -func (c *IPPClient) SendRequest(url string, req *Request, additionalResponseData io.Writer) (*Response, error) { - if _, ok := req.OperationAttributes[AttributeRequestingUserName]; !ok { - req.OperationAttributes[AttributeRequestingUserName] = c.username - } - - return c.adapter.SendRequest(url, req, additionalResponseData) -} - -// PrintDocuments prints one or more documents using a Create-Job operation followed by one or more Send-Document operation(s). custom job settings can be specified via the jobAttributes parameter -func (c *IPPClient) PrintDocuments(docs []Document, printer string, jobAttributes map[string]any) (int, error) { - printerURI := c.getPrinterUri(printer) - - req := NewRequest(OperationCreateJob, 1) - req.OperationAttributes[AttributePrinterURI] = printerURI - req.OperationAttributes[AttributeRequestingUserName] = c.username - - // set defaults for some attributes, may get overwritten - req.OperationAttributes[AttributeJobName] = docs[0].Name - req.OperationAttributes[AttributeCopies] = 1 - req.OperationAttributes[AttributeJobPriority] = DefaultJobPriority - - for key, value := range jobAttributes { - req.JobAttributes[key] = value - } - - resp, err := c.SendRequest(c.adapter.GetHttpUri("printers", printer), req, nil) - if err != nil { - return -1, err - } - - if len(resp.JobAttributes) == 0 { - return 0, errors.New("server doesn't returned a job id") - } - - jobID := resp.JobAttributes[0][AttributeJobID][0].Value.(int) - - documentCount := len(docs) - 1 - - for docID, doc := range docs { - req = NewRequest(OperationSendDocument, 2) - req.OperationAttributes[AttributePrinterURI] = printerURI - req.OperationAttributes[AttributeRequestingUserName] = c.username - req.OperationAttributes[AttributeJobID] = jobID - req.OperationAttributes[AttributeDocumentName] = doc.Name - req.OperationAttributes[AttributeDocumentFormat] = doc.MimeType - req.OperationAttributes[AttributeLastDocument] = docID == documentCount - req.File = doc.Document - req.FileSize = doc.Size - - _, err = c.SendRequest(c.adapter.GetHttpUri("printers", printer), req, nil) - if err != nil { - return -1, err - } - } - - return jobID, nil -} - -// PrintJob prints a document using a Print-Job operation. custom job settings can be specified via the jobAttributes parameter -func (c *IPPClient) PrintJob(doc Document, printer string, jobAttributes map[string]any) (int, error) { - printerURI := c.getPrinterUri(printer) - - req := NewRequest(OperationPrintJob, 1) - req.OperationAttributes[AttributePrinterURI] = printerURI - req.OperationAttributes[AttributeRequestingUserName] = c.username - req.OperationAttributes[AttributeJobName] = doc.Name - req.OperationAttributes[AttributeDocumentFormat] = doc.MimeType - - // set defaults for some attributes, may get overwritten - req.OperationAttributes[AttributeCopies] = 1 - req.OperationAttributes[AttributeJobPriority] = DefaultJobPriority - - for key, value := range jobAttributes { - req.JobAttributes[key] = value - } - - req.File = doc.Document - req.FileSize = doc.Size - - resp, err := c.SendRequest(c.adapter.GetHttpUri("printers", printer), req, nil) - if err != nil { - return -1, err - } - - if len(resp.JobAttributes) == 0 { - return 0, errors.New("server doesn't returned a job id") - } - - jobID := resp.JobAttributes[0][AttributeJobID][0].Value.(int) - - return jobID, nil -} - -// PrintFile prints a local file on the file system. custom job settings can be specified via the jobAttributes parameter -func (c *IPPClient) PrintFile(filePath, printer string, jobAttributes map[string]any) (int, error) { - fileStats, err := os.Stat(filePath) - if os.IsNotExist(err) { - return -1, err - } - - fileName := path.Base(filePath) - - document, err := os.Open(filePath) - if err != nil { - return 0, err - } - defer document.Close() - - jobAttributes[AttributeJobName] = fileName - - return c.PrintDocuments([]Document{ - { - Document: document, - Name: fileName, - Size: int(fileStats.Size()), - MimeType: MimeTypeOctetStream, - }, - }, printer, jobAttributes) -} - -// GetPrinterAttributes returns the requested attributes for the specified printer, if attributes is nil the default attributes will be used -func (c *IPPClient) GetPrinterAttributes(printer string, attributes []string) (Attributes, error) { - req := NewRequest(OperationGetPrinterAttributes, 1) - req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(printer) - req.OperationAttributes[AttributeRequestingUserName] = c.username - - if attributes == nil { - req.OperationAttributes[AttributeRequestedAttributes] = DefaultPrinterAttributes - } else { - req.OperationAttributes[AttributeRequestedAttributes] = attributes - } - - resp, err := c.SendRequest(c.adapter.GetHttpUri("printers", printer), req, nil) - if err != nil { - return nil, err - } - - if len(resp.PrinterAttributes) == 0 { - return nil, errors.New("server doesn't return any printer attributes") - } - - return resp.PrinterAttributes[0], nil -} - -// ResumePrinter resumes a printer -func (c *IPPClient) ResumePrinter(printer string) error { - req := NewRequest(OperationResumePrinter, 1) - req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(printer) - - _, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil) - return err -} - -// PausePrinter pauses a printer -func (c *IPPClient) PausePrinter(printer string) error { - req := NewRequest(OperationPausePrinter, 1) - req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(printer) - - _, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil) - return err -} - -// GetJobAttributes returns the requested attributes for the specified job, if attributes is nil the default job will be used -func (c *IPPClient) GetJobAttributes(jobID int, attributes []string) (Attributes, error) { - req := NewRequest(OperationGetJobAttributes, 1) - req.OperationAttributes[AttributeJobURI] = c.getJobUri(jobID) - - if attributes == nil { - req.OperationAttributes[AttributeRequestedAttributes] = DefaultJobAttributes - } else { - req.OperationAttributes[AttributeRequestedAttributes] = attributes - } - - resp, err := c.SendRequest(c.adapter.GetHttpUri("jobs", jobID), req, nil) - if err != nil { - return nil, err - } - - if len(resp.JobAttributes) == 0 { - return nil, errors.New("server doesn't return any job attributes") - } - - return resp.JobAttributes[0], nil -} - -// GetJobs returns jobs from a printer or class -func (c *IPPClient) GetJobs(printer, class string, whichJobs string, myJobs bool, firstJobId, limit int, attributes []string) (map[int]Attributes, error) { - req := NewRequest(OperationGetJobs, 1) - req.OperationAttributes[AttributeWhichJobs] = whichJobs - req.OperationAttributes[AttributeMyJobs] = myJobs - - if printer != "" { - req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(printer) - } else if class != "" { - req.OperationAttributes[AttributePrinterURI] = c.getClassUri(printer) - } else { - req.OperationAttributes[AttributePrinterURI] = "ipp://localhost/" - } - - if firstJobId > 0 { - req.OperationAttributes[AttributeFirstJobID] = firstJobId - } - - if limit > 0 { - req.OperationAttributes[AttributeLimit] = limit - } - - if myJobs { - req.OperationAttributes[AttributeRequestingUserName] = c.username - } - - if attributes == nil { - req.OperationAttributes[AttributeRequestedAttributes] = DefaultJobAttributes - } else { - req.OperationAttributes[AttributeRequestedAttributes] = append(attributes, AttributeJobID) - } - - resp, err := c.SendRequest(c.adapter.GetHttpUri("", nil), req, nil) - if err != nil { - return nil, err - } - - jobIDMap := make(map[int]Attributes) - - for _, jobAttributes := range resp.JobAttributes { - jobIDMap[jobAttributes[AttributeJobID][0].Value.(int)] = jobAttributes - } - - return jobIDMap, nil -} - -// CancelJob cancels a job. if purge is true, the job will also be removed -func (c *IPPClient) CancelJob(jobID int, purge bool) error { - req := NewRequest(OperationCancelJob, 1) - req.OperationAttributes[AttributeJobURI] = c.getJobUri(jobID) - req.OperationAttributes[AttributePurgeJobs] = purge - - _, err := c.SendRequest(c.adapter.GetHttpUri("jobs", ""), req, nil) - return err -} - -// CancelAllJob cancels all jobs for a specified printer. if purge is true, the jobs will also be removed -func (c *IPPClient) CancelAllJob(printer string, purge bool) error { - req := NewRequest(OperationCancelJobs, 1) - req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(printer) - req.OperationAttributes[AttributePurgeJobs] = purge - - _, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil) - return err -} - -// RestartJob restarts a job -func (c *IPPClient) RestartJob(jobID int) error { - req := NewRequest(OperationRestartJob, 1) - req.OperationAttributes[AttributeJobURI] = c.getJobUri(jobID) - - _, err := c.SendRequest(c.adapter.GetHttpUri("jobs", ""), req, nil) - return err -} - -// HoldJobUntil holds a job -func (c *IPPClient) HoldJobUntil(jobID int, holdUntil string) error { - req := NewRequest(OperationRestartJob, 1) - req.OperationAttributes[AttributeJobURI] = c.getJobUri(jobID) - req.JobAttributes[AttributeHoldJobUntil] = holdUntil - - _, err := c.SendRequest(c.adapter.GetHttpUri("jobs", ""), req, nil) - return err -} - -// TestConnection tests if a tcp connection to the remote server is possible -func (c *IPPClient) TestConnection() error { - return c.adapter.TestConnection() -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/request.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/request.go deleted file mode 100644 index 3207038..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/request.go +++ /dev/null @@ -1,299 +0,0 @@ -package ipp - -import ( - "bytes" - "encoding/binary" - "io" -) - -// Request defines a ipp request -type Request struct { - ProtocolVersionMajor int8 - ProtocolVersionMinor int8 - - Operation int16 - RequestId int32 - - OperationAttributes map[string]any - JobAttributes map[string]any - PrinterAttributes map[string]any - SubscriptionAttributes map[string]any // Added for subscription operations - - File io.Reader - FileSize int -} - -// NewRequest creates a new ipp request -func NewRequest(op int16, reqID int32) *Request { - return &Request{ - ProtocolVersionMajor: ProtocolVersionMajor, - ProtocolVersionMinor: ProtocolVersionMinor, - Operation: op, - RequestId: reqID, - OperationAttributes: make(map[string]any), - JobAttributes: make(map[string]any), - PrinterAttributes: make(map[string]any), - SubscriptionAttributes: make(map[string]any), - File: nil, - FileSize: -1, - } -} - -// Encode encodes the request to a byte slice -func (r *Request) Encode() ([]byte, error) { - buf := new(bytes.Buffer) - enc := NewAttributeEncoder(buf) - - if err := binary.Write(buf, binary.BigEndian, r.ProtocolVersionMajor); err != nil { - return nil, err - } - - if err := binary.Write(buf, binary.BigEndian, r.ProtocolVersionMinor); err != nil { - return nil, err - } - - if err := binary.Write(buf, binary.BigEndian, r.Operation); err != nil { - return nil, err - } - - if err := binary.Write(buf, binary.BigEndian, r.RequestId); err != nil { - return nil, err - } - - if err := binary.Write(buf, binary.BigEndian, TagOperation); err != nil { - return nil, err - } - - if r.OperationAttributes == nil { - r.OperationAttributes = make(map[string]any, 2) - } - - if _, found := r.OperationAttributes[AttributeCharset]; !found { - r.OperationAttributes[AttributeCharset] = Charset - } - - if _, found := r.OperationAttributes[AttributeNaturalLanguage]; !found { - r.OperationAttributes[AttributeNaturalLanguage] = CharsetLanguage - } - - if err := r.encodeOperationAttributes(enc); err != nil { - return nil, err - } - - if len(r.JobAttributes) > 0 { - if err := binary.Write(buf, binary.BigEndian, TagJob); err != nil { - return nil, err - } - for attr, value := range r.JobAttributes { - if err := enc.Encode(attr, value); err != nil { - return nil, err - } - } - } - - if len(r.PrinterAttributes) > 0 { - if err := binary.Write(buf, binary.BigEndian, TagPrinter); err != nil { - return nil, err - } - for attr, value := range r.PrinterAttributes { - if err := enc.Encode(attr, value); err != nil { - return nil, err - } - } - } - - if len(r.SubscriptionAttributes) > 0 { - if err := binary.Write(buf, binary.BigEndian, TagSubscription); err != nil { - return nil, err - } - if err := r.encodeSubscriptionAttributes(enc); err != nil { - return nil, err - } - } - - if err := binary.Write(buf, binary.BigEndian, TagEnd); err != nil { - return nil, err - } - - return buf.Bytes(), nil -} - -func (r *Request) encodeOperationAttributes(enc *AttributeEncoder) error { - ordered := []string{ - AttributeCharset, - AttributeNaturalLanguage, - AttributePrinterURI, - AttributeJobID, - } - - for _, attr := range ordered { - if value, ok := r.OperationAttributes[attr]; ok { - delete(r.OperationAttributes, attr) - if err := enc.Encode(attr, value); err != nil { - return err - } - } - } - - for attr, value := range r.OperationAttributes { - if err := enc.Encode(attr, value); err != nil { - return err - } - } - - return nil -} - -func (r *Request) encodeSubscriptionAttributes(enc *AttributeEncoder) error { - // Encode subscription attributes in proper order - // notify-pull-method and notify-lease-duration must come before notify-events - ordered := []string{ - "notify-pull-method", - "notify-lease-duration", - "notify-events", - } - - for _, attr := range ordered { - if value, ok := r.SubscriptionAttributes[attr]; ok { - delete(r.SubscriptionAttributes, attr) - if err := enc.Encode(attr, value); err != nil { - return err - } - } - } - - // Encode any remaining subscription attributes - for attr, value := range r.SubscriptionAttributes { - if err := enc.Encode(attr, value); err != nil { - return err - } - } - - return nil -} - -// RequestDecoder reads and decodes a request from a stream -type RequestDecoder struct { - reader io.Reader -} - -// NewRequestDecoder returns a new decoder that reads from r -func NewRequestDecoder(r io.Reader) *RequestDecoder { - return &RequestDecoder{ - reader: r, - } -} - -// Decode decodes a ipp request into a request struct. additional data will be written to an io.Writer if data is not nil -func (d *RequestDecoder) Decode(data io.Writer) (*Request, error) { - req := new(Request) - - if err := binary.Read(d.reader, binary.BigEndian, &req.ProtocolVersionMajor); err != nil { - return nil, err - } - - if err := binary.Read(d.reader, binary.BigEndian, &req.ProtocolVersionMinor); err != nil { - return nil, err - } - - if err := binary.Read(d.reader, binary.BigEndian, &req.Operation); err != nil { - return nil, err - } - - if err := binary.Read(d.reader, binary.BigEndian, &req.RequestId); err != nil { - return nil, err - } - - startByteSlice := make([]byte, 1) - - tag := TagCupsInvalid - previousAttributeName := "" - tagSet := false - - attribDecoder := NewAttributeDecoder(d.reader) - - // decode attribute buffer - for { - if _, err := d.reader.Read(startByteSlice); err != nil { - // when we read from a stream, we may get an EOF if we want to read the end tag - // all data should be read and we can ignore the error - if err == io.EOF { - break - } - return nil, err - } - - startByte := int8(startByteSlice[0]) - - // check if attributes are completed - if startByte == TagEnd { - break - } - - if startByte == TagOperation { - if req.OperationAttributes == nil { - req.OperationAttributes = make(map[string]any) - } - - tag = TagOperation - tagSet = true - - } - - if startByte == TagJob { - if req.JobAttributes == nil { - req.JobAttributes = make(map[string]any) - } - tag = TagJob - tagSet = true - } - - if startByte == TagPrinter { - if req.PrinterAttributes == nil { - req.PrinterAttributes = make(map[string]any) - } - tag = TagPrinter - tagSet = true - } - - if tagSet { - if _, err := d.reader.Read(startByteSlice); err != nil { - return nil, err - } - startByte = int8(startByteSlice[0]) - } - - attrib, err := attribDecoder.Decode(startByte) - if err != nil { - return nil, err - } - - if attrib.Name != "" { - appendAttributeToRequest(req, tag, attrib.Name, attrib.Value) - previousAttributeName = attrib.Name - } else { - appendAttributeToRequest(req, tag, previousAttributeName, attrib.Value) - } - - tagSet = false - } - - if data != nil { - if _, err := io.Copy(data, d.reader); err != nil { - return nil, err - } - } - - return req, nil -} - -func appendAttributeToRequest(req *Request, tag int8, name string, value any) { - switch tag { - case TagOperation: - req.OperationAttributes[name] = value - case TagPrinter: - req.PrinterAttributes[name] = value - case TagJob: - req.JobAttributes[name] = value - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/response.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/response.go deleted file mode 100644 index e7cbd75..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/response.go +++ /dev/null @@ -1,383 +0,0 @@ -package ipp - -import ( - "bytes" - "encoding/binary" - "io" -) - -// Attributes is a wrapper for a set of attributes -type Attributes map[string][]Attribute - -// Response defines a ipp response -type Response struct { - ProtocolVersionMajor int8 - ProtocolVersionMinor int8 - - StatusCode int16 - RequestId int32 - - OperationAttributes Attributes - PrinterAttributes []Attributes - JobAttributes []Attributes - SubscriptionAttributes []Attributes // Added for subscription responses -} - -// CheckForErrors checks the status code and returns a error if it is not zero. it also returns the status message if provided by the server -func (r *Response) CheckForErrors() error { - if r.StatusCode != StatusOk { - err := IPPError{ - Status: r.StatusCode, - Message: "no status message returned", - } - - if len(r.OperationAttributes["status-message"]) > 0 { - err.Message = r.OperationAttributes["status-message"][0].Value.(string) - } - - return err - } - - return nil -} - -// NewResponse creates a new ipp response -func NewResponse(statusCode int16, reqID int32) *Response { - return &Response{ - ProtocolVersionMajor: ProtocolVersionMajor, - ProtocolVersionMinor: ProtocolVersionMinor, - StatusCode: statusCode, - RequestId: reqID, - OperationAttributes: make(Attributes), - PrinterAttributes: make([]Attributes, 0), - JobAttributes: make([]Attributes, 0), - } -} - -// Encode encodes the response to a byte slice -func (r *Response) Encode() ([]byte, error) { - buf := new(bytes.Buffer) - enc := NewAttributeEncoder(buf) - - if err := binary.Write(buf, binary.BigEndian, r.ProtocolVersionMajor); err != nil { - return nil, err - } - - if err := binary.Write(buf, binary.BigEndian, r.ProtocolVersionMinor); err != nil { - return nil, err - } - - if err := binary.Write(buf, binary.BigEndian, r.StatusCode); err != nil { - return nil, err - } - - if err := binary.Write(buf, binary.BigEndian, r.RequestId); err != nil { - return nil, err - } - - if err := binary.Write(buf, binary.BigEndian, TagOperation); err != nil { - return nil, err - } - - if r.OperationAttributes == nil { - r.OperationAttributes = make(Attributes, 0) - } - - if _, found := r.OperationAttributes[AttributeCharset]; !found { - r.OperationAttributes[AttributeCharset] = []Attribute{ - { - Value: Charset, - }, - } - } - - if _, found := r.OperationAttributes[AttributeNaturalLanguage]; !found { - r.OperationAttributes[AttributeNaturalLanguage] = []Attribute{ - { - Value: CharsetLanguage, - }, - } - } - - if err := r.encodeOperationAttributes(enc); err != nil { - return nil, err - } - - if len(r.PrinterAttributes) > 0 { - for _, printerAttr := range r.PrinterAttributes { - if err := binary.Write(buf, binary.BigEndian, TagPrinter); err != nil { - return nil, err - } - - for name, attr := range printerAttr { - if len(attr) == 0 { - continue - } - - values := make([]any, len(attr)) - for i, v := range attr { - values[i] = v.Value - } - - if len(values) == 1 { - if err := enc.Encode(name, values[0]); err != nil { - return nil, err - } - } else { - if err := enc.Encode(name, values); err != nil { - return nil, err - } - } - } - } - } - - if len(r.JobAttributes) > 0 { - for _, jobAttr := range r.JobAttributes { - if err := binary.Write(buf, binary.BigEndian, TagJob); err != nil { - return nil, err - } - - for name, attr := range jobAttr { - if len(attr) == 0 { - continue - } - - values := make([]any, len(attr)) - for i, v := range attr { - values[i] = v.Value - } - - if len(values) == 1 { - if err := enc.Encode(name, values[0]); err != nil { - return nil, err - } - } else { - if err := enc.Encode(name, values); err != nil { - return nil, err - } - } - } - } - } - - if err := binary.Write(buf, binary.BigEndian, TagEnd); err != nil { - return nil, err - } - - return buf.Bytes(), nil -} - -func (r *Response) encodeOperationAttributes(enc *AttributeEncoder) error { - ordered := []string{ - AttributeCharset, - AttributeNaturalLanguage, - AttributePrinterURI, - AttributeJobID, - } - - for _, name := range ordered { - if attr, ok := r.OperationAttributes[name]; ok { - delete(r.OperationAttributes, name) - if err := encodeOperationAttribute(enc, name, attr); err != nil { - return err - } - } - } - - for name, attr := range r.OperationAttributes { - if err := encodeOperationAttribute(enc, name, attr); err != nil { - return err - } - } - - return nil -} - -func encodeOperationAttribute(enc *AttributeEncoder, name string, attr []Attribute) error { - if len(attr) == 0 { - return nil - } - - values := make([]any, len(attr)) - for i, v := range attr { - values[i] = v.Value - } - - if len(values) == 1 { - return enc.Encode(name, values[0]) - } - - return enc.Encode(name, values) -} - -// ResponseDecoder reads and decodes a response from a stream -type ResponseDecoder struct { - reader io.Reader -} - -// NewResponseDecoder returns a new decoder that reads from r -func NewResponseDecoder(r io.Reader) *ResponseDecoder { - return &ResponseDecoder{ - reader: r, - } -} - -// Decode decodes a ipp response into a response struct. additional data will be written to an io.Writer if data is not nil -func (d *ResponseDecoder) Decode(data io.Writer) (*Response, error) { - /* - 1 byte: Protocol Major Version - b - 1 byte: Protocol Minor Version - b - 2 byte: Status ID - h - 4 byte: Request ID - i - 1 byte: Operation Attribute Byte (\0x01) - N times: Attributes - 1 byte: Attribute End Byte (\0x03) - */ - - resp := new(Response) - - // wrap the reader so we have more functionality - // reader := bufio.NewReader(d.reader) - - if err := binary.Read(d.reader, binary.BigEndian, &resp.ProtocolVersionMajor); err != nil { - return nil, err - } - - if err := binary.Read(d.reader, binary.BigEndian, &resp.ProtocolVersionMinor); err != nil { - return nil, err - } - - if err := binary.Read(d.reader, binary.BigEndian, &resp.StatusCode); err != nil { - return nil, err - } - - if err := binary.Read(d.reader, binary.BigEndian, &resp.RequestId); err != nil { - return nil, err - } - - startByteSlice := make([]byte, 1) - - tag := TagCupsInvalid - previousAttributeName := "" - tempAttributes := make(Attributes) - tagSet := false - - attribDecoder := NewAttributeDecoder(d.reader) - - // decode attribute buffer - for { - if _, err := d.reader.Read(startByteSlice); err != nil { - // when we read from a stream, we may get an EOF if we want to read the end tag - // all data should be read and we can ignore the error - if err == io.EOF { - break - } - return nil, err - } - - startByte := int8(startByteSlice[0]) - - // check if attributes are completed - if startByte == TagEnd { - break - } - - if startByte == TagOperation { - if len(tempAttributes) > 0 && tag != TagCupsInvalid { - appendAttributeToResponse(resp, tag, tempAttributes) - tempAttributes = make(Attributes) - } - - tag = TagOperation - tagSet = true - } - - if startByte == TagJob { - if len(tempAttributes) > 0 && tag != TagCupsInvalid { - appendAttributeToResponse(resp, tag, tempAttributes) - tempAttributes = make(Attributes) - } - - tag = TagJob - tagSet = true - } - - if startByte == TagPrinter { - if len(tempAttributes) > 0 && tag != TagCupsInvalid { - appendAttributeToResponse(resp, tag, tempAttributes) - tempAttributes = make(Attributes) - } - - tag = TagPrinter - tagSet = true - } - - if startByte == TagSubscription { - if len(tempAttributes) > 0 && tag != TagCupsInvalid { - appendAttributeToResponse(resp, tag, tempAttributes) - tempAttributes = make(Attributes) - } - - tag = TagSubscription - tagSet = true - } - - if startByte == TagEventNotification { - if len(tempAttributes) > 0 && tag != TagCupsInvalid { - appendAttributeToResponse(resp, tag, tempAttributes) - tempAttributes = make(Attributes) - } - - tag = TagEventNotification - tagSet = true - } - - if tagSet { - if _, err := d.reader.Read(startByteSlice); err != nil { - return nil, err - } - startByte = int8(startByteSlice[0]) - } - - attrib, err := attribDecoder.Decode(startByte) - if err != nil { - return nil, err - } - - if attrib.Name != "" { - tempAttributes[attrib.Name] = append(tempAttributes[attrib.Name], *attrib) - previousAttributeName = attrib.Name - } else { - tempAttributes[previousAttributeName] = append(tempAttributes[previousAttributeName], *attrib) - } - - tagSet = false - } - - if len(tempAttributes) > 0 && tag != TagCupsInvalid { - appendAttributeToResponse(resp, tag, tempAttributes) - } - - if data != nil { - if _, err := io.Copy(data, d.reader); err != nil { - return nil, err - } - } - - return resp, nil -} - -func appendAttributeToResponse(resp *Response, tag int8, attr map[string][]Attribute) { - switch tag { - case TagOperation: - resp.OperationAttributes = attr - case TagPrinter: - resp.PrinterAttributes = append(resp.PrinterAttributes, attr) - case TagJob: - resp.JobAttributes = append(resp.JobAttributes, attr) - case TagSubscription, TagEventNotification: - // Both subscription and event notification attributes go to SubscriptionAttributes - resp.SubscriptionAttributes = append(resp.SubscriptionAttributes, attr) - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/utils.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/utils.go deleted file mode 100644 index 62689a3..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/ipp/utils.go +++ /dev/null @@ -1,28 +0,0 @@ -package ipp - -import ( - "fmt" - "os" - "path" -) - -// ParseControlFile reads and decodes a cups control file into a response -func ParseControlFile(jobID int, spoolDirectory string) (*Response, error) { - if spoolDirectory == "" { - spoolDirectory = "/var/spool/cups" - } - - controlFilePath := path.Join(spoolDirectory, fmt.Sprintf("c%d", jobID)) - - if _, err := os.Stat(controlFilePath); err != nil { - return nil, err - } - - controlFile, err := os.Open(controlFilePath) - if err != nil { - return nil, err - } - defer controlFile.Close() - - return NewResponseDecoder(controlFile).Decode(nil) -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/syncmap/LICENSE b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/syncmap/LICENSE deleted file mode 100644 index edba275..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/syncmap/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Copyright 2009 The Go Authors. -Copyright 2024 Zachary Olstein. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google LLC nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/syncmap/syncmap.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/syncmap/syncmap.go deleted file mode 100644 index 27d9458..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/pkg/syncmap/syncmap.go +++ /dev/null @@ -1,537 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package syncmap - -import ( - "sync" - "sync/atomic" - "unsafe" -) - -// Map is like a Go map[K]V but is safe for concurrent use -// by multiple goroutines without additional locking or coordination. -// Loads, stores, and deletes run in amortized constant time. -// -// The Map type is specialized. Most code should use a plain Go map instead, -// with separate locking or coordination, for better type safety and to make it -// easier to maintain other invariants along with the map content. -// -// The Map type is optimized for two common use cases: (1) when the entry for a given -// key is only ever written once but read many times, as in caches that only grow, -// or (2) when multiple goroutines read, write, and overwrite entries for disjoint -// sets of keys. In these two cases, use of a Map may significantly reduce lock -// contention compared to a Go map paired with a separate [Mutex] or [RWMutex]. -// -// The zero Map is empty and ready for use. A Map must not be copied after first use. -// -// In the terminology of [the Go memory model], Map arranges that a write operation -// “synchronizes before” any read operation that observes the effect of the write, where -// read and write operations are defined as follows. -// [Map.Load], [Map.LoadAndDelete], [Map.LoadOrStore], and [Map.Swap] are read operations; -// [Map.Delete], [Map.LoadAndDelete], [Map.Store], and [Map.Swap] are write operations; -// [Map.LoadOrStore] is a write operation when it returns loaded set to false. -// -// [the Go memory model]: https://go.dev/ref/mem -type Map[K comparable, V any] struct { - mu sync.Mutex - - // read contains the portion of the map's contents that are safe for - // concurrent access (with or without mu held). - // - // The read field itself is always safe to load, but must only be stored with - // mu held. - // - // Entries stored in read may be updated concurrently without mu, but updating - // a previously-expunged entry requires that the entry be copied to the dirty - // map and unexpunged with mu held. - read atomic.Pointer[readOnly[K, V]] - - // dirty contains the portion of the map's contents that require mu to be - // held. To ensure that the dirty map can be promoted to the read map quickly, - // it also includes all of the non-expunged entries in the read map. - // - // Expunged entries are not stored in the dirty map. An expunged entry in the - // clean map must be unexpunged and added to the dirty map before a new value - // can be stored to it. - // - // If the dirty map is nil, the next write to the map will initialize it by - // making a shallow copy of the clean map, omitting stale entries. - dirty map[K]*entry[V] - - // misses counts the number of loads since the read map was last updated that - // needed to lock mu to determine whether the key was present. - // - // Once enough misses have occurred to cover the cost of copying the dirty - // map, the dirty map will be promoted to the read map (in the unamended - // state) and the next store to the map will make a new dirty copy. - misses int -} - -// readOnly is an immutable struct stored atomically in the Map.read field. -type readOnly[K comparable, V any] struct { - m map[K]*entry[V] - amended bool // true if the dirty map contains some key not in m. -} - -// expunged is an arbitrary pointer that marks entries which have been deleted -// from the dirty map. -// Because the same expunged pointer is used regardless of the Map's value type, -// value pointers read from the map must be compared against expunged BEFORE -// casting the pointer to *V. -var expunged = unsafe.Pointer(new(int)) - -// An entry is a slot in the map corresponding to a particular key. -type entry[V any] struct { - // p points to the value stored for the entry. - // - // If p == nil, the entry has been deleted, and either m.dirty == nil or - // m.dirty[key] is e. - // - // If p == expunged, the entry has been deleted, m.dirty != nil, and the entry - // is missing from m.dirty. - // - // Otherwise, the entry is valid and recorded in m.read.m[key] and, if m.dirty - // != nil, in m.dirty[key]. - // - // If p != expunged, it is always safe to cast it to (*V). - // - // An entry can be deleted by atomic replacement with nil: when m.dirty is - // next created, it will atomically replace nil with expunged and leave - // m.dirty[key] unset. - // - // An entry's associated value can be updated by atomic replacement, provided - // p != expunged. If p == expunged, an entry's associated value can be updated - // only after first setting m.dirty[key] = e so that lookups using the dirty - // map find the entry. - p unsafe.Pointer -} - -func newEntry[V any](i V) *entry[V] { - e := &entry[V]{} - atomic.StorePointer(&e.p, unsafe.Pointer(&i)) - return e -} - -func (m *Map[K, V]) loadReadOnly() readOnly[K, V] { - if p := m.read.Load(); p != nil { - return *p - } - return readOnly[K, V]{} -} - -// Load returns the value stored in the map for a key, or nil if no -// value is present. -// The ok result indicates whether value was found in the map. -func (m *Map[K, V]) Load(key K) (value V, ok bool) { - read := m.loadReadOnly() - e, ok := read.m[key] - if !ok && read.amended { - m.mu.Lock() - // Avoid reporting a spurious miss if m.dirty got promoted while we were - // blocked on m.mu. (If further loads of the same key will not miss, it's - // not worth copying the dirty map for this key.) - read = m.loadReadOnly() - e, ok = read.m[key] - if !ok && read.amended { - e, ok = m.dirty[key] - // Regardless of whether the entry was present, record a miss: this key - // will take the slow path until the dirty map is promoted to the read - // map. - m.missLocked() - } - m.mu.Unlock() - } - if !ok { - return value, false - } - return e.load() -} - -func (e *entry[V]) load() (value V, ok bool) { - p := atomic.LoadPointer(&e.p) - if p == nil || p == expunged { - return value, false - } - return *(*V)(p), true -} - -// Store sets the value for a key. -func (m *Map[K, V]) Store(key K, value V) { - _, _ = m.Swap(key, value) -} - -// unexpungeLocked ensures that the entry is not marked as expunged. -// -// If the entry was previously expunged, it must be added to the dirty map -// before m.mu is unlocked. -func (e *entry[V]) unexpungeLocked() (wasExpunged bool) { - return atomic.CompareAndSwapPointer(&e.p, expunged, nil) -} - -// swapLocked unconditionally swaps a value into the entry. -// -// The entry must be known not to be expunged. -func (e *entry[V]) swapLocked(i *V) *V { - return (*V)(atomic.SwapPointer(&e.p, unsafe.Pointer(i))) -} - -// LoadOrStore returns the existing value for the key if present. -// Otherwise, it stores and returns the given value. -// The loaded result is true if the value was loaded, false if stored. -func (m *Map[K, V]) LoadOrStore(key K, value V) (actual V, loaded bool) { - // Avoid locking if it's a clean hit. - read := m.loadReadOnly() - if e, ok := read.m[key]; ok { - actual, loaded, ok := e.tryLoadOrStore(value) - if ok { - return actual, loaded - } - } - - m.mu.Lock() - read = m.loadReadOnly() - if e, ok := read.m[key]; ok { - if e.unexpungeLocked() { - m.dirty[key] = e - } - actual, loaded, _ = e.tryLoadOrStore(value) - } else if e, ok := m.dirty[key]; ok { - actual, loaded, _ = e.tryLoadOrStore(value) - m.missLocked() - } else { - if !read.amended { - // We're adding the first new key to the dirty map. - // Make sure it is allocated and mark the read-only map as incomplete. - m.dirtyLocked() - m.read.Store(&readOnly[K, V]{m: read.m, amended: true}) - } - m.dirty[key] = newEntry(value) - actual, loaded = value, false - } - m.mu.Unlock() - - return actual, loaded -} - -// tryLoadOrStore atomically loads or stores a value if the entry is not -// expunged. -// -// If the entry is expunged, tryLoadOrStore leaves the entry unchanged and -// returns with ok==false. -func (e *entry[V]) tryLoadOrStore(i V) (actual V, loaded, ok bool) { - ptr := atomic.LoadPointer(&e.p) - if ptr == expunged { - return actual, false, false - } - p := (*V)(ptr) - if p != nil { - return *p, true, true - } - - // Copy the interface after the first load to make this method more amenable - // to escape analysis: if we hit the "load" path or the entry is expunged, we - // shouldn't bother heap-allocating. - ic := i - for { - if atomic.CompareAndSwapPointer(&e.p, nil, unsafe.Pointer(&ic)) { - return i, false, true - } - ptr = atomic.LoadPointer(&e.p) - if ptr == expunged { - return actual, false, false - } - p = (*V)(ptr) - if p != nil { - return *p, true, true - } - } -} - -// LoadAndDelete deletes the value for a key, returning the previous value if any. -// The loaded result reports whether the key was present. -func (m *Map[K, V]) LoadAndDelete(key K) (value V, loaded bool) { - read := m.loadReadOnly() - e, ok := read.m[key] - if !ok && read.amended { - m.mu.Lock() - read = m.loadReadOnly() - e, ok = read.m[key] - if !ok && read.amended { - e, ok = m.dirty[key] - delete(m.dirty, key) - // Regardless of whether the entry was present, record a miss: this key - // will take the slow path until the dirty map is promoted to the read - // map. - m.missLocked() - } - m.mu.Unlock() - } - if ok { - return e.delete() - } - return value, false -} - -// Delete deletes the value for a key. -func (m *Map[K, V]) Delete(key K) { - m.LoadAndDelete(key) -} - -func (e *entry[V]) delete() (value V, ok bool) { - for { - p := atomic.LoadPointer(&e.p) - if p == nil || p == expunged { - return value, false - } - if atomic.CompareAndSwapPointer(&e.p, p, nil) { - return *(*V)(p), true - } - } -} - -// trySwap swaps a value if the entry has not been expunged. -// -// If the entry is expunged, trySwap returns false and leaves the entry -// unchanged. -func (e *entry[V]) trySwap(i *V) (*V, bool) { - for { - p := atomic.LoadPointer(&e.p) - if p == expunged { - return nil, false - } - if atomic.CompareAndSwapPointer(&e.p, p, unsafe.Pointer(i)) { - return (*V)(p), true - } - } -} - -// Swap swaps the value for a key and returns the previous value if any. -// The loaded result reports whether the key was present. -func (m *Map[K, V]) Swap(key K, value V) (previous V, loaded bool) { - read := m.loadReadOnly() - if e, ok := read.m[key]; ok { - if v, ok := e.trySwap(&value); ok { - if v == nil { - return previous, false - } - return *v, true - } - } - - m.mu.Lock() - read = m.loadReadOnly() - if e, ok := read.m[key]; ok { - if e.unexpungeLocked() { - // The entry was previously expunged, which implies that there is a - // non-nil dirty map and this entry is not in it. - m.dirty[key] = e - } - if v := e.swapLocked(&value); v != nil { - loaded = true - previous = *v - } - } else if e, ok := m.dirty[key]; ok { - if v := e.swapLocked(&value); v != nil { - loaded = true - previous = *v - } - } else { - if !read.amended { - // We're adding the first new key to the dirty map. - // Make sure it is allocated and mark the read-only map as incomplete. - m.dirtyLocked() - m.read.Store(&readOnly[K, V]{m: read.m, amended: true}) - } - m.dirty[key] = newEntry(value) - } - m.mu.Unlock() - return previous, loaded -} - -// Range calls f sequentially for each key and value present in the map. -// If f returns false, range stops the iteration. -// -// Range does not necessarily correspond to any consistent snapshot of the Map's -// contents: no key will be visited more than once, but if the value for any key -// is stored or deleted concurrently (including by f), Range may reflect any -// mapping for that key from any point during the Range call. Range does not -// block other methods on the receiver; even f itself may call any method on m. -// -// Range may be O(N) with the number of elements in the map even if f returns -// false after a constant number of calls. -func (m *Map[K, V]) Range(f func(key K, value V) bool) { - // We need to be able to iterate over all of the keys that were already - // present at the start of the call to Range. - // If read.amended is false, then read.m satisfies that property without - // requiring us to hold m.mu for a long time. - read := m.loadReadOnly() - if read.amended { - // m.dirty contains keys not in read.m. Fortunately, Range is already O(N) - // (assuming the caller does not break out early), so a call to Range - // amortizes an entire copy of the map: we can promote the dirty copy - // immediately! - m.mu.Lock() - read = m.loadReadOnly() - if read.amended { - read = readOnly[K, V]{m: m.dirty} - copyRead := read - m.read.Store(©Read) - m.dirty = nil - m.misses = 0 - } - m.mu.Unlock() - } - - for k, e := range read.m { - v, ok := e.load() - if !ok { - continue - } - if !f(k, v) { - break - } - } -} - -// CompareAndSwap swaps the old and new values for key -// if the value stored in the map is equal to old. -// The old value must be of a comparable type. -func CompareAndSwap[K comparable, V comparable](m *Map[K, V], key K, old, new V) (swapped bool) { - read := m.loadReadOnly() - if e, ok := read.m[key]; ok { - return tryCompareAndSwap(e, old, new) - } else if !read.amended { - return false // No existing value for key. - } - - m.mu.Lock() - defer m.mu.Unlock() - read = m.loadReadOnly() - swapped = false - if e, ok := read.m[key]; ok { - swapped = tryCompareAndSwap(e, old, new) - } else if e, ok := m.dirty[key]; ok { - swapped = tryCompareAndSwap(e, old, new) - // We needed to lock mu in order to load the entry for key, - // and the operation didn't change the set of keys in the map - // (so it would be made more efficient by promoting the dirty - // map to read-only). - // Count it as a miss so that we will eventually switch to the - // more efficient steady state. - m.missLocked() - } - return swapped -} - -// CompareAndDelete deletes the entry for key if its value is equal to old. -// The old value must be of a comparable type. -// -// If there is no current value for key in the map, CompareAndDelete -// returns false (even if the old value is the zero value of V). -func CompareAndDelete[K comparable, V comparable](m *Map[K, V], key K, old V) (deleted bool) { - read := m.loadReadOnly() - e, ok := read.m[key] - if !ok && read.amended { - m.mu.Lock() - read = m.loadReadOnly() - e, ok = read.m[key] - if !ok && read.amended { - e, ok = m.dirty[key] - // Don't delete key from m.dirty: we still need to do the “compare” part - // of the operation. The entry will eventually be expunged when the - // dirty map is promoted to the read map. - // - // Regardless of whether the entry was present, record a miss: this key - // will take the slow path until the dirty map is promoted to the read - // map. - m.missLocked() - } - m.mu.Unlock() - } - for ok { - ptr := atomic.LoadPointer(&e.p) - if ptr == nil || ptr == expunged { - return false - } - p := (*V)(ptr) - if *p != old { - return false - } - if atomic.CompareAndSwapPointer(&e.p, ptr, nil) { - return true - } - } - return false -} - -// tryCompareAndSwap compare the entry with the given old value and swaps -// it with a new value if the entry is equal to the old value, and the entry -// has not been expunged. -// -// If the entry is expunged, tryCompareAndSwap returns false and leaves -// the entry unchanged. -func tryCompareAndSwap[V comparable](e *entry[V], old, new V) bool { - ptr := atomic.LoadPointer(&e.p) - if ptr == nil || ptr == expunged { - return false - } - p := (*V)(ptr) - if *p != old { - return false - } - - // Copy the interface after the first load to make this method more amenable - // to escape analysis: if the comparison fails from the start, we shouldn't - // bother heap-allocating an interface value to store. - nc := new - for { - if atomic.CompareAndSwapPointer(&e.p, ptr, unsafe.Pointer(&nc)) { - return true - } - ptr = atomic.LoadPointer(&e.p) - if ptr == nil || ptr == expunged { - return false - } - p = (*V)(ptr) - if *p != old { - return false - } - } -} - -func (m *Map[K, V]) missLocked() { - m.misses++ - if m.misses < len(m.dirty) { - return - } - m.read.Store(&readOnly[K, V]{m: m.dirty}) - m.dirty = nil - m.misses = 0 -} - -func (m *Map[K, V]) dirtyLocked() { - if m.dirty != nil { - return - } - - read := m.loadReadOnly() - m.dirty = make(map[K]*entry[V], len(read.m)) - for k, e := range read.m { - if !e.tryExpungeLocked() { - m.dirty[k] = e - } - } -} - -func (e *entry[V]) tryExpungeLocked() (isExpunged bool) { - p := atomic.LoadPointer(&e.p) - for p == nil { - if atomic.CompareAndSwapPointer(&e.p, nil, expunged) { - return true - } - p = atomic.LoadPointer(&e.p) - } - return p == expunged -} -- cgit v1.3