aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/pipewire
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-12-07 02:00:19 +0900
committerOphestra <cat@gensokyo.uk>2025-12-07 02:00:19 +0900
commit503bfc64689ebf90ab54e59593976876600c4b9b (patch)
tree255e8a91069a23ea9f9629c0d9e18aaa67ff33a5 /internal/pipewire
parentd837628b4ca58b4de85c27dbf815decadd4a0903 (diff)
internal/system: port connect by name
This behaviour is a bit messy and checks what appears to be a windows-specific environment variable for some reason. Keeping everything intact regardless to match upstream behaviour. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/pipewire')
-rw-r--r--internal/pipewire/pipewire.go63
1 files changed, 63 insertions, 0 deletions
diff --git a/internal/pipewire/pipewire.go b/internal/pipewire/pipewire.go
index 907f8543..65178bf6 100644
--- a/internal/pipewire/pipewire.go
+++ b/internal/pipewire/pipewire.go
@@ -18,10 +18,13 @@ import (
"encoding/binary"
"fmt"
"io"
+ "net"
"os"
+ "path"
"runtime"
"slices"
"strconv"
+ "strings"
"syscall"
)
@@ -769,3 +772,63 @@ func (ctx *Context) Close() (err error) {
return err
}
}
+
+/* modules/module-protocol-native/local-socket.c */
+
+const DEFAULT_SYSTEM_RUNTIME_DIR = "/run/pipewire"
+
+// connectName connects to a PipeWire remote by name and returns the [net.UnixConn].
+func connectName(name string, manager bool) (conn *net.UnixConn, err error) {
+ if manager && !strings.HasSuffix(name, "-manager") {
+ return connectName(name+"-manager", false)
+ }
+
+ if path.IsAbs(name) || (len(name) > 0 && name[0] == '@') {
+ return net.DialUnix("unix", nil, &net.UnixAddr{Name: name, Net: "unix"})
+ } else {
+ runtimeDir, ok := os.LookupEnv("PIPEWIRE_RUNTIME_DIR")
+ if !ok || !path.IsAbs(runtimeDir) {
+ runtimeDir, ok = os.LookupEnv("XDG_RUNTIME_DIR")
+ }
+ if !ok || !path.IsAbs(runtimeDir) {
+ // this is cargo culted from windows stuff and has no effect normally;
+ // keeping it to maintain compatibility in case someone sets this
+ runtimeDir, ok = os.LookupEnv("USERPROFILE")
+ }
+
+ if !ok || !path.IsAbs(runtimeDir) {
+ runtimeDir = DEFAULT_SYSTEM_RUNTIME_DIR
+ }
+ return net.DialUnix("unix", nil, &net.UnixAddr{Name: path.Join(runtimeDir, name), Net: "unix"})
+ }
+}
+
+// ConnectName connects to a PipeWire remote by name.
+func ConnectName(name string, manager bool) (ctx *Context, err error) {
+ var props SPADict
+ if manager {
+ props = append(props, SPADictItem{Key: PW_KEY_REMOTE_INTENTION, Value: "manager"})
+ }
+
+ if name == "" {
+ if v, ok := os.LookupEnv("PIPEWIRE_REMOTE"); !ok || v == "" {
+ name = PW_DEFAULT_REMOTE
+ } else {
+ name = v
+ }
+ }
+
+ var conn *net.UnixConn
+ if conn, err = connectName(name, manager); err != nil {
+ return
+ }
+
+ if ctx, err = New(SyscallConn{conn}, props); err != nil {
+ ctx = nil
+ _ = conn.Close()
+ }
+ return
+}
+
+// Connect connects to the PipeWire remote.
+func Connect(manager bool) (ctx *Context, err error) { return ConnectName("", manager) }