+/* Used temporarily while reading a statusline */
+struct statusline_head statusline_buffer = TAILQ_HEAD_INITIALIZER(statusline_buffer);
+
+int child_stdin;
+
+/*
+ * Remove all blocks from the given statusline.
+ * If free_resources is set, the fields of each status block will be free'd.
+ */
+static void clear_statusline(struct statusline_head *head, bool free_resources) {
+ struct status_block *first;
+ while (!TAILQ_EMPTY(head)) {
+ first = TAILQ_FIRST(head);
+ if (free_resources) {
+ I3STRING_FREE(first->full_text);
+ I3STRING_FREE(first->short_text);
+ FREE(first->color);
+ FREE(first->name);
+ FREE(first->instance);
+ FREE(first->min_width_str);
+ }
+
+ TAILQ_REMOVE(head, first, blocks);
+ free(first);
+ }
+}
+
+static void copy_statusline(struct statusline_head *from, struct statusline_head *to) {
+ struct status_block *current;
+ TAILQ_FOREACH(current, from, blocks) {
+ struct status_block *new_block = smalloc(sizeof(struct status_block));
+ memcpy(new_block, current, sizeof(struct status_block));
+ TAILQ_INSERT_TAIL(to, new_block, blocks);
+ }
+}
+
+/*
+ * Replaces the statusline in memory with an error message. Pass a format
+ * string and format parameters as you would in `printf'. The next time
+ * `draw_bars' is called, the error message text will be drawn on the bar in
+ * the space allocated for the statusline.
+ */
+__attribute__((format(printf, 1, 2))) static void set_statusline_error(const char *format, ...) {
+ clear_statusline(&statusline_head, true);
+
+ char *message;
+ va_list args;
+ va_start(args, format);
+ (void)vasprintf(&message, format, args);
+
+ struct status_block *err_block = scalloc(sizeof(struct status_block));
+ err_block->full_text = i3string_from_utf8("Error: ");
+ err_block->name = "error";
+ err_block->color = "red";
+ err_block->no_separator = true;
+
+ struct status_block *message_block = scalloc(sizeof(struct status_block));
+ message_block->full_text = i3string_from_utf8(message);
+ message_block->name = "error_message";
+ message_block->color = "red";
+ message_block->no_separator = true;
+
+ TAILQ_INSERT_HEAD(&statusline_head, err_block, blocks);
+ TAILQ_INSERT_TAIL(&statusline_head, message_block, blocks);
+
+ FREE(message);
+ va_end(args);
+}