i3-session-manager/socket.go

97 lines
1.8 KiB
Go

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
i3Socket.filename = filename
err = i3Socket.Open()
if err != nil {
return i3Socket, err
}
return i3Socket, nil
}
func (sock *I3Socket) Open() (err error) {
sock.conn, err = net.Dial("unix", sock.filename)
return
}
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
}