2021-12-21 19:43:46 +01:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
// Standard
|
|
|
|
"encoding/binary"
|
|
|
|
"fmt"
|
|
|
|
"net"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
RUN_COMMAND = 0
|
|
|
|
GET_WORKSPACES = 1
|
|
|
|
SUBSCRIBE = 2
|
|
|
|
GET_OUTPUTS = 3
|
|
|
|
GET_TREE = 4
|
|
|
|
GET_MARKS = 5
|
|
|
|
GET_BAR_CONFIG = 6
|
|
|
|
GET_VERSION = 7
|
|
|
|
GET_BINDING_MODES = 8
|
|
|
|
GET_CONFIG = 9
|
|
|
|
SEND_TICK = 10
|
|
|
|
SYNC = 11
|
|
|
|
)
|
|
|
|
|
|
|
|
func NewI3Socket(filename string) (I3Socket, error) {
|
|
|
|
var i3Socket I3Socket
|
|
|
|
var err error
|
|
|
|
|
2021-12-23 09:06:43 +01:00
|
|
|
i3Socket.filename = filename
|
|
|
|
err = i3Socket.Open()
|
2021-12-21 19:43:46 +01:00
|
|
|
if err != nil {
|
|
|
|
return i3Socket, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return i3Socket, nil
|
|
|
|
}
|
2021-12-23 09:06:43 +01:00
|
|
|
func (sock *I3Socket) Open() (err error) {
|
|
|
|
sock.conn, err = net.Dial("unix", sock.filename)
|
|
|
|
return
|
|
|
|
}
|
2021-12-21 19:43:46 +01:00
|
|
|
|
|
|
|
func (sock I3Socket) Close() error {
|
|
|
|
return sock.conn.Close()
|
|
|
|
}
|
|
|
|
|
|
|
|
func I3ReadMessage(sock I3Socket) (msg []byte, err error) {
|
|
|
|
buf := make([]byte, 6)
|
|
|
|
if _, err = sock.conn.Read(buf); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if string(buf) != "i3-ipc" {
|
|
|
|
return nil, fmt.Errorf("Invalid i3 IPC answer")
|
|
|
|
}
|
|
|
|
|
|
|
|
// LE encoded length
|
|
|
|
buf = make([]byte, 4)
|
|
|
|
if _, err = sock.conn.Read(buf); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
msgLength := binary.LittleEndian.Uint32(buf)
|
|
|
|
|
|
|
|
// LE encoded msg type
|
|
|
|
buf = make([]byte, 4)
|
|
|
|
if _, err = sock.conn.Read(buf); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Requested data
|
|
|
|
buf = make([]byte, msgLength)
|
|
|
|
if _, err = sock.conn.Read(buf); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
msg = buf
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (sock I3Socket) Request(typ int, message string) ([]byte, error) {
|
|
|
|
header := []byte("i3-ipc")
|
|
|
|
buf := make([]byte, 8)
|
|
|
|
binary.LittleEndian.PutUint32(buf, uint32(len(message)))
|
|
|
|
binary.LittleEndian.PutUint32(buf[4:], uint32(typ))
|
|
|
|
msg := append(header, buf...)
|
|
|
|
msg = append(msg, ([]byte(message))...)
|
|
|
|
|
|
|
|
_, err := sock.conn.Write(msg)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
buf, err = I3ReadMessage(sock)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return buf, nil
|
|
|
|
}
|