+void propertynotify(xcb_property_notify_event_t *);
+void quirk_free(struct quirk *);
+void quirk_insert(const char *, const char *, const char *, uint32_t, int);
+void quirk_remove(struct quirk *);
+void quirk_replace(struct quirk *, const char *, const char *, const char *,
+ uint32_t, int);
+void quit(struct swm_region *, union arg *);
+void raise_toggle(struct swm_region *, union arg *);
+void raise_window(struct ws_win *);
+void region_containment(struct ws_win *, struct swm_region *, int);
+struct swm_region *region_under(struct swm_screen *, int, int);
+void regionize(struct ws_win *, int, int);
+void resize(struct ws_win *, union arg *);
+void resize_step(struct swm_region *, union arg *);
+void restart(struct swm_region *, union arg *);
+struct swm_region *root_to_region(xcb_window_t, int);
+void screenchange(xcb_randr_screen_change_notify_event_t *);
+void scan_randr(int);
+void search_do_resp(void);
+void search_resp_name_workspace(const char *, size_t);
+void search_resp_search_window(const char *);
+void search_resp_search_workspace(const char *);
+void search_resp_uniconify(const char *, size_t);
+void search_win(struct swm_region *, union arg *);
+void search_win_cleanup(void);
+void search_workspace(struct swm_region *, union arg *);
+void send_to_rg(struct swm_region *, union arg *);
+void send_to_ws(struct swm_region *, union arg *);
+void set_region(struct swm_region *);
+int setautorun(const char *, const char *, int);
+int setconfbinding(const char *, const char *, int);
+int setconfcolor(const char *, const char *, int);
+int setconfmodkey(const char *, const char *, int);
+int setconfquirk(const char *, const char *, int);
+int setconfregion(const char *, const char *, int);
+int setconfspawn(const char *, const char *, int);
+int setconfvalue(const char *, const char *, int);
+void setkeybinding(unsigned int, KeySym, enum keyfuncid, const char *);
+int setkeymapping(const char *, const char *, int);
+int setlayout(const char *, const char *, int);
+void setquirk(const char *, const char *, const char *, uint32_t, int);
+void setscreencolor(const char *, int, int);
+void setspawn(const char *, const char *, int);
+void setup_ewmh(void);
+void setup_globals(void);
+void setup_keys(void);
+void setup_quirks(void);
+void setup_screens(void);
+void setup_spawn(void);
+void set_child_transient(struct ws_win *, xcb_window_t *);
+void set_win_state(struct ws_win *, uint8_t);
+void shutdown_cleanup(void);
+void sighdlr(int);
+void socket_setnonblock(int);
+void sort_windows(struct ws_win_list *);
+void spawn(int, union arg *, bool);
+void spawn_custom(struct swm_region *, union arg *, const char *);
+int spawn_expand(struct swm_region *, union arg *, const char *, char ***);
+void spawn_insert(const char *, const char *, int);
+struct spawn_prog *spawn_find(const char *);
+void spawn_remove(struct spawn_prog *);
+void spawn_replace(struct spawn_prog *, const char *, const char *, int);
+void spawn_select(struct swm_region *, union arg *, const char *, int *);
+void stack_config(struct swm_region *, union arg *);
+void stack_master(struct workspace *, struct swm_geometry *, int, bool);
+void store_float_geom(struct ws_win *);
+char *strdupsafe(const char *);
+void swapwin(struct swm_region *, union arg *);
+void switchws(struct swm_region *, union arg *);
+void teardown_ewmh(void);
+void unescape_selector(char *);
+void unfocus_win(struct ws_win *);
+void uniconify(struct swm_region *, union arg *);
+void unmanage_window(struct ws_win *);
+void unmapnotify(xcb_unmap_notify_event_t *);
+void unmap_all(void);
+void unmap_window(struct ws_win *);
+void updatenumlockmask(void);
+void update_floater(struct ws_win *);
+void update_modkey(unsigned int);
+void update_win_stacking(struct ws_win *);
+void update_window(struct ws_win *);
+void update_window_color(struct ws_win *);
+void update_wm_state(struct ws_win *win);
+void validate_spawns(void);
+int validate_win(struct ws_win *);
+int validate_ws(struct workspace *);
+void version(struct swm_region *, union arg *);
+void win_to_ws(struct ws_win *, int, bool);
+pid_t window_get_pid(xcb_window_t);
+void wkill(struct swm_region *, union arg *);
+void update_ws_stack(struct workspace *);
+void xft_init(struct swm_region *);
+void _add_startup_exception(const char *, va_list);
+void add_startup_exception(const char *, ...);
+
+RB_PROTOTYPE(key_tree, key, entry, key_cmp);
+RB_GENERATE(key_tree, key, entry, key_cmp);
+struct key_tree keys;
+
+void
+cursors_load(void)
+{
+ xcb_font_t cf = XCB_NONE;
+ int i;
+
+ for (i = 0; i < LENGTH(cursors); ++i) {
+ /* try to load Xcursor first. */
+ cursors[i].cid = XcursorLibraryLoadCursor(display,
+ cursors[i].name);
+
+ /* fallback to cursorfont. */
+ if (cursors[i].cid == XCB_CURSOR_NONE) {
+ if (cf == XCB_NONE) {
+ cf = xcb_generate_id(conn);
+ xcb_open_font(conn, cf, strlen("cursor"),
+ "cursor");
+ }
+
+ cursors[i].cid = xcb_generate_id(conn);
+ xcb_create_glyph_cursor(conn, cursors[i].cid, cf, cf,
+ cursors[i].cf_char, cursors[i].cf_char + 1, 0, 0, 0,
+ 0xffff, 0xffff, 0xffff);
+
+ }
+ }
+
+ if (cf != XCB_NONE)
+ xcb_close_font(conn, cf);
+}
+
+void
+cursors_cleanup(void)
+{
+ int i;
+ for (i = 0; i < LENGTH(cursors); ++i)
+ xcb_free_cursor(conn, cursors[i].cid);
+}
+
+char *
+expand_tilde(const char *s)
+{
+ struct passwd *ppwd;
+ int i;
+ long max;
+ char *user;
+ const char *sc = s;
+ char *result;
+
+ if (s == NULL)
+ errx(1, "expand_tilde: NULL string.");
+
+ if (s[0] != '~') {
+ result = strdup(sc);
+ goto out;
+ }
+
+ ++s;
+
+ if ((max = sysconf(_SC_LOGIN_NAME_MAX)) == -1)
+ errx(1, "expand_tilde: sysconf");
+
+ if ((user = calloc(1, max + 1)) == NULL)
+ errx(1, "expand_tilde: calloc");
+
+ for (i = 0; s[i] != '/' && s[i] != '\0'; ++i)
+ user[i] = s[i];
+ user[i] = '\0';
+ s = &s[i];
+
+ ppwd = strlen(user) == 0 ? getpwuid(getuid()) : getpwnam(user);
+ free(user);
+
+ if (ppwd == NULL)
+ result = strdup(sc);
+ else
+ if (asprintf(&result, "%s%s", ppwd->pw_dir, s) == -1)
+ result = NULL;
+out:
+ if (result == NULL)
+ errx(1, "expand_tilde: failed to allocate memory.");
+
+ return result;
+}