-i3Font *load_font(xcb_connection_t *conn, const char *pattern) {
- /* Check if we got the font cached */
- i3Font *font;
- TAILQ_FOREACH(font, &cached_fonts, fonts)
- if (strcmp(font->pattern, pattern) == 0)
- return font;
-
- i3Font *new = smalloc(sizeof(i3Font));
- xcb_void_cookie_t font_cookie;
- xcb_list_fonts_with_info_cookie_t info_cookie;
-
- /* Send all our requests first */
- new->id = xcb_generate_id(conn);
- font_cookie = xcb_open_font_checked(conn, new->id, strlen(pattern), pattern);
- info_cookie = xcb_list_fonts_with_info(conn, 1, strlen(pattern), pattern);
-
- check_error(conn, font_cookie, "Could not open font");
-
- /* Get information (height/name) for this font */
- xcb_list_fonts_with_info_reply_t *reply = xcb_list_fonts_with_info_reply(conn, info_cookie, NULL);
- exit_if_null(reply, "Could not load font \"%s\"\n", pattern);
-
- if (asprintf(&(new->name), "%.*s", xcb_list_fonts_with_info_name_length(reply),
- xcb_list_fonts_with_info_name(reply)) == -1)
- die("asprintf() failed\n");
- new->pattern = sstrdup(pattern);
- new->height = reply->font_ascent + reply->font_descent;
-
- /* Insert into cache */
- TAILQ_INSERT_TAIL(&cached_fonts, new, fonts);
-
- return new;
+xcb_window_t create_window(xcb_connection_t *conn, Rect dims,
+ uint16_t depth, xcb_visualid_t visual, uint16_t window_class,
+ enum xcursor_cursor_t cursor, bool map, uint32_t mask, uint32_t *values) {
+ xcb_window_t result = xcb_generate_id(conn);
+
+ /* If the window class is XCB_WINDOW_CLASS_INPUT_ONLY, we copy depth and
+ * visual id from the parent window. */
+ if (window_class == XCB_WINDOW_CLASS_INPUT_ONLY) {
+ depth = XCB_COPY_FROM_PARENT;
+ visual = XCB_COPY_FROM_PARENT;
+ }
+
+ xcb_create_window(conn,
+ depth,
+ result, /* the window id */
+ root, /* parent == root */
+ dims.x, dims.y, dims.width, dims.height, /* dimensions */
+ 0, /* border = 0, we draw our own */
+ window_class,
+ visual,
+ mask,
+ values);
+
+ /* Set the cursor */
+ if (xcursor_supported) {
+ mask = XCB_CW_CURSOR;
+ values[0] = xcursor_get_cursor(cursor);
+ xcb_change_window_attributes(conn, result, mask, values);
+ } else {
+ xcb_cursor_t cursor_id = xcb_generate_id(conn);
+ i3Font cursor_font = load_font("cursor", false);
+ int xcb_cursor = xcursor_get_xcb_cursor(cursor);
+ xcb_create_glyph_cursor(conn, cursor_id, cursor_font.specific.xcb.id,
+ cursor_font.specific.xcb.id, xcb_cursor, xcb_cursor + 1, 0, 0, 0,
+ 65535, 65535, 65535);
+ xcb_change_window_attributes(conn, result, XCB_CW_CURSOR, &cursor_id);
+ xcb_free_cursor(conn, cursor_id);
+ }
+
+ /* Map the window (= make it visible) */
+ if (map)
+ xcb_map_window(conn, result);
+
+ return result;