args.go RawHistoryFolder
1package server
2
3import (
4 "math"
5 "runtime"
6 "unsafe"
7)
8
9// Arg is one raw union wl_argument value.
10type Arg uint64
11
12// Fixed is a wl_fixed_t: a signed 24.8 fixed-point number.
13type Fixed int32
14
15func FixedFromFloat(v float64) Fixed { return Fixed(math.Round(v * 256)) }
16func (f Fixed) Float() float64 { return float64(f) / 256 }
17
18// Argument constructors for PostEvent.
19func Uint(v uint32) Arg { return Arg(v) }
20func Int(v int32) Arg { return Arg(uint32(v)) }
21func FixedArg(v Fixed) Arg { return Arg(uint32(v)) }
22
23// Fd passes a file descriptor. libwayland duplicates it, so the caller keeps
24// ownership.
25func Fd(fd int) Arg { return Arg(uint32(int32(fd))) }
26
27// Object passes a resource, or a null object when r is nil.
28func Object(r *Resource) Arg {
29 if r == nil {
30 return 0
31 }
32 return Arg(r.c)
33}
34
35// NewID passes a resource created for a new_id event argument.
36func NewID(r *Resource) Arg { return Object(r) }
37
38// String passes a string. The bytes stay pinned until p is unpinned, which
39// must happen after PostEvent returns. With null set, "" is sent as NULL.
40func String(p *runtime.Pinner, s string, null bool) Arg {
41 if null && s == "" {
42 return 0
43 }
44 b := make([]byte, len(s)+1)
45 copy(b, s)
46 p.Pin(&b[0])
47 return Arg(uintptr(unsafe.Pointer(&b[0])))
48}
49
50// wlArray matches struct wl_array on LP64 (size_t, size_t, void *).
51type wlArray struct {
52 size uintptr
53 alloc uintptr
54 data unsafe.Pointer
55}
56
57// Array passes a byte array. See String for the pinning rule.
58func Array(p *runtime.Pinner, b []byte) Arg {
59 a := &wlArray{size: uintptr(len(b)), alloc: uintptr(len(b))}
60 if len(b) > 0 {
61 p.Pin(&b[0])
62 a.data = unsafe.Pointer(&b[0])
63 }
64 p.Pin(a)
65 return Arg(uintptr(unsafe.Pointer(a)))
66}
67
68// Request argument accessors. Values are only valid during dispatch; the
69// String and Array accessors copy.
70func (a Arg) Uint() uint32 { return uint32(a) }
71func (a Arg) Int() int32 { return int32(uint32(a)) }
72func (a Arg) Fixed() Fixed { return Fixed(int32(uint32(a))) }
73func (a Arg) NewID() uint32 { return uint32(a) }
74func (a Arg) Resource() *Resource { return live.resources[uintptr(a)] }
75
76// Fd returns a received file descriptor. The handler owns it and must close it.
77func (a Arg) Fd() int { return int(int32(uint32(a))) }
78
79// String copies a received string; NULL becomes "".
80func (a Arg) String() string {
81 p := *(*unsafe.Pointer)(unsafe.Pointer(&a)) // C memory owned by libwayland
82 if p == nil {
83 return ""
84 }
85 n := 0
86 for *(*byte)(unsafe.Add(p, n)) != 0 {
87 n++
88 }
89 return string(unsafe.Slice((*byte)(p), n))
90}
91
92// Array copies a received wl_array.
93func (a Arg) Array() []byte {
94 arr := (*wlArray)(*(*unsafe.Pointer)(unsafe.Pointer(&a))) // C memory owned by libwayland
95 if arr == nil || arr.size == 0 {
96 return nil
97 }
98 return append([]byte(nil), unsafe.Slice((*byte)(arr.data), arr.size)...)
99}