+
+/**
+ * This function resolves ~ in pathnames.
+ * It may resolve wildcards in the first part of the path, but if no match
+ * or multiple matches are found, it just returns a copy of path as given.
+ *
+ */
+char *resolve_tilde(const char *path);
+
+/**
+ * Get the path of the first configuration file found. If override_configpath is
+ * specified, that path is returned and saved for further calls. Otherwise,
+ * checks the home directory first, then the system directory, always taking
+ * into account the XDG Base Directory Specification ($XDG_CONFIG_HOME,
+ * $XDG_CONFIG_DIRS).
+ *
+ */
+char *get_config_path(const char *override_configpath, bool use_system_paths);
+
+#if !defined(__sun)
+/**
+ * Emulates mkdir -p (creates any missing folders)
+ *
+ */
+int mkdirp(const char *path, mode_t mode);
+#endif
+
+/** Helper structure for usage in format_placeholders(). */
+typedef struct placeholder_t {
+ /* The placeholder to be replaced, e.g., "%title". */
+ char *name;
+ /* The value this placeholder should be replaced with. */
+ char *value;
+} placeholder_t;
+
+/**
+ * Replaces occurrences of the defined placeholders in the format string.
+ *
+ */
+char *format_placeholders(char *format, placeholder_t *placeholders, int num);
+
+/* We need to flush cairo surfaces twice to avoid an assertion bug. See #1989
+ * and https://bugs.freedesktop.org/show_bug.cgi?id=92455. */
+#define CAIRO_SURFACE_FLUSH(surface) \
+ do { \
+ cairo_surface_flush(surface); \
+ cairo_surface_flush(surface); \
+ } while (0)
+
+/* A wrapper grouping an XCB drawable and both a graphics context
+ * and the corresponding cairo objects representing it. */
+typedef struct surface_t {
+ /* The drawable which is being represented. */
+ xcb_drawable_t id;
+
+ /* A classic XCB graphics context. */
+ xcb_gcontext_t gc;
+
+ xcb_visualtype_t *visual_type;
+
+ int width;
+ int height;
+
+ /* A cairo surface representing the drawable. */
+ cairo_surface_t *surface;
+
+ /* The cairo object representing the drawable. In general,
+ * this is what one should use for any drawing operation. */
+ cairo_t *cr;
+} surface_t;
+
+/**
+ * Initialize the surface to represent the given drawable.
+ *
+ */
+void draw_util_surface_init(xcb_connection_t *conn, surface_t *surface, xcb_drawable_t drawable,
+ xcb_visualtype_t *visual, int width, int height);
+
+/**
+ * Resize the surface to the given size.
+ *
+ */
+void draw_util_surface_set_size(surface_t *surface, int width, int height);
+
+/**
+ * Destroys the surface.
+ *
+ */
+void draw_util_surface_free(xcb_connection_t *conn, surface_t *surface);
+
+/**
+ * Parses the given color in hex format to an internal color representation.
+ * Note that the input must begin with a hash sign, e.g., "#3fbc59".
+ *
+ */
+color_t draw_util_hex_to_color(const char *color);
+
+/**
+ * Draw the given text using libi3.
+ * This function also marks the surface dirty which is needed if other means of
+ * drawing are used. This will be the case when using XCB to draw text.
+ *
+ */
+void draw_util_text(i3String *text, surface_t *surface, color_t fg_color, color_t bg_color, int x, int y, int max_width);
+
+/**
+ * Draws a filled rectangle.
+ * This function is a convenience wrapper and takes care of flushing the
+ * surface as well as restoring the cairo state.
+ *
+ */
+void draw_util_rectangle(surface_t *surface, color_t color, double x, double y, double w, double h);
+
+/**
+ * Clears a surface with the given color.
+ *
+ */
+void draw_util_clear_surface(surface_t *surface, color_t color);
+
+/**
+ * Copies a surface onto another surface.
+ *
+ */
+void draw_util_copy_surface(surface_t *src, surface_t *dest, double src_x, double src_y,
+ double dest_x, double dest_y, double width, double height);