// Package ipc provides Unix socket IPC for remote playback control of cliamp. // The protocol is newline-delimited JSON over a Unix domain socket. package ipc import "time" // Compile-time interface check. var _ Dispatcher = DispatcherFunc(nil) // Request is the JSON command sent by the client. type Request struct { Cmd string `json:"cmd"` Value float64 `json:"value,omitempty"` Playlist string `json:"playlist,omitempty"` Path string `json:"path,omitempty"` Name string `json:"name,omitempty"` Band int `json:"band,omitempty"` Sub string `json:"sub,omitempty"` Args []string `json:"args,omitempty"` } // Response is the JSON response sent by the server. type Response struct { OK bool `json:"ok"` Error string `json:"error,omitempty"` State string `json:"state,omitempty"` Track *TrackInfo `json:"track,omitempty"` Position float64 `json:"position,omitempty"` Duration float64 `json:"duration,omitempty"` Volume float64 `json:"volume,omitempty"` Playlist string `json:"playlist,omitempty"` Index int `json:"index,omitempty"` Total int `json:"total,omitempty"` Visualizer string `json:"visualizer,omitempty"` Shuffle *bool `json:"shuffle,omitempty"` Repeat string `json:"repeat,omitempty"` Mono *bool `json:"mono,omitempty"` Speed float64 `json:"speed,omitempty"` EQPreset string `json:"eq_preset,omitempty"` Device string `json:"device,omitempty"` Output string `json:"output,omitempty"` Items []string `json:"items,omitempty"` Theme *ThemeInfo `json:"theme,omitempty"` Bands []float64 `json:"bands,omitempty"` } // ThemeInfo carries the active theme name and its resolved hex colors. // Empty hex fields mean the default (ANSI fallback) theme is active. type ThemeInfo struct { Name string `json:"name"` Accent string `json:"accent,omitempty"` Fg string `json:"fg,omitempty"` BrightFg string `json:"bright_fg,omitempty"` Green string `json:"green,omitempty"` Yellow string `json:"yellow,omitempty"` Red string `json:"red,omitempty"` } // PluginDispatcher is the hook the IPC server calls to forward plugin.call and // plugin.commands requests to the Lua plugin manager. Optional — if nil, those // subcommands return an error. type PluginDispatcher interface { EmitCommand(plugin, command string, args []string) (string, error) CommandList() []string } // TrackInfo is the track metadata in a status response. type TrackInfo struct { Title string `json:"title,omitempty"` Artist string `json:"artist,omitempty"` Path string `json:"path"` } // DispatcherFunc adapts a plain function to the Dispatcher interface. type DispatcherFunc func(msg any) // Send implements Dispatcher. func (f DispatcherFunc) Send(msg any) { f(msg) } // IPC-specific messages sent to the TUI via prog.Send(). // For shared types (NextMsg, PrevMsg, StopMsg, PlayPauseMsg), see internal/playback. // PlayMsg requests playback to start (unpause only, not toggle). type PlayMsg struct{} // PauseMsg requests playback to pause (pause only, not toggle). type PauseMsg struct{} // VolumeMsg requests a relative volume change in dB. type VolumeMsg struct{ DB float64 } // SeekMsg requests a relative seek. type SeekMsg struct{ Offset time.Duration } // LoadMsg requests loading a playlist by name. // Reply receives the result so the client can report errors. type LoadMsg struct { Playlist string Reply chan Response } // QueueMsg requests queuing a file path for playback. type QueueMsg struct{ Path string } // ThemeMsg requests changing the TUI theme by name. // Reply receives confirmation or error if theme not found. type ThemeMsg struct { Name string Reply chan Response } // VisMsg requests changing the active visualizer by name. // If Name is "next", the visualizer cycles to the next mode. // Reply receives confirmation or error if mode not found. type VisMsg struct { Name string Reply chan Response } // ShuffleMsg requests toggling or setting shuffle mode. // If Name is "on"/"off", it sets the mode explicitly; "toggle" toggles. type ShuffleMsg struct { Name string Reply chan Response } // RepeatMsg requests setting or cycling the repeat mode. // Name is "off", "all", "one", or "cycle". type RepeatMsg struct { Name string Reply chan Response } // MonoMsg requests toggling or setting mono mode. // If Name is "on"/"off", it sets the mode explicitly; "toggle" toggles. type MonoMsg struct { Name string Reply chan Response } // SpeedMsg requests setting the playback speed. type SpeedMsg struct { Speed float64 Reply chan Response } // EQMsg requests setting EQ preset by name or a single band's gain. // If Band >= 0, sets that band to Value dB. Otherwise applies preset Name. type EQMsg struct { Name string Band int Value float64 Reply chan Response } // DeviceMsg requests switching the audio output device or listing devices. // If Name is "list", returns available devices. Otherwise switches to named device. type DeviceMsg struct { Name string Reply chan Response } // StatusRequestMsg asks the TUI for current state. // The TUI writes the response to Reply and closes the channel. type StatusRequestMsg struct { Reply chan Response } // BandsRequestMsg asks the TUI for the current visualizer band values // (smoothed) and the active visualizer mode name. Lightweight compared to // StatusRequestMsg — intended for high-rate polling from external widgets. type BandsRequestMsg struct { Reply chan Response }