]> git.sur5r.net Git - i3/i3/blobdiff - src/util.c
implement 'move' command in the new parser
[i3/i3] / src / util.c
index 2f8225c0f493707625bfca9f85eef446206fe654..c8f4ee389492962b8817b8be39737dcbed20362a 100644 (file)
  * util.c: Utility functions, which can be useful everywhere.
  *
  */
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
 #include <sys/wait.h>
 #include <stdarg.h>
-#include <assert.h>
 #include <iconv.h>
 #if defined(__OpenBSD__)
 #include <sys/cdefs.h>
 #endif
 
-#include <xcb/xcb_icccm.h>
+#include <fcntl.h>
 
-#include "i3.h"
-#include "data.h"
-#include "table.h"
-#include "layout.h"
-#include "util.h"
-#include "xcb.h"
-#include "client.h"
-#include "log.h"
-#include "ewmh.h"
+#include "all.h"
 
 static iconv_t conversion_descriptor = 0;
-struct keyvalue_table_head by_parent = TAILQ_HEAD_INITIALIZER(by_parent);
-struct keyvalue_table_head by_child = TAILQ_HEAD_INITIALIZER(by_child);
 
 int min(int a, int b) {
         return (a < b ? a : b);
@@ -46,6 +31,13 @@ int max(int a, int b) {
         return (a > b ? a : b);
 }
 
+bool rect_contains(Rect rect, uint32_t x, uint32_t y) {
+        return (x >= rect.x &&
+                x <= (rect.x + rect.width) &&
+                y >= rect.y &&
+                y <= (rect.y + rect.height));
+}
+
 /*
  * Updates *destination with new_value and returns true if it was changed or false
  * if it was the same
@@ -74,50 +66,18 @@ void *scalloc(size_t size) {
         return result;
 }
 
+void *srealloc(void *ptr, size_t size) {
+        void *result = realloc(ptr, size);
+        exit_if_null(result, "Error: out memory (realloc(%zd))\n", size);
+        return result;
+}
+
 char *sstrdup(const char *str) {
         char *result = strdup(str);
         exit_if_null(result, "Error: out of memory (strdup())\n");
         return result;
 }
 
-/*
- * The table_* functions emulate the behaviour of libxcb-wm, which in libxcb 0.3.4 suddenly
- * vanished. Great.
- *
- */
-bool table_put(struct keyvalue_table_head *head, uint32_t key, void *value) {
-        struct keyvalue_element *element = scalloc(sizeof(struct keyvalue_element));
-        element->key = key;
-        element->value = value;
-
-        TAILQ_INSERT_TAIL(head, element, elements);
-        return true;
-}
-
-void *table_remove(struct keyvalue_table_head *head, uint32_t key) {
-        struct keyvalue_element *element;
-
-        TAILQ_FOREACH(element, head, elements)
-                if (element->key == key) {
-                        void *value = element->value;
-                        TAILQ_REMOVE(head, element, elements);
-                        free(element);
-                        return value;
-                }
-
-        return NULL;
-}
-
-void *table_get(struct keyvalue_table_head *head, uint32_t key) {
-        struct keyvalue_element *element;
-
-        TAILQ_FOREACH(element, head, elements)
-                if (element->key == key)
-                        return element->value;
-
-        return NULL;
-}
-
 /*
  * Starts the given application by passing it through a shell. We use double fork
  * to avoid zombie processes. As the started application’s parent exits (immediately),
@@ -129,6 +89,7 @@ void *table_get(struct keyvalue_table_head *head, uint32_t key) {
  *
  */
 void start_application(const char *command) {
+        LOG("executing: %s\n", command);
         if (fork() == 0) {
                 /* Child process */
                 if (fork() == 0) {
@@ -205,6 +166,7 @@ char *convert_utf8_to_ucs2(char *input, int *real_strlen) {
 
         return buffer;
 }
+#if 0
 
 /*
  * Returns the client which comes next in focus stack (= was selected before) for
@@ -298,12 +260,17 @@ void set_focus(xcb_connection_t *conn, Client *client, bool set_anyways) {
                         redecorate_window(conn, current);
                         break;
                 }
-
         }
 
         SLIST_REMOVE(&(client->workspace->focus_stack), client, Client, focus_clients);
         SLIST_INSERT_HEAD(&(client->workspace->focus_stack), client, focus_clients);
 
+        /* Clear the urgency flag if set (necessary when i3 sets the flag, for
+         * example when automatically putting windows on the workspace of their
+         * leader) */
+        client->urgent = false;
+        workspace_update_urgent_flag(client->workspace);
+
         /* If we’re in stacking mode, this renders the container to update changes in the title
            bars and to raise the focused client */
         if ((old_client != NULL) && (old_client != client) && !old_client->dock)
@@ -474,6 +441,7 @@ done:
         FREE(to_title_ucs);
         return matching;
 }
+#endif
 
 /*
  * Goes through the list of arguments (for exec()) and checks if the given argument
@@ -498,12 +466,59 @@ static char **append_argument(char **original, char *argument) {
         return result;
 }
 
+#define y(x, ...) yajl_gen_ ## x (gen, ##__VA_ARGS__)
+#define ystr(str) yajl_gen_string(gen, (unsigned char*)str, strlen(str))
+
+void store_restart_layout() {
+        yajl_gen gen = yajl_gen_alloc(NULL, NULL);
+
+        dump_node(gen, croot, true);
+
+        const unsigned char *payload;
+        unsigned int length;
+        y(get_buf, &payload, &length);
+
+        char *globbed = glob_path("~/.i3/_restart.json");
+        int fd = open(globbed, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+        free(globbed);
+        if (fd == -1) {
+                perror("open()");
+                return;
+        }
+
+        int written = 0;
+        while (written < length) {
+                int n = write(fd, payload + written, length - written);
+                /* TODO: correct error-handling */
+                if (n == -1) {
+                        perror("write()");
+                        return;
+                }
+                if (n == 0) {
+                        printf("write == 0?\n");
+                        return;
+                }
+                written += n;
+                printf("written: %d of %d\n", written, length);
+        }
+        close(fd);
+
+        printf("layout: %.*s\n", length, payload);
+
+        y(free);
+}
+
 /*
  * Restart i3 in-place
  * appends -a to argument list to disable autostart
  *
  */
 void i3_restart() {
+        store_restart_layout();
+        restore_geometry();
+
+        //ipc_shutdown();
+
         LOG("restarting \"%s\"...\n", start_argv[0]);
         /* make sure -a is in the argument list or append it */
         start_argv = append_argument(start_argv, "-a");
@@ -512,6 +527,8 @@ void i3_restart() {
         /* not reached */
 }
 
+#if 0
+
 #if defined(__OpenBSD__)
 
 /*
@@ -547,4 +564,4 @@ void *memmem(const void *l, size_t l_len, const void *s, size_t s_len) {
 }
 
 #endif
-
+#endif