summaryrefslogtreecommitdiff
path: root/lib/sway/ipc.vala
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sway/ipc.vala')
-rw-r--r--lib/sway/ipc.vala131
1 files changed, 131 insertions, 0 deletions
diff --git a/lib/sway/ipc.vala b/lib/sway/ipc.vala
new file mode 100644
index 0000000..5818883
--- /dev/null
+++ b/lib/sway/ipc.vala
@@ -0,0 +1,131 @@
+namespace AstalSway {
+ private const string IPC_MAGIC = "i3-ipc";
+
+ public enum PayloadType {
+ MESSAGE_RUN_COMMAND = 0,
+ MESSAGE_GET_WORKSPACES = 1,
+ MESSAGE_SUBSCRIBE = 2,
+ MESSAGE_GET_OUTPUTS = 3,
+ MESSAGE_GET_TREE = 4,
+ MESSAGE_GET_MARKS = 5,
+ MESSAGE_GET_BAR_CONFIG = 6,
+ MESSAGE_GET_VERSION = 7,
+ MESSAGE_GET_BINDING_NODES = 8,
+ MESSAGE_GET_CONFIG = 9,
+ MESSAGE_SEND_TICK = 10,
+ MESSAGE_SYNC = 11,
+ MESSAGE_GET_BINDING_STATE = 12,
+ MESSAGE_GET_INPUTS = 100,
+ MESSAGE_GET_SEATS = 101,
+ EVENT_WORKSPACE = 0x80000000,
+ EVENT_MODE = 0x80000002,
+ EVENT_WINDOW = 0x80000003,
+ EVENT_BARCONFIG_UPDATE = 0x80000004,
+ EVENT_BINDING = 0x80000005,
+ EVENT_SHUTDOWN = 0x80000006,
+ EVENT_TICK = 0x80000007,
+ EVENT_BAR_STATE_UPDATE = 0x80000014,
+ EVENT_INPUT = 0x80000015,
+ }
+
+ private struct IpcReply {
+ public PayloadType type;
+ public string payload;
+ }
+
+
+ // Basic interface to send and receive data through Sway IPjC
+ private class Ipc : Object {
+ private string SWAYSOCK = GLib.Environment.get_variable("SWAYSOCK");
+
+ internal void init() throws Error {
+ SWAYSOCK = GLib.Environment.get_variable("SWAYSOCK");
+
+ if (SWAYSOCK == null) {
+ critical("Unable to detect Sway");
+ return;
+ }
+ }
+
+ internal SocketConnection? connection() {
+ try {
+ SocketConnection socket = new SocketClient().connect(new UnixSocketAddress(SWAYSOCK), null);
+ return socket;
+ } catch (Error err) {
+ critical(err.message);
+ return null;
+ }
+ }
+
+ internal void send(OutputStream stream, PayloadType type, string payload) {
+ Array<uint8> message = new Array<uint8> ();
+
+ uint8[] magic_str = IPC_MAGIC.data;
+ uint32 pl_length = (uint32) payload.length;
+ uint32 pl_type = (uint32) type;
+ uint8[] pl_data = payload.data;
+
+ message.append_vals(magic_str, magic_str.length);
+ message.append_vals((uint8 *)&pl_length, 4);
+ message.append_vals((uint8 *)&pl_type, 4);
+ message.append_vals(pl_data, pl_data.length);
+
+ stream.write(message.data);
+ }
+
+ internal IpcReply? receive(InputStream stream) {
+ var header = stream.read_bytes(14);
+ uint8 *data = header.get_data();
+ if (data == null) {
+ return null;
+ }
+ uint32 pl_length = *(uint32 *)&data[IPC_MAGIC.length];
+ PayloadType pl_type = *(uint32 *)&data[IPC_MAGIC.length+4];
+
+ var result = stream.read_bytes(pl_length);
+ return {pl_type, (string)result.get_data()};
+
+ }
+
+ internal async IpcReply? receive_async(InputStream stream) {
+ var header = yield stream.read_bytes_async(14, Priority.DEFAULT, null);
+ uint8 *data = header.get_data();
+ if (data == null) {
+ return null;
+ }
+ uint32 pl_length = *(uint32 *)&data[IPC_MAGIC.length];
+ PayloadType pl_type = *(uint32 *)&data[IPC_MAGIC.length+4];
+
+ var result = yield stream.read_bytes_async(pl_length, Priority.DEFAULT, null);
+
+ return {pl_type, (string)result.get_data()};
+ }
+
+ public string message(PayloadType type, string payload) {
+ SocketConnection conn = connection();
+ if (conn == null) {
+ return "";
+ }
+
+ send(conn.output_stream, type, payload);
+ var result = receive(conn.input_stream);
+ conn.close(null);
+
+ return result.payload;
+ }
+
+ public async string message_async(PayloadType type, string payload) {
+ SocketConnection conn = connection();
+ if (conn == null) {
+ return "";
+ }
+
+ send(conn.output_stream, type, payload);
+ var result = yield receive_async(conn.input_stream);
+ conn.close(null);
+
+ return result.payload;
+ }
+
+ }
+}