aboutsummaryrefslogtreecommitdiff
path: root/src/dwm.c
diff options
context:
space:
mode:
authorFederico Angelilli <code@fedang.net>2024-07-08 15:22:41 +0200
committerFederico Angelilli <code@fedang.net>2024-07-08 15:22:41 +0200
commit5d170a634ead0119f6e5a9f63c23b2b064126f75 (patch)
tree0447d2dbb0da6358d184a4c62d5557d4d22f5e8d /src/dwm.c
parent92feb3c130966202c7caa6d9bf3a3800c97ca7a1 (diff)
Remove old files
Diffstat (limited to 'src/dwm.c')
-rw-r--r--src/dwm.c445
1 files changed, 0 insertions, 445 deletions
diff --git a/src/dwm.c b/src/dwm.c
deleted file mode 100644
index eda553e..0000000
--- a/src/dwm.c
+++ /dev/null
@@ -1,445 +0,0 @@
-#include <stdbool.h>
-#include <stdint.h>
-#include <glib.h>
-#include <gio/gio.h>
-#include <json-glib/json-glib.h>
-#include <json-glib/json-builder.h>
-
-#include "dwm.h"
-#include "log.h"
-
-#define IPC_MAGIC "DWM-IPC"
-#define IPC_MAGIC_LEN 7
-
-typedef struct {
- uint8_t magic[IPC_MAGIC_LEN];
- uint32_t size;
- uint8_t type;
-} __attribute__((packed)) DwmIpcHeader;
-
-typedef enum {
- IPC_TYPE_RUN_COMMAND = 0,
- IPC_TYPE_GET_MONITORS = 1,
- IPC_TYPE_GET_TAGS = 2,
- IPC_TYPE_GET_LAYOUTS = 3,
- IPC_TYPE_GET_DWM_CLIENT = 4,
- IPC_TYPE_SUBSCRIBE = 5,
- IPC_TYPE_EVENT = 6
-} DwmIpcMessage;
-
-#define IPC_EVENT_TAG_CHANGE "tag_change_event"
-#define IPC_EVENT_CLIENT_FOCUS_CHANGE "client_focus_change_event"
-#define IPC_EVENT_LAYOUT_CHANGE "layout_change_event"
-#define IPC_EVENT_MONITOR_FOCUS_CHANGE "monitor_focus_change_event"
-#define IPC_EVENT_FOCUSED_TITLE_CHANGE "focused_title_change_event"
-#define IPC_EVENT_FOCUSED_STATE_CHANGE "focused_state_change_event"
-
-static void ipc_send(DwmIpc *dwm, DwmIpcMessage msg_type, uint8_t *msg, uint32_t msg_size)
-{
- DwmIpcHeader header;
- memcpy(header.magic, IPC_MAGIC, IPC_MAGIC_LEN);
- header.size = msg_size;
- header.type = msg_type;
-
- GError *error = NULL;
-
- gssize size = 0;
- while (size < sizeof(DwmIpcHeader)) {
- gssize sent = g_socket_send(dwm->socket, (void *)&header + size, sizeof(DwmIpcHeader) - size, NULL, &error);
- if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
- g_error_free(error);
- continue;
- }
- g_assert(sent != -1);
- size += sent;
- }
-
- size = 0;
- while (size < msg_size) {
- gssize sent = g_socket_send(dwm->socket, msg + size, msg_size - size, NULL, &error);
- if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
- g_error_free(error);
- continue;
- }
- g_assert(sent != -1);
- size += sent;
- }
-
- log_debug("Sent ipc message [type=%d, size=%d]", msg_type, msg_size);
-}
-
-static void ipc_subscribe(DwmIpc *dwm, const char *event)
-{
- // {
- // "event": "<event>",
- // "action": "subscribe"
- // }
-
- JsonBuilder *builder = json_builder_new();
-
- json_builder_begin_object(builder);
-
- json_builder_set_member_name(builder, "event");
- json_builder_add_string_value(builder, event);
-
- json_builder_set_member_name(builder, "action");
- json_builder_add_string_value(builder, "subscribe");
-
- json_builder_end_object(builder);
-
- JsonNode *root = json_builder_get_root(builder);
-
- JsonGenerator *gen = json_generator_new();
- json_generator_set_root(gen, root);
-
- gsize msg_len = 0;
- gchar *msg = json_generator_to_data(gen, &msg_len);
-
- log_debug("Subscribing to dwm ipc: %s", msg);
- ipc_send(dwm, IPC_TYPE_SUBSCRIBE, msg, msg_len);
-
- json_node_free(root);
- g_object_unref(gen);
- g_object_unref(builder);
- g_free(msg);
-}
-
-static void ipc_run_command(DwmIpc *dwm, const char *cmd, JsonNode **args)
-{
- // {
- // "command": "<name>",
- // "args": [ ... ]
- // }
-
- JsonBuilder *builder = json_builder_new();
-
- json_builder_begin_object(builder);
-
- json_builder_set_member_name(builder, "command");
- json_builder_add_string_value(builder, cmd);
-
- json_builder_set_member_name(builder, "args");
- json_builder_begin_array(builder);
-
- while (*args != NULL) {
- json_builder_add_value(builder, *args++);
- }
-
- json_builder_end_array(builder);
- json_builder_end_object(builder);
-
- JsonNode *root = json_builder_get_root(builder);
-
- JsonGenerator *gen = json_generator_new();
- json_generator_set_root(gen, root);
-
- gsize msg_len = 0;
- gchar *msg = json_generator_to_data(gen, &msg_len);
-
- log_debug("Sending run_command to dwm ipc: %s", msg);
- ipc_send(dwm, IPC_TYPE_RUN_COMMAND, msg, msg_len);
-
- json_node_free(root);
- g_object_unref(gen);
- g_object_unref(builder);
- g_free(msg);
-}
-
-static void ipc_get_tags(DwmIpc *dwm)
-{
- log_debug("Sending get_tags to dwm ipc");
- ipc_send(dwm, IPC_TYPE_GET_TAGS, "", 1);
-}
-
-#define JSON_FIELD(reader, member) (json_reader_end_member(reader), json_reader_read_member(reader, member))
-
-static void ipc_handle(DwmIpc *dwm, DwmIpcMessage type, char *reply, uint32_t reply_size)
-{
- GError *error = NULL;
- JsonParser *parser = json_parser_new();
- if (!json_parser_load_from_data(parser, reply, reply_size - 1, &error)) {
- log_warning("Failed to parse dwm ipc reply: %s", error->message);
- g_error_free(error);
- return;
- }
-
- JsonReader *reader = json_reader_new(json_parser_get_root(parser));
-
- switch (type) {
- case IPC_TYPE_EVENT:
- {
- if (json_reader_read_member(reader, IPC_EVENT_TAG_CHANGE)) {
- log_debug("Handling dwm ipc event [event=%s]", IPC_EVENT_TAG_CHANGE);
-
- json_reader_read_member(reader, "new_state");
- json_reader_read_member(reader, "selected");
- long selected = json_reader_get_int_value(reader);
- json_reader_end_member(reader);
- json_reader_end_member(reader);
- json_reader_end_member(reader);
-
- log_debug("Selected tag mask: %ld", selected);
-
- if (dwm->tags[0] != NULL) {
- for (int i = 0; i < 9; i++)
- dwm->tags[i]->color = selected & (1 << i) ? dwm->selected : dwm->color;
-
- state_request_redraw(dwm->state, false);
- }
- } else if (JSON_FIELD(reader, IPC_EVENT_CLIENT_FOCUS_CHANGE)) {
- log_debug("Handling dwm ipc event [event=%s]", IPC_EVENT_CLIENT_FOCUS_CHANGE);
-
- json_reader_read_member(reader, "new_win_id");
- long win_id = json_reader_get_int_value(reader);
- json_reader_end_member(reader);
- json_reader_end_member(reader);
-
- char *msg = g_strdup_printf("{ \"client_window_id\": %ld }\n", win_id);
- dwm->change_title = true;
- ipc_send(dwm, IPC_TYPE_GET_DWM_CLIENT, msg, strlen(msg));
- g_free(msg);
- } else if (JSON_FIELD(reader, IPC_EVENT_LAYOUT_CHANGE)) {
- log_debug("Ignoring dwm ipc event [event=%s]", IPC_EVENT_LAYOUT_CHANGE);
- // TODO
-
- } else if (JSON_FIELD(reader, IPC_EVENT_MONITOR_FOCUS_CHANGE)) {
- log_debug("Ignoring dwm ipc event [event=%s]", IPC_EVENT_MONITOR_FOCUS_CHANGE);
- // TODO
-
- } else if (JSON_FIELD(reader, IPC_EVENT_FOCUSED_TITLE_CHANGE)) {
- log_debug("Ignoring dwm ipc event [event=%s]", IPC_EVENT_FOCUSED_TITLE_CHANGE);
- // TODO
-
- } else if (JSON_FIELD(reader, IPC_EVENT_FOCUSED_STATE_CHANGE)) {
- log_debug("Ignoring dwm ipc event [event=%s]", IPC_EVENT_FOCUSED_STATE_CHANGE);
- // TODO
-
- } else {
- const char *event = "?";
- if (json_reader_read_element(reader, 0))
- event = json_reader_get_string_value(reader);
-
- log_warning("Unrecognized dwm ipc event: %s", event);
- }
- break;
- }
-
- case IPC_TYPE_GET_DWM_CLIENT:
- {
- log_debug("Received dwm client information message [type=%d]", type);
-
- if (dwm->change_title) {
- json_reader_read_member(reader, "name");
- const char *title = json_reader_get_string_value(reader);
-
- log_debug("Changing current program title: %s", title ? title : "?");
- if (title == NULL || *title == '\0') {
- state_remove_button(dwm->state, dwm->title);
- dwm->hidden_title = true;
- } else {
- button_simple_set_text(dwm->title, g_strdup(title), dwm->text_color);
- if (dwm->hidden_title) {
- state_add_button(dwm->state, dwm->title);
- state_order_button(dwm->state);
- dwm->hidden_title = false;
- }
- }
-
- dwm->change_title = false;
- state_request_redraw(dwm->state, true);
- json_reader_end_member(reader);
- }
- break;
- }
-
- case IPC_TYPE_GET_TAGS:
- {
- log_debug("Received dwm tag information message [type=%d]", type);
-
- guint index = 0;
- while (json_reader_read_element(reader, index)) {
-
- json_reader_read_member(reader, "bit_mask");
- int mask = json_reader_get_int_value(reader);
- json_reader_end_element(reader);
-
- // XXX: Handle nicely
- g_assert_cmpint(mask, ==, 1 << index);
-
- // Set the tag names accordingly
- json_reader_read_member(reader, "name");
- const char *name = json_reader_get_string_value(reader);
- json_reader_end_element(reader);
-
- g_assert(index < 9);
- button_simple_set_text(dwm->tags[index], g_strdup(name), dwm->text_color);
-
- json_reader_end_element(reader);
- index++;
- }
-
- break;
- }
-
- default:
- {
- log_debug("Ignoring dwm ipc message [type=%d]", type);
- //log_debug("%s", reply);
- break;
- }
- }
-
- g_object_unref(reader);
- g_object_unref(parser);
-}
-
-static gboolean socket_callback(GSocket *socket, GIOCondition condition, gpointer data)
-{
- if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) return G_SOURCE_REMOVE;
- GError *error = NULL;
-
- DwmIpcHeader header;
- gssize size = 0;
- while (size < sizeof(DwmIpcHeader)) {
- gssize read = g_socket_receive(socket, (void *)&header + size, sizeof(DwmIpcHeader) - size, NULL, &error);
- if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
- g_error_free(error);
- continue;
- }
- g_assert(read != -1);
- size += read;
- }
-
- if (memcmp(&header, IPC_MAGIC, IPC_MAGIC_LEN) != 0) {
- log_warning("Malformed dwm ipc message");
- return G_SOURCE_CONTINUE;;
- }
-
- uint32_t reply_size;
- memcpy(&reply_size, (void *)&header + IPC_MAGIC_LEN, sizeof(uint32_t));
-
- uint8_t msg_type;
- memcpy(&msg_type, (void *)&header + IPC_MAGIC_LEN + sizeof(uint32_t), sizeof(uint8_t));
-
- char *reply = g_malloc(reply_size);
- size = 0;
- while (size < reply_size) {
- gssize read = g_socket_receive(socket, reply + size, reply_size - size, NULL, NULL);
- if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
- g_error_free(error);
- continue;
- }
- g_assert(read != -1);
- size += read;
- }
-
- //log_debug("Received dwm ipc response: %s", reply);
- ipc_handle(data, msg_type, reply, reply_size);
- g_free(reply);
-
- return G_SOURCE_CONTINUE;
-}
-
-DwmIpc *dwm_create(State *state, const char *socket)
-{
- DwmIpc *dwm = g_malloc0(sizeof(DwmIpc));
- dwm->state = state;
-
- GError *error = NULL;
- dwm->socket = g_socket_new(G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, 0, &error);
- g_assert_nonnull(dwm->socket);
-
- GSocketAddress *addr = g_unix_socket_address_new(socket);
- if (!g_socket_connect(dwm->socket, addr, NULL, &error)) {
- g_assert_nonnull(error);
- log_debug("Failed to connect socket %s: %s", socket, error->message);
- log_info("Skipped dwm ipc [socket=%s]", socket);
-
- g_error_free(error);
- g_object_unref(dwm->socket);
- g_free(dwm);
- return NULL;
- }
-
- dwm->source = g_socket_create_source(dwm->socket, G_IO_IN, NULL);
- g_source_set_static_name(dwm->source, "DwmIpcSource");
- g_source_set_callback(dwm->source, (GSourceFunc)socket_callback, dwm, NULL);
-
- const char *events[] = {
- IPC_EVENT_TAG_CHANGE,
- IPC_EVENT_CLIENT_FOCUS_CHANGE,
- IPC_EVENT_LAYOUT_CHANGE,
- IPC_EVENT_MONITOR_FOCUS_CHANGE,
- IPC_EVENT_FOCUSED_TITLE_CHANGE,
- IPC_EVENT_FOCUSED_STATE_CHANGE,
- };
- for (int i = 0; i < G_N_ELEMENTS(events); ++i)
- ipc_subscribe(dwm, events[i]);
-
- g_source_attach(dwm->source, NULL);
- log_info("Attached dwm ipc source [socket=%s]", socket);
-
- g_object_unref(addr);
- return dwm;
-}
-
-static void change_tag_action(Button *btn)
-{
- ButtonSimple *sbtn = CAST(btn, ButtonSimple);
- DwmIpc *dwm = sbtn->data;
-
- int n = sbtn->text[0] - '0';
- g_assert(n >= 1 && n <= 9);
-
- log_info("Toggled tag %d", n);
-
- JsonNode *args[] = {
- json_node_init_int(json_node_alloc(), 1 << (n - 1)),
- NULL
- };
- ipc_run_command(dwm, "view", args);
-}
-
-void dwm_register_tags(DwmIpc *dwm, Color color, Color selected, Color text_color)
-{
- if (dwm == NULL) return;
-
- dwm->color = color;
- dwm->text_color = text_color;
- dwm->selected = selected;
-
- // Tags button
- for (int i = 0; i < 9; ++i) {
- char text[] = { '1' + i, '\0' };
- dwm->tags[i] = button_simple_create(PANGO_ALIGN_LEFT, color);
- button_simple_set_text(dwm->tags[i], g_strdup(text), text_color);
- button_simple_set_action(dwm->tags[i], change_tag_action, dwm);
- state_add_button(dwm->state, dwm->tags[i]);
- }
-
- // This will set the tag names
- ipc_get_tags(dwm);
-
- dwm->title = button_simple_create(PANGO_ALIGN_CENTER, color);
- dwm->hidden_title = true;
-
- // FIXME: Set the first tag
- CAST(dwm->tags[0], ButtonSimple)->action(dwm->tags[0]);
- dwm->tags[0]->color = dwm->selected;
-}
-
-void dwm_destroy(DwmIpc *dwm)
-{
- if (dwm == NULL) return;
-
- g_source_destroy(dwm->source);
- g_source_unref(dwm->source);
- g_object_unref(dwm->socket);
-
- if (dwm->hidden_title)
- button_destroy(dwm->title);
-
- g_free(dwm);
-}
-
-// vim: ts=4 sw=4 et