int min(int a, int b);
int max(int a, int b);
+void exit_if_null(void *pointer, char *fmt, ...);
+void die(char *fmt, ...);
+void *smalloc(size_t size);
+char *sstrdup(const char *str);
void start_application(const char *command);
void check_error(xcb_connection_t *connection, xcb_void_cookie_t cookie, char *err_message);
void set_focus(xcb_connection_t *conn, Client *client);
*
* i3 - an improved dynamic tiling window manager
*
- * (c) 2009 Michael Stapelberg and contributors
+ * © 2009 Michael Stapelberg and contributors
*
* See file LICENSE for license information.
*
- */
-/*
- * Handles font loading
+ * font.c: Handles font loading (with caching, with height information)
*
*/
#include <string.h>
* maintains a cache.
*
*/
-i3Font *load_font(xcb_connection_t *c, const char *pattern) {
+i3Font *load_font(xcb_connection_t *connection, 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 = malloc(sizeof(i3Font));
+ i3Font *new = smalloc(sizeof(i3Font));
/* Send all our requests first */
- new->id = xcb_generate_id(c);
- xcb_void_cookie_t font_cookie = xcb_open_font_checked(c, new->id, strlen(pattern), pattern);
- xcb_list_fonts_with_info_cookie_t cookie = xcb_list_fonts_with_info(c, 1, strlen(pattern), pattern);
+ new->id = xcb_generate_id(connection);
+ xcb_void_cookie_t font_cookie = xcb_open_font_checked(connection, new->id, strlen(pattern), pattern);
+ xcb_list_fonts_with_info_cookie_t cookie = xcb_list_fonts_with_info(connection, 1, strlen(pattern), pattern);
- check_error(c, font_cookie, "Could not open font");
+ check_error(connection, 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(c, cookie, NULL);
- if (reply == NULL) {
- printf("Could not load font\n");
- exit(1);
- }
-
- asprintf(&(new->name), "%.*s", xcb_list_fonts_with_info_name_length(reply),
- xcb_list_fonts_with_info_name(reply));
- new->pattern = strdup(pattern);
+ xcb_list_fonts_with_info_reply_t *reply = xcb_list_fonts_with_info_reply(connection, 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 */
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
+#include <stdarg.h>
#include "i3.h"
#include "data.h"
return (a > b ? a : b);
}
+/*
+ * Checks if pointer is NULL and exits the whole program, printing a message to stdout
+ * before with the given format (see printf())
+ *
+ */
+void exit_if_null(void *pointer, char *fmt, ...) {
+ va_list args;
+
+ if (pointer != NULL)
+ return;
+
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+
+ exit(EXIT_FAILURE);
+}
+
+/*
+ * Prints the message (see printf()) to stderr, then exits the program.
+ *
+ */
+void die(char *fmt, ...) {
+ va_list args;
+
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+
+ exit(EXIT_FAILURE);
+}
+
+/*
+ * The s* functions (safe) are wrappers around malloc, strdup, …, which exits if one of
+ * the called functions returns NULL, meaning that there is no more memory available
+ *
+ */
+void *smalloc(size_t size) {
+ void *result = malloc(size);
+ exit_if_null(result, "Too less memory for malloc(%d)\n", size);
+ return result;
+}
+
+char *sstrdup(const char *str) {
+ char *result = strdup(str);
+ exit_if_null(result, "Too less memory for strdup()\n");
+ return result;
+}
+
/*
* 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),