commit 236104387a38581c2d7e0b50dd208d6f2db4e312
parent ffdfc8d4bc5e24eab86b857e637d60c7521bf0b0
Author: lumidify <nobody@lumidify.org>
Date: Wed, 30 Dec 2020 21:37:51 +0100
Improve error reporting
Diffstat:
M | button.c | | | 44 | ++++++++++++++++++++++++++++---------------- |
M | button.h | | | 5 | +++-- |
M | color.c | | | 3 | ++- |
M | draw.c | | | 230 | ++++++++++++++++++++++++++++++++++++++++++++----------------------------------- |
M | draw.h | | | 5 | +++-- |
M | grid.c | | | 264 | +++++++++++++++++++++++++++++++++++++++++++------------------------------------ |
M | grid.h | | | 2 | +- |
M | ltk.h | | | 7 | ++++--- |
M | ltkd.c | | | 116 | +++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------- |
M | text_pango.c | | | 4 | +++- |
M | text_stb.c | | | 12 | ++++++------ |
M | util.c | | | 3 | ++- |
12 files changed, 403 insertions(+), 292 deletions(-)
diff --git a/button.c b/button.c
@@ -196,15 +196,18 @@ ltk_button_mouse_release(ltk_button *button, XEvent event) {
static ltk_button *
ltk_button_create(ltk_window *window, const char *id, const char *text) {
+ char *text_copy;
ltk_button *button = malloc(sizeof(ltk_button));
- if (!button) ltk_fatal("ERROR: Unable to allocate memory for ltk_button.\n");
+ if (!button) ltk_fatal_errno("Unable to allocate memory for ltk_button.\n");
ltk_fill_widget_defaults(&button->widget, id, window,
<k_button_draw, <k_button_change_state, <k_button_destroy, 1, LTK_BUTTON);
button->widget.mouse_release = <k_button_mouse_release;
uint16_t font_size = window->theme.font_size;
- /* FIXME: check return of strdup */
- button->tl = ltk_text_line_create(window->xwindow, font_size, strdup(text), -1);
+ text_copy = strdup(text);
+ if (!text_copy)
+ ltk_fatal_errno("Unable to allocate button text.\n");
+ button->tl = ltk_text_line_create(window->xwindow, font_size, text_copy, -1);
int text_w, text_h;
ltk_text_line_get_size(button->tl, &text_w, &text_h);
button->widget.rect.w = text_w + theme.border_width * 2 + theme.pad * 2;
@@ -218,7 +221,7 @@ ltk_button_create(ltk_window *window, const char *id, const char *text) {
static void
ltk_button_destroy(ltk_button *button, int shallow) {
if (!button) {
- (void)printf("WARNING: Tried to destroy NULL button.\n");
+ ltk_warn("Tried to destroy NULL button.\n");
return;
}
ltk_text_line_destroy(button->tl);
@@ -228,35 +231,44 @@ ltk_button_destroy(ltk_button *button, int shallow) {
}
/* button <button id> create <text> */
-static void
+static int
ltk_button_cmd_create(
ltk_window *window,
char **tokens,
- size_t num_tokens) {
+ size_t num_tokens,
+ char **errstr) {
ltk_button *button;
if (num_tokens != 4) {
- (void)fprintf(stderr, "button create: Invalid number of arguments.\n");
- return;
+ *errstr = "Invalid number of arguments.\n";
+ return 1;
+ }
+ if (!ltk_widget_id_free(window, tokens[1])) {
+ *errstr = "Widget ID already taken.\n";
+ return 1;
}
- if (!ltk_check_widget_id_free(window, tokens[1], "button create"))
- return;
button = ltk_button_create(window, tokens[1], tokens[3]);
ltk_set_widget(window, button, tokens[1]);
+
+ return 0;
}
/* button <button id> <command> ... */
-void
+int
ltk_button_cmd(
ltk_window *window,
char **tokens,
- size_t num_tokens) {
+ size_t num_tokens,
+ char **errstr) {
if (num_tokens < 3) {
- (void)fprintf(stderr, "button: Invalid number of arguments.\n");
- return;
+ *errstr = "Invalid number of arguments.\n";
+ return 1;
}
if (strcmp(tokens[2], "create") == 0) {
- ltk_button_cmd_create(window, tokens, num_tokens);
+ return ltk_button_cmd_create(window, tokens, num_tokens, errstr);
} else {
- (void)fprintf(stderr, "button: Invalid command.\n");
+ *errstr = "Invalid command.\n";
+ return 1;
}
+
+ return 0;
}
diff --git a/button.h b/button.h
@@ -35,9 +35,10 @@ typedef struct {
void ltk_button_setup_theme_defaults(ltk_window *window);
void ltk_button_ini_handler(ltk_window *window, const char *prop, const char *value);
-void ltk_button_cmd(
+int ltk_button_cmd(
ltk_window *window,
char **tokens,
- size_t num_tokens);
+ size_t num_tokens,
+ char **errstr);
#endif /* _LTK_BUTTON_H_ */
diff --git a/color.c b/color.c
@@ -7,7 +7,8 @@
void
ltk_color_create(Display *dpy, int screen, Colormap cm, const char *hex, LtkColor *col) {
if (!XParseColor(dpy, cm, hex, &col->xcolor)) {
- /* FIXME: better error reporting */
+ /* FIXME: better error reporting!!! */
+ /* FIXME: remove obsolete ltk_err function */
ltk_err("ltk_color_create");
}
XAllocColor(dpy, cm, &col->xcolor);
diff --git a/draw.c b/draw.c
@@ -40,26 +40,31 @@ static void ltk_draw_clear(ltk_window *window, ltk_draw *draw);
static void ltk_draw_set_color(ltk_window *window, ltk_draw *draw, const char *color);
static void ltk_draw_line(ltk_window *window, ltk_draw *draw, int x1, int y1, int x2, int y2);
static void ltk_draw_rect(ltk_window *window, ltk_draw *draw, int x, int y, int w, int h, int fill);
-static void ltk_draw_cmd_clear(
+static int ltk_draw_cmd_clear(
ltk_window *window,
char **tokens,
- size_t num_tokens);
-static void ltk_draw_cmd_set_color(
+ size_t num_tokens,
+ char **errstr);
+static int ltk_draw_cmd_set_color(
ltk_window *window,
char **tokens,
- size_t num_tokens);
-static void ltk_draw_cmd_line(
+ size_t num_tokens,
+ char **errstr);
+static int ltk_draw_cmd_line(
ltk_window *window,
char **tokens,
- size_t num_tokens);
-static void ltk_draw_cmd_rect(
+ size_t num_tokens,
+ char **errstr);
+static int ltk_draw_cmd_rect(
ltk_window *window,
char **tokens,
- size_t num_tokens);
-static void ltk_draw_cmd_create(
+ size_t num_tokens,
+ char **errstr);
+static int ltk_draw_cmd_create(
ltk_window *window,
char **tokens,
- size_t num_tokens);
+ size_t num_tokens,
+ char **errstr);
static void
ltk_draw_draw(ltk_draw *draw) {
@@ -73,7 +78,7 @@ static ltk_draw *
ltk_draw_create(ltk_window *window, const char *id, int w, int h, const char *color) {
XWindowAttributes attrs;
ltk_draw *draw = malloc(sizeof(ltk_draw));
- if (!draw) ltk_fatal("ERROR: Unable to allocate memory for ltk_draw.\n");
+ if (!draw) ltk_fatal_errno("Unable to allocate memory for ltk_draw.\n");
ltk_fill_widget_defaults(&draw->widget, id, window,
<k_draw_draw, NULL, <k_draw_destroy, 1, LTK_DRAW);
@@ -85,7 +90,7 @@ ltk_draw_create(ltk_window *window, const char *id, int w, int h, const char *co
draw->pix = XCreatePixmap(window->dpy, window->xwindow, w, h, draw->depth);
if (!ltk_create_xcolor(window, color, &draw->bg)) {
free(draw);
- return NULL;
+ ltk_fatal_errno("Unable to allocate XColor.\n");
}
draw->fg = draw->bg;
XSetForeground(window->dpy, window->gc, draw->bg.pixel);
@@ -120,7 +125,7 @@ ltk_draw_resize(ltk_draw *draw, int orig_w, int orig_h) {
static void
ltk_draw_destroy(ltk_draw *draw, int shallow) {
if (!draw) {
- (void)printf("WARNING: Tried to destroy NULL draw.\n");
+ ltk_warn("Tried to destroy NULL draw.\n");
return;
}
ltk_remove_widget(draw->widget.window, draw->widget.id);
@@ -139,6 +144,7 @@ ltk_draw_clear(ltk_window *window, ltk_draw *draw) {
ltk_draw_draw(draw);
}
+/* FIXME: Error return */
static void
ltk_draw_set_color(ltk_window *window, ltk_draw *draw, const char *color) {
XColor tmp;
@@ -183,166 +189,186 @@ ltk_draw_rect(ltk_window *window, ltk_draw *draw, int x, int y, int w, int h, in
}
}
-static void
+static int
ltk_draw_cmd_clear(
ltk_window *window,
char **tokens,
- size_t num_tokens) {
+ size_t num_tokens,
+ char **errstr) {
ltk_draw *draw;
if (num_tokens != 3) {
- (void)fprintf(stderr, "draw clear: Invalid number of arguments.\n");
- return;
+ *errstr = "Invalid number of arguments.\n";
+ return 1;
}
- draw = ltk_get_widget(window, tokens[1], LTK_DRAW, "draw clear");
- if (!draw) return;
+ draw = ltk_get_widget(window, tokens[1], LTK_DRAW, errstr);
+ if (!draw) return 1;
ltk_draw_clear(window, draw);
+
+ return 0;
}
-static void
+static int
ltk_draw_cmd_set_color(
ltk_window *window,
char **tokens,
- size_t num_tokens) {
+ size_t num_tokens,
+ char **errstr) {
ltk_draw *draw;
if (num_tokens != 4) {
- (void)fprintf(stderr, "draw set-color: Invalid number of arguments.\n");
- return;
+ *errstr = "Invalid number of arguments.\n";
+ return 1;
}
- draw = ltk_get_widget(window, tokens[1], LTK_DRAW, "draw set-color");
- if (!draw) return;
+ draw = ltk_get_widget(window, tokens[1], LTK_DRAW, errstr);
+ if (!draw) return 1;
ltk_draw_set_color(window, draw, tokens[3]);
+
+ return 0;
}
-static void
+static int
ltk_draw_cmd_line(
ltk_window *window,
char **tokens,
- size_t num_tokens) {
+ size_t num_tokens,
+ char **errstr) {
ltk_draw *draw;
int x1, y1, x2, y2;
- const char *errstr;
+ const char *errstr_num;
if (num_tokens != 7) {
- (void)fprintf(stderr, "draw line: Invalid number of arguments.\n");
- return;
+ *errstr = "Invalid number of arguments.\n";
+ return 1;
}
- draw = ltk_get_widget(window, tokens[1], LTK_DRAW, "draw line");
- if (!draw) return;
- x1 = strtonum(tokens[3], 0, 100000, &errstr);
- if (errstr) {
- (void)fprintf(stderr, "draw line: Invalid x1: %s\n", errstr);
- return;
+ draw = ltk_get_widget(window, tokens[1], LTK_DRAW, errstr);
+ if (!draw) return 1;
+ x1 = strtonum(tokens[3], 0, 100000, &errstr_num);
+ if (errstr_num) {
+ *errstr = "Invalid x1.\n";
+ return 1;
}
- y1 = strtonum(tokens[4], 0, 100000, &errstr);
- if (errstr) {
- (void)fprintf(stderr, "draw line: Invalid y1: %s\n", errstr);
- return;
+ y1 = strtonum(tokens[4], 0, 100000, &errstr_num);
+ if (errstr_num) {
+ *errstr = "Invalid y1.\n";
+ return 1;
}
- x2 = strtonum(tokens[5], 0, 100000, &errstr);
- if (errstr) {
- (void)fprintf(stderr, "draw line: Invalid x2: %s\n", errstr);
- return;
+ x2 = strtonum(tokens[5], 0, 100000, &errstr_num);
+ if (errstr_num) {
+ *errstr = "Invalid x2.\n";
+ return 1;
}
- y2 = strtonum(tokens[6], 0, 100000, &errstr);
- if (errstr) {
- (void)fprintf(stderr, "draw line: Invalid y2: %s\n", errstr);
- return;
+ y2 = strtonum(tokens[6], 0, 100000, &errstr_num);
+ if (errstr_num) {
+ *errstr = "Invalid y2.\n";
+ return 1;
}
ltk_draw_line(window, draw, x1, y1, x2, y2);
+
+ return 0;
}
-static void
+static int
ltk_draw_cmd_rect(
ltk_window *window,
char **tokens,
- size_t num_tokens) {
+ size_t num_tokens,
+ char **errstr) {
ltk_draw *draw;
- const char *errstr;
+ const char *errstr_num;
int x, y, w, h, fill;
if (num_tokens != 8) {
- (void)fprintf(stderr, "draw clear: Invalid number of arguments.\n");
- return;
+ *errstr = "Invalid number of arguments.\n";
+ return 1;
}
- draw = ltk_get_widget(window, tokens[1], LTK_DRAW, "draw clear");
- if (!draw) return;
- x = strtonum(tokens[3], 0, 100000, &errstr);
- if (errstr) {
- (void)fprintf(stderr, "draw rect: Invalid x: %s\n", errstr);
- return;
+ draw = ltk_get_widget(window, tokens[1], LTK_DRAW, errstr);
+ if (!draw) return 1;
+ x = strtonum(tokens[3], 0, 100000, &errstr_num);
+ if (errstr_num) {
+ *errstr = "Invalid x.\n";
+ return 1;
}
- y = strtonum(tokens[4], 0, 100000, &errstr);
- if (errstr) {
- (void)fprintf(stderr, "draw rect: Invalid y: %s\n", errstr);
- return;
+ y = strtonum(tokens[4], 0, 100000, &errstr_num);
+ if (errstr_num) {
+ *errstr = "Invalid y.\n";
+ return 1;
}
- w = strtonum(tokens[5], 1, 100000, &errstr);
- if (errstr) {
- (void)fprintf(stderr, "draw rect: Invalid width: %s\n", errstr);
- return;
+ w = strtonum(tokens[5], 1, 100000, &errstr_num);
+ if (errstr_num) {
+ *errstr = "Invalid width.\n";
+ return 1;
}
- h = strtonum(tokens[6], 1, 100000, &errstr);
- if (errstr) {
- (void)fprintf(stderr, "draw rect: Invalid height: %s\n", errstr);
- return;
+ h = strtonum(tokens[6], 1, 100000, &errstr_num);
+ if (errstr_num) {
+ *errstr = "Invalid height.\n";
+ return 1;
}
- fill = strtonum(tokens[7], 0, 1, &errstr);
- if (errstr) {
- (void)fprintf(stderr, "draw rect: Invalid fill bool: %s\n", errstr);
- return;
+ fill = strtonum(tokens[7], 0, 1, &errstr_num);
+ if (errstr_num) {
+ *errstr = "Invalid fill bool.\n";
+ return 1;
}
ltk_draw_rect(window, draw, x, y, w, h, fill);
+
+ return 0;
}
/* draw <draw id> create <width> <height> <color> */
-static void
+static int
ltk_draw_cmd_create(
ltk_window *window,
char **tokens,
- size_t num_tokens) {
+ size_t num_tokens,
+ char **errstr) {
ltk_draw *draw;
int w, h;
- const char *errstr;
+ const char *errstr_num;
if (num_tokens != 6) {
- (void)fprintf(stderr, "draw create: Invalid number of arguments.\n");
- return;
+ *errstr = "Invalid number of arguments.\n";
+ return 1;
}
- if (!ltk_check_widget_id_free(window, tokens[1], "draw create"))
- return;
- w = strtonum(tokens[3], 1, 100000, &errstr);
- if (errstr) {
- (void)fprintf(stderr, "draw create: Invalid width: %s\n", errstr);
- return;
+ if (!ltk_widget_id_free(window, tokens[1])) {
+ *errstr = "Widget ID already taken.\n";
+ return 1;
}
- h = strtonum(tokens[4], 1, 100000, &errstr);
- if (errstr) {
- (void)fprintf(stderr, "draw create: Invalid height: %s\n", errstr);
- return;
+ w = strtonum(tokens[3], 1, 100000, &errstr_num);
+ if (errstr_num) {
+ *errstr = "Invalid width.\n";
+ return 1;
+ }
+ h = strtonum(tokens[4], 1, 100000, &errstr_num);
+ if (errstr_num) {
+ *errstr = "Invalid height.\n";
+ return 1;
}
draw = ltk_draw_create(window, tokens[1], w, h, tokens[5]);
- if (draw)
- ltk_set_widget(window, draw, tokens[1]);
+ ltk_set_widget(window, draw, tokens[1]);
+
+ return 0;
}
/* draw <draw id> <command> ... */
-void
+int
ltk_draw_cmd(
ltk_window *window,
char **tokens,
- size_t num_tokens) {
+ size_t num_tokens,
+ char **errstr) {
if (num_tokens < 3) {
- (void)fprintf(stderr, "draw: Invalid number of arguments.\n");
- return;
+ *errstr = "Invalid number of arguments.\n";
+ return 1;
}
if (strcmp(tokens[2], "create") == 0) {
- ltk_draw_cmd_create(window, tokens, num_tokens);
+ return ltk_draw_cmd_create(window, tokens, num_tokens, errstr);
} else if (strcmp(tokens[2], "clear") == 0) {
- ltk_draw_cmd_clear(window, tokens, num_tokens);
+ return ltk_draw_cmd_clear(window, tokens, num_tokens, errstr);
} else if (strcmp(tokens[2], "set-color") == 0) {
- ltk_draw_cmd_set_color(window, tokens, num_tokens);
+ return ltk_draw_cmd_set_color(window, tokens, num_tokens, errstr);
} else if (strcmp(tokens[2], "line") == 0) {
- ltk_draw_cmd_line(window, tokens, num_tokens);
+ return ltk_draw_cmd_line(window, tokens, num_tokens, errstr);
} else if (strcmp(tokens[2], "rect") == 0) {
- ltk_draw_cmd_rect(window, tokens, num_tokens);
+ return ltk_draw_cmd_rect(window, tokens, num_tokens, errstr);
} else {
- (void)fprintf(stderr, "draw: Invalid command.\n");
+ *errstr = "Invalid command.\n";
+ return 1;
}
+
+ return 0;
}
diff --git a/draw.h b/draw.h
@@ -34,9 +34,10 @@ typedef struct {
XColor bg;
} ltk_draw;
-void ltk_draw_cmd(
+int ltk_draw_cmd(
ltk_window *window,
char **tokens,
- size_t num_tokens);
+ size_t num_tokens,
+ char **errstr);
#endif /* _LTK_DRAW_H_ */
diff --git a/grid.c b/grid.c
@@ -41,35 +41,40 @@ static ltk_grid *ltk_grid_create(ltk_window *window, const char *id,
int rows, int columns);
static void ltk_grid_destroy(ltk_grid *grid, int shallow);
static void ltk_recalculate_grid(ltk_grid *grid);
-static void ltk_grid_add(ltk_window *window, ltk_widget *widget, ltk_grid *grid,
- int row, int column, int row_span, int column_span, unsigned short sticky);
-static void ltk_grid_ungrid(ltk_window *window, ltk_widget *widget, ltk_grid *grid);
+static int ltk_grid_add(ltk_window *window, ltk_widget *widget, ltk_grid *grid,
+ int row, int column, int row_span, int column_span, unsigned short sticky, char **errstr);
+static int ltk_grid_ungrid(ltk_window *window, ltk_widget *widget, ltk_grid *grid, char **errstr);
static int ltk_grid_find_nearest_column(ltk_grid *grid, int x);
static int ltk_grid_find_nearest_row(ltk_grid *grid, int y);
static void ltk_grid_mouse_press(ltk_grid *grid, XEvent event);
static void ltk_grid_mouse_release(ltk_grid *grid, XEvent event);
static void ltk_grid_motion_notify(ltk_grid *grid, XEvent event);
-static void ltk_grid_cmd_add(
+static int ltk_grid_cmd_add(
ltk_window *window,
char **tokens,
- size_t num_tokens);
-static void ltk_grid_cmd_ungrid(
+ size_t num_tokens,
+ char **errstr);
+static int ltk_grid_cmd_ungrid(
ltk_window *window,
char **tokens,
- size_t num_tokens);
-static void ltk_grid_cmd_create(
+ size_t num_tokens,
+ char **errstr);
+static int ltk_grid_cmd_create(
ltk_window *window,
char **tokens,
- size_t num_tokens);
-static void ltk_grid_cmd_set_row_weight(
+ size_t num_tokens,
+ char **errstr);
+static int ltk_grid_cmd_set_row_weight(
ltk_window *window,
char **tokens,
- size_t num_tokens);
-static void ltk_grid_cmd_set_column_weight(
+ size_t num_tokens,
+ char **errstr);
+static int ltk_grid_cmd_set_column_weight(
ltk_window *window,
char **tokens,
- size_t num_tokens);
+ size_t num_tokens,
+ char **errstr);
static void
ltk_grid_set_row_weight(ltk_grid *grid, int row, int weight) {
@@ -251,12 +256,12 @@ ltk_recalculate_grid(ltk_grid *grid) {
}
}
-static void
+static int
ltk_grid_add(ltk_window *window, ltk_widget *widget, ltk_grid *grid,
- int row, int column, int row_span, int column_span, unsigned short sticky) {
+ int row, int column, int row_span, int column_span, unsigned short sticky, char **errstr) {
if (row + row_span > grid->rows || column + column_span > grid->columns) {
- (void)fprintf(stderr, "Invalid row or column.\n");
- return;
+ *errstr = "Invalid row or column.\n";
+ return 1;
}
widget->sticky = sticky;
widget->row = row;
@@ -277,13 +282,15 @@ ltk_grid_add(ltk_window *window, ltk_widget *widget, ltk_grid *grid,
widget->parent = grid;
ltk_recalculate_grid(grid);
ltk_window_invalidate_rect(window, grid->widget.rect);
+
+ return 0;
}
-static void
-ltk_grid_ungrid(ltk_window *window, ltk_widget *widget, ltk_grid *grid) {
+static int
+ltk_grid_ungrid(ltk_window *window, ltk_widget *widget, ltk_grid *grid, char **errstr) {
if (widget->parent != grid) {
- (void)fprintf(stderr, "grid remove: Widget isn't gridded in given grid.\n");
- return;
+ *errstr = "Widget isn't gridded in given grid.\n";
+ return 1;
}
widget->parent = NULL;
for (int i = widget->row; i < widget->row + widget->row_span; i++) {
@@ -292,6 +299,8 @@ ltk_grid_ungrid(ltk_window *window, ltk_widget *widget, ltk_grid *grid) {
}
}
ltk_window_invalidate_rect(window, grid->widget.rect);
+
+ return 0;
}
static int
@@ -359,175 +368,192 @@ ltk_grid_motion_notify(ltk_grid *grid, XEvent event) {
}
/* grid <grid id> add <widget id> <row> <column> <row_span> <column_span> <sticky> */
-static void
+static int
ltk_grid_cmd_add(
ltk_window *window,
char **tokens,
- size_t num_tokens) {
+ size_t num_tokens,
+ char **errstr) {
ltk_grid *grid;
ltk_widget *widget;
- const char *errstr;
+ const char *errstr_num;
int row, column, row_span, column_span, sticky;
if (num_tokens != 9) {
- (void)fprintf(stderr, "grid: Invalid number of arguments.\n");
- return;
- }
- grid = ltk_get_widget(window, tokens[1], LTK_GRID, "grid add");
- widget = ltk_get_widget(window, tokens[3], LTK_WIDGET, "grid add");
- if (!grid || !widget) return;
- row = strtonum(tokens[4], 0, grid->rows - 1, &errstr);
- if (errstr) {
- (void)fprintf(stderr, "grid add: Invalid row number: %s\n", errstr);
- return;
- }
- column = strtonum(tokens[5], 0, grid->columns - 1, &errstr);
- if (errstr) {
- (void)fprintf(stderr, "grid add: Invalid column number: %s\n", errstr);
- return;
- }
- row_span = strtonum(tokens[6], 1, grid->rows, &errstr);
- if (errstr) {
- (void)fprintf(stderr, "grid add: Invalid row_span: %s\n", errstr);
- return;
- }
- column_span = strtonum(tokens[7], 1, grid->columns, &errstr);
- if (errstr) {
- (void)fprintf(stderr, "grid add: Invalid column_span: %s\n", errstr);
- return;
- }
- sticky = strtonum(tokens[8], 0, 15, &errstr);
- if (errstr) {
- (void)fprintf(stderr, "grid add: Invalid sticky setting: %s\n", errstr);
- return;
- }
- ltk_grid_add(window, widget, grid, row, column, row_span, column_span, sticky);
+ *errstr = "Invalid number of arguments.\n";
+ return 1;
+ }
+ grid = ltk_get_widget(window, tokens[1], LTK_GRID, errstr);
+ widget = ltk_get_widget(window, tokens[3], LTK_WIDGET, errstr);
+ if (!grid || !widget) return 1;
+ row = strtonum(tokens[4], 0, grid->rows - 1, &errstr_num);
+ if (errstr_num) {
+ *errstr = "Invalid row number.\n";
+ return 1;
+ }
+ column = strtonum(tokens[5], 0, grid->columns - 1, &errstr_num);
+ if (errstr_num) {
+ *errstr = "Invalid row number.\n";
+ return 1;
+ }
+ row_span = strtonum(tokens[6], 1, grid->rows, &errstr_num);
+ if (errstr_num) {
+ *errstr = "Invalid row span.\n";
+ return 1;
+ }
+ column_span = strtonum(tokens[7], 1, grid->columns, &errstr_num);
+ if (errstr_num) {
+ *errstr = "Invalid column span.\n";
+ return 1;
+ }
+ sticky = strtonum(tokens[8], 0, 15, &errstr_num);
+ if (errstr_num) {
+ *errstr = "Invalid sticky setting.\n";
+ return 1;
+ }
+ return ltk_grid_add(window, widget, grid, row, column, row_span, column_span, sticky, errstr);
}
/* grid <grid id> remove <widget id> */
-static void
+static int
ltk_grid_cmd_ungrid(
ltk_window *window,
char **tokens,
- size_t num_tokens) {
+ size_t num_tokens,
+ char **errstr) {
ltk_grid *grid;
ltk_widget *widget;
if (num_tokens != 4) {
- (void)fprintf(stderr, "grid ungrid: Invalid number of arguments.\n");
- return;
+ *errstr = "Invalid number of arguments.\n";
+ return 1;
}
- grid = ltk_get_widget(window, tokens[1], LTK_GRID, "grid remove");
- widget = ltk_get_widget(window, tokens[3], LTK_WIDGET, "grid ungrid");
- if (!grid || !widget) return;
- ltk_grid_ungrid(window, widget, grid);
+ grid = ltk_get_widget(window, tokens[1], LTK_GRID, errstr);
+ widget = ltk_get_widget(window, tokens[3], LTK_WIDGET, errstr);
+ if (!grid || !widget) return 1;
+ return ltk_grid_ungrid(window, widget, grid, errstr);
}
/* grid <grid id> create <rows> <columns> */
-static void
+static int
ltk_grid_cmd_create(
ltk_window *window,
char **tokens,
- size_t num_tokens) {
+ size_t num_tokens,
+ char **errstr) {
int rows, columns;
ltk_grid *grid;
- const char *errstr;
+ const char *errstr_num;
if (num_tokens != 5) {
- (void)fprintf(stderr, "grid create: Invalid number of arguments.\n");
- return;
+ *errstr = "Invalid number of arguments.\n";
+ return 1;
}
- if (!ltk_check_widget_id_free(window, tokens[1], "grid create"))
- return;
- rows = strtonum(tokens[3], 1, 64, &errstr);
- if (errstr) {
- (void)fprintf(stderr, "grid create: Invalid number of rows: %s\n ", errstr);
- return;
+ if (!ltk_widget_id_free(window, tokens[1])) {
+ *errstr = "Widget ID already taken.\n";
+ return 1;
}
- columns = strtonum(tokens[4], 1, 64, &errstr);
- if (errstr) {
- (void)fprintf(stderr, "grid create: Invalid number of columns: %s\n ", errstr);
- return;
+ rows = strtonum(tokens[3], 1, 64, &errstr_num);
+ if (errstr_num) {
+ *errstr = "Invalid number of rows.\n";
+ return 1;
+ }
+ columns = strtonum(tokens[4], 1, 64, &errstr_num);
+ if (errstr_num) {
+ *errstr = "Invalid number of columns.\n";
+ return 1;
}
grid = ltk_grid_create(window, tokens[1], rows, columns);
ltk_set_widget(window, grid, tokens[1]);
+
+ return 0;
}
/* grid <grid id> set-row-weight <row> <weight> */
-static void
+static int
ltk_grid_cmd_set_row_weight(
ltk_window *window,
char **tokens,
- size_t num_tokens) {
+ size_t num_tokens,
+ char **errstr) {
ltk_grid *grid;
int row, weight;
- const char *errstr;
+ const char *errstr_num;
if (num_tokens != 5) {
- (void)fprintf(stderr, "grid set-row-weight: Invalid number of arguments.\n");
- return;
+ *errstr = "Invalid number of arguments.\n";
+ return 1;
}
- grid = ltk_get_widget(window, tokens[1], LTK_GRID, "grid set-row-weight");
- if (!grid) return;
- row = strtonum(tokens[3], 0, grid->rows, &errstr);
- if (errstr) {
- (void)fprintf(stderr, "grid set-row-weight: Invalid row number: %s\n ", errstr);
- return;
+ grid = ltk_get_widget(window, tokens[1], LTK_GRID, errstr);
+ if (!grid) return 1;
+ row = strtonum(tokens[3], 0, grid->rows, &errstr_num);
+ if (errstr_num) {
+ *errstr = "Invalid row number.\n";
+ return 1;
}
- weight = strtonum(tokens[4], 0, 64, &errstr);
- if (errstr) {
- (void)fprintf(stderr, "grid set-row-weight: Invalid weight: %s\n ", errstr);
- return;
+ weight = strtonum(tokens[4], 0, 64, &errstr_num);
+ if (errstr_num) {
+ *errstr = "Invalid row weight.\n";
+ return 1;
}
ltk_grid_set_row_weight(grid, row, weight);
+
+ return 0;
}
/* grid <grid id> set-column-weight <column> <weight> */
-static void
+static int
ltk_grid_cmd_set_column_weight(
ltk_window *window,
char **tokens,
- size_t num_tokens) {
+ size_t num_tokens,
+ char **errstr) {
ltk_grid *grid;
int column, weight;
- const char *errstr;
+ const char *errstr_num;
if (num_tokens != 5) {
- (void)fprintf(stderr, "grid set-column-weight: Invalid number of arguments.\n");
- return;
+ *errstr = "Invalid number of arguments.\n";
+ return 1;
}
- grid = ltk_get_widget(window, tokens[1], LTK_GRID, "grid set-column-weight");
- if (!grid) return;
- column = strtonum(tokens[3], 0, grid->columns, &errstr);
- if (errstr) {
- (void)fprintf(stderr, "grid set-column-weight: Invalid column number: %s\n ", errstr);
- return;
+ grid = ltk_get_widget(window, tokens[1], LTK_GRID, errstr);
+ if (!grid) return 1;
+ column = strtonum(tokens[3], 0, grid->columns, &errstr_num);
+ if (errstr_num) {
+ *errstr = "Invalid column number.\n";
+ return 1;
}
- weight = strtonum(tokens[4], 0, 64, &errstr);
- if (errstr) {
- (void)fprintf(stderr, "grid set-column-weight: Invalid weight: %s\n ", errstr);
- return;
+ weight = strtonum(tokens[4], 0, 64, &errstr_num);
+ if (errstr_num) {
+ *errstr = "Invalid column weight.\n";
+ return 1;
}
ltk_grid_set_column_weight(grid, column, weight);
+
+ return 0;
}
/* grid <grid id> <command> ... */
-void
+int
ltk_grid_cmd(
ltk_window *window,
char **tokens,
- size_t num_tokens) {
+ size_t num_tokens,
+ char **errstr) {
if (num_tokens < 3) {
- (void)fprintf(stderr, "grid: Invalid number of arguments.\n");
- return;
+ *errstr = "Invalid number of arguments.\n";
+ return 1;
}
if (strcmp(tokens[2], "add") == 0) {
- ltk_grid_cmd_add(window, tokens, num_tokens);
+ return ltk_grid_cmd_add(window, tokens, num_tokens, errstr);
} else if (strcmp(tokens[2], "ungrid") == 0) {
- ltk_grid_cmd_ungrid(window, tokens, num_tokens);
+ return ltk_grid_cmd_ungrid(window, tokens, num_tokens, errstr);
} else if (strcmp(tokens[2], "create") == 0) {
- ltk_grid_cmd_create(window, tokens, num_tokens);
+ return ltk_grid_cmd_create(window, tokens, num_tokens, errstr);
} else if (strcmp(tokens[2], "set-row-weight") == 0) {
- ltk_grid_cmd_set_row_weight(window, tokens, num_tokens);
+ return ltk_grid_cmd_set_row_weight(window, tokens, num_tokens, errstr);
} else if (strcmp(tokens[2], "set-column-weight") == 0) {
- ltk_grid_cmd_set_column_weight(window, tokens, num_tokens);
+ return ltk_grid_cmd_set_column_weight(window, tokens, num_tokens, errstr);
} else {
- (void)fprintf(stderr, "button: Invalid command.\n");
+ *errstr = "Invalid command.\n";
+ return 1;
}
+
+ return 0; /* Well, I guess this is impossible anyways... */
}
diff --git a/grid.h b/grid.h
@@ -42,6 +42,6 @@ typedef struct {
unsigned int *column_pos;
} ltk_grid;
-void ltk_grid_cmd(ltk_window *window, char **tokens, size_t num_tokens);
+int ltk_grid_cmd(ltk_window *window, char **tokens, size_t num_tokens, char **errstr);
#endif
diff --git a/ltk.h b/ltk.h
@@ -137,6 +137,8 @@ typedef struct ltk_window {
void ltk_window_invalidate_rect(ltk_window *window, ltk_rect rect);
void ltk_warn(const char *format, ...);
void ltk_fatal(const char *format, ...);
+void ltk_warn_errno(const char *format, ...);
+void ltk_fatal_errno(const char *format, ...);
int ltk_create_xcolor(ltk_window *window, const char *hex, XColor *col);
void ltk_queue_event(ltk_window *window, ltk_event_type type, const char *id, const char *data);
int ltk_collide_rect(ltk_rect rect, int x, int y);
@@ -149,10 +151,9 @@ void ltk_fill_widget_defaults(ltk_widget *widget, const char *id, ltk_window * w
void ltk_widget_mouse_press_event(ltk_widget *widget, XEvent event);
void ltk_widget_mouse_release_event(ltk_widget *widget, XEvent event);
void ltk_widget_motion_notify_event(ltk_widget *widget, XEvent event);
-int ltk_check_widget_id_free(ltk_window *window, const char *id,
- const char *caller);
+int ltk_check_widget_id_free(ltk_window *window, const char *id);
ltk_widget *ltk_get_widget(ltk_window *window, const char *id,
- ltk_widget_type type, const char *caller);
+ ltk_widget_type type, char **errstr);
void ltk_set_widget(ltk_window *window, ltk_widget *widget, const char *id);
#endif
diff --git a/ltkd.c b/ltkd.c
@@ -94,7 +94,7 @@ static int read_sock(struct ltk_sock_info *sock);
static int write_sock(struct ltk_sock_info *sock);
static int queue_sock_write(struct ltk_sock_info *sock, const char *str, int len);
static int tokenize_command(struct ltk_sock_info *sock);
-static void ltk_set_root_widget_cmd(ltk_window *window, char **tokens, int num_tokens);
+static int ltk_set_root_widget_cmd(ltk_window *window, char **tokens, int num_tokens, char **errstr);
static void process_commands(ltk_window *window, struct ltk_sock_info *sock);
static ltk_rect ltk_rect_union(ltk_rect r1, ltk_rect r2);
static int add_client(int fd);
@@ -126,16 +126,16 @@ int main(int argc, char *argv[]) {
}
ltk_dir = ltk_setup_directory();
- if (!ltk_dir) ltk_fatal("Unable to setup ltk directory.\n");
+ if (!ltk_dir) ltk_fatal_errno("Unable to setup ltk directory.\n");
ltk_logfile = open_log(ltk_dir);
- if (!ltk_logfile) ltk_fatal("Unable to open log file.\n");
+ if (!ltk_logfile) ltk_fatal_errno("Unable to open log file.\n");
/* FIXME: set window size properly - I only run it in a tiling WM
anyways, so it doesn't matter, but still... */
main_window = ltk_create_window(title, 0, 0, 500, 500);
sock_path = get_sock_path(ltk_dir, main_window->xwindow);
- if (!sock_path) ltk_fatal("Unable to allocate memory for socket path.\n");
+ if (!sock_path) ltk_fatal_errno("Unable to allocate memory for socket path.\n");
/* Note: sockets should be initialized to 0 because it is static */
for (int i = 0; i < MAX_SOCK_CONNS; i++) {
@@ -164,7 +164,7 @@ ltk_mainloop(ltk_window *window) {
FD_ZERO(&wallfds);
if ((listenfd = listen_sock(sock_path)) < 0)
- ltk_fatal("Error listening on socket.\n");
+ ltk_fatal_errno("Error listening on socket.\n");
FD_SET(listenfd, &rallfds);
maxfd = listenfd;
@@ -191,7 +191,7 @@ ltk_mainloop(ltk_window *window) {
if (FD_ISSET(listenfd, &rfds)) {
if ((clifd = accept_sock(listenfd)) < 0) {
/* FIXME: Just log this! */
- ltk_fatal("Error accepting socket connection.\n");
+ ltk_fatal_errno("Error accepting socket connection.\n");
}
int i = add_client(clifd);
FD_SET(clifd, &rallfds);
@@ -207,7 +207,6 @@ ltk_mainloop(ltk_window *window) {
continue;
if (FD_ISSET(clifd, &rfds)) {
if (read_sock(&sockets[i]) == 0) {
- fprintf(stderr, "Closed socket fd %d\n", clifd); /* FIXME */
FD_CLR(clifd, &rallfds);
FD_CLR(clifd, &wallfds);
sockets[i].fd = -1;
@@ -236,7 +235,7 @@ ltk_mainloop(ltk_window *window) {
for (int i = 0; i <= maxsocket; i++) {
if (sockets[i].fd != -1 && sockets[i].event_mask & cur->event_type) {
if (queue_sock_write(&sockets[i], cur->data, event_len) < 0)
- ltk_fatal("Unable to queue event.\n");
+ ltk_fatal_errno("Unable to queue event.\n");
}
}
free(cur->data);
@@ -267,7 +266,7 @@ daemonize(void) {
fflush(ltk_logfile);
if ((pid = fork()) < 0)
- ltk_fatal("Can't fork.\n");
+ ltk_fatal_errno("Can't fork.\n");
else if (pid != 0)
exit(0);
setsid();
@@ -276,14 +275,14 @@ daemonize(void) {
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGHUP, &sa, NULL) < 0)
- ltk_fatal("Unable to ignore SIGHUP.\n");
+ ltk_fatal_errno("Unable to ignore SIGHUP.\n");
if ((pid = fork()) < 0)
- ltk_fatal("Can't fork.\n");
+ ltk_fatal_errno("Can't fork.\n");
else if (pid != 0)
exit(0);
if (chdir("/") < 0)
- ltk_fatal("Can't change directory to root.\n");
+ ltk_fatal_errno("Can't change directory to root.\n");
close(fileno(stdin));
close(fileno(stdout));
@@ -322,6 +321,10 @@ open_log(char *dir) {
if (!path)
return NULL;
f = fopen(path, "a");
+ if (!f) {
+ free(path);
+ return NULL;
+ }
free(path);
return f;
@@ -362,26 +365,28 @@ ltk_quit(ltk_window *window) {
running = 0;
}
-static void
+static int
ltk_set_root_widget_cmd(
ltk_window *window,
char **tokens,
- int num_tokens) {
+ int num_tokens,
+ char **errstr) {
ltk_widget *widget;
if (num_tokens != 2) {
- (void)fprintf(stderr, "set-root-widget: Invalid number of arguments.\n");
- return;
+ *errstr = "Invalid number of arguments.\n";
+ return 1;
}
- widget = ltk_get_widget(window, tokens[1], LTK_WIDGET, "set-root-widget");
- if (!widget) return;
+ widget = ltk_get_widget(window, tokens[1], LTK_WIDGET, errstr);
+ if (!widget) return 1;
window->root_widget = widget;
int w = widget->rect.w;
int h = widget->rect.h;
widget->rect.w = window->rect.w;
widget->rect.h = window->rect.h;
- if (widget->resize) {
+ if (widget->resize)
widget->resize(widget, w, h);
- }
+
+ return 0;
}
static ltk_rect
@@ -446,12 +451,31 @@ ltk_fatal(const char *format, ...) {
exit(1);
};
+void
+ltk_warn_errno(const char *format, ...) {
+ va_list args;
+ char *errstr = strerror(errno);
+ va_start(args, format);
+ print_log("Warning", format, args);
+ va_end(args);
+ ltk_warn("system error: %s\n", errstr);
+}
+
+void
+ltk_fatal_errno(const char *format, ...) {
+ va_list args;
+ char *errstr = strerror(errno);
+ va_start(args, format);
+ print_log("Fatal", format, args);
+ va_end(args);
+ ltk_fatal("system error: %s\n", errstr);
+}
+
+/* FIXME: Proper error checking by calling functions */
int
ltk_create_xcolor(ltk_window *window, const char *hex, XColor *col) {
- if (!XParseColor(window->dpy, window->cm, hex, col)) {
- (void)fprintf(stderr, "Invalid color: %s\n", hex);
+ if (!XParseColor(window->dpy, window->cm, hex, col))
return 0;
- }
XAllocColor(window->dpy, window->cm, col);
return 1;
@@ -461,12 +485,12 @@ void
ltk_queue_event(ltk_window *window, ltk_event_type type, const char *id, const char *data) {
/* FIXME: make it nicer and safer */
struct ltk_event_queue *new = malloc(sizeof(struct ltk_event_queue));
- if (!new) ltk_fatal("Unable to queue event.\n");
+ if (!new) ltk_fatal_errno("Unable to queue event.\n");
new->event_type = type;
int id_len = strlen(id);
int data_len = strlen(data);
new->data = malloc(id_len + data_len + 3);
- if (!new->data) ltk_fatal("Unable to queue event.\n");
+ if (!new->data) ltk_fatal_errno("Unable to queue event.\n");
strcpy(new->data, id);
new->data[id_len] = ' ';
strcpy(new->data + id_len + 1, data);
@@ -533,14 +557,15 @@ ltk_create_window(const char *title, int x, int y, unsigned int w, unsigned int
ltk_window *window = malloc(sizeof(ltk_window));
if (!window)
- ltk_fatal("Not enough memory left for window!\n");
+ ltk_fatal_errno("Not enough memory left for window!\n");
window->dpy = XOpenDisplay(NULL);
window->screen = DefaultScreen(window->dpy);
window->cm = DefaultColormap(window->dpy, window->screen);
theme_path = ltk_strcat_useful(ltk_dir, "/theme.ini");
+ window->theme.font = NULL;
if (!theme_path)
- ltk_fatal("Not enough memory for theme path.\n");
+ ltk_fatal_errno("Not enough memory for theme path.\n");
ltk_load_theme(window, theme_path);
window->wm_delete_msg = XInternAtom(window->dpy, "WM_DELETE_WINDOW", False);
@@ -595,6 +620,8 @@ ltk_destroy_window(ltk_window *window) {
kh_destroy(widget, window->widget_hash);
ltk_cleanup_text();
XCloseDisplay(window->dpy);
+ if (window->theme.font)
+ free(window->theme.font);
free(window);
}
@@ -608,6 +635,8 @@ ltk_window_ini_handler(ltk_window *window, const char *prop, const char *value)
ltk_create_xcolor(window, value, &window->theme.fg);
} else if (strcmp(prop, "font") == 0) {
window->theme.font = strdup(value);
+ if (!window->theme.font)
+ ltk_fatal_errno("Unable to allocate copy of font name.\n");
} else if (strcmp(prop, "font_size") == 0) {
window->theme.font_size = atoi(value);
}
@@ -685,6 +714,8 @@ ltk_fill_widget_defaults(ltk_widget *widget, const char *id, ltk_window *window,
void (*destroy) (void *, int), unsigned int needs_redraw,
ltk_widget_type type) {
widget->id = strdup(id);
+ if (!widget->id)
+ ltk_fatal_errno("Unable to allocate copy of widget ID.\n");
widget->window = window;
widget->active_widget = NULL;
widget->parent = NULL;
@@ -800,11 +831,10 @@ ltk_handle_event(ltk_window *window, XEvent event) {
}
int
-ltk_check_widget_id_free(ltk_window *window, const char *id, const char *caller) {
+ltk_widget_id_free(ltk_window *window, const char *id) {
khint_t k;
k = kh_get(widget, window->widget_hash, id);
if (k != kh_end(window->widget_hash)) {
- (void)fprintf(stderr, "%s: Widget \"%s\" already exists.\n", caller, id);
return 0;
}
return 1;
@@ -812,17 +842,17 @@ ltk_check_widget_id_free(ltk_window *window, const char *id, const char *caller)
ltk_widget *
ltk_get_widget(ltk_window *window, const char *id, ltk_widget_type type,
- const char *caller) {
+ char **errstr) {
khint_t k;
ltk_widget *widget;
k = kh_get(widget, window->widget_hash, id);
if (k == kh_end(window->widget_hash)) {
- (void)fprintf(stderr, "%s: Widget \"%s\" doesn't exist.\n", caller, id);
+ *errstr = "Widget with given ID doesn't exist.\n";
return NULL;
}
widget = kh_value(window->widget_hash, k);
if (type != LTK_WIDGET && widget->type != type) {
- (void)fprintf(stderr, "%s: Widget \"%s\" has wrong type.\n", caller, id);
+ *errstr = "Widget with given ID has wrong type.\n";
return NULL;
}
return widget;
@@ -833,7 +863,10 @@ ltk_set_widget(ltk_window *window, ltk_widget *widget, const char *id) {
int ret;
khint_t k;
/* apparently, khash requires the string to stay accessible */
+ /* FIXME: How is this freed? */
char *tmp = strdup(id);
+ if (!tmp)
+ ltk_fatal_errno("Unable to add widget to hash table.\n");
k = kh_put(widget, window->widget_hash, tmp, &ret);
kh_value(window->widget_hash, k) = widget;
}
@@ -1079,26 +1112,33 @@ static void
process_commands(ltk_window *window, struct ltk_sock_info *sock) {
char **tokens;
int num_tokens;
+ char *errstr;
+ int err;
while (!tokenize_command(sock)) {
+ err = 0;
tokens = sock->tokens.tokens;
num_tokens = sock->tokens.num_tokens;
if (num_tokens < 1)
continue;
if (strcmp(tokens[0], "grid") == 0) {
- ltk_grid_cmd(window, tokens, num_tokens);
+ err = ltk_grid_cmd(window, tokens, num_tokens, &errstr);
} else if (strcmp(tokens[0], "button") == 0) {
- ltk_button_cmd(window, tokens, num_tokens);
+ err = ltk_button_cmd(window, tokens, num_tokens, &errstr);
} else if (strcmp(tokens[0], "set-root-widget") == 0) {
- ltk_set_root_widget_cmd(window, tokens, num_tokens);
+ err = ltk_set_root_widget_cmd(window, tokens, num_tokens, &errstr);
} else if (strcmp(tokens[0], "draw") == 0) {
- ltk_draw_cmd(window, tokens, num_tokens);
+ err = ltk_draw_cmd(window, tokens, num_tokens, &errstr);
} else if (strcmp(tokens[0], "quit") == 0) {
ltk_quit(window);
} else {
- /* FIXME... */
- (void)fprintf(stderr, "Invalid command.\n");
+ errstr = "Invalid command.\n";
+ err = 1;
}
sock->tokens.num_tokens = 0;
+ if (err) {
+ if (queue_sock_write(sock, errstr, -1) < 0)
+ ltk_fatal("Unable to queue socket write.\n");
+ }
}
if (sock->tokens.num_tokens > 0 && sock->tokens.tokens[0] != sock->read) {
memmove(sock->read, sock->tokens.tokens[0], sock->read + sock->read_len - sock->tokens.tokens[0]);
diff --git a/text_pango.c b/text_pango.c
@@ -8,6 +8,7 @@
#include <pango/pangoxft.h>
#include "util.h"
#include "text.h"
+#include "ltk.h"
struct LtkTextLine {
char *text;
@@ -34,7 +35,8 @@ ltk_init_text(const char *default_font, Display *dpy, int screen, Colormap cm) {
tm.fontmap = pango_xft_get_font_map(dpy, screen);
tm.context = pango_font_map_create_context(tm.fontmap);
tm.default_font = strdup(default_font);
- if (!tm.default_font) ltk_err("ltk_init_text (pango)");
+ if (!tm.default_font)
+ ltk_fatal_errno("Unable to allocate copy of font path.\n");
tm.dpy = dpy;
tm.screen = screen;
tm.cm = cm;
diff --git a/text_stb.c b/text_stb.c
@@ -318,17 +318,17 @@ ltk_create_font(char *path, uint16_t id, int index) {
LtkFont *font = malloc(sizeof(LtkFont));
if (!font) ltk_err("ltk_create_font (stb)");
char *contents = ltk_read_file(path, &len);
- /* FIXME: error checking */
+ if (!contents)
+ ltk_fatal_errno("Unable to read font file %s\n", path);
int offset = stbtt_GetFontOffsetForIndex(contents, index);
- if (!stbtt_InitFont(&font->info, contents, offset)) {
- (void)fprintf(stderr, "Failed to load font %s\n", path);
- exit(1);
- }
+ if (!stbtt_InitFont(&font->info, contents, offset))
+ ltk_fatal("Failed to load font %s\n", path);
font->id = id;
font->refs = 0;
font->index = index;
font->path = strdup(path);
- if (!font->path) ltk_err("ltk_create_font");
+ if (!font->path)
+ ltk_fatal_errno("Unable to allocate copy of font path.\n");
return font;
}
diff --git a/util.c b/util.c
@@ -38,11 +38,12 @@ ltk_read_file(const char *path, unsigned long *len) {
FILE *f;
char *file_contents;
f = fopen(path, "rb");
+ if (!f) return NULL;
fseek(f, 0, SEEK_END);
*len = ftell(f);
fseek(f, 0, SEEK_SET);
- /* FIXME: error checking */
file_contents = malloc(*len + 1);
+ if (!file_contents) return NULL;
fread(file_contents, 1, *len, f);
file_contents[*len] = '\0';
fclose(f);