commit 7dac53a708dd3625c7aa43f97a79ff0ef94158e3
parent f452a00a4143a913e61a395cf9e4b8728fa0a7a6
Author: lumidify <nobody@lumidify.org>
Date: Fri, 19 Feb 2021 22:43:45 +0100
Add wrapper for memory allocation
Diffstat:
M | Makefile | | | 4 | ++-- |
M | box.c | | | 15 | ++++++--------- |
M | button.c | | | 8 | ++++---- |
M | config.mk | | | 2 | +- |
M | draw.c | | | 10 | +++++----- |
M | grid.c | | | 37 | ++++++++++++++++++------------------- |
M | label.c | | | 8 | ++++---- |
M | ltkd.c | | | 39 | +++++++++++++++++---------------------- |
A | memory.c | | | 71 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | memory.h | | | 34 | ++++++++++++++++++++++++++++++++++ |
M | scrollbar.c | | | 7 | +++---- |
D | text_line.c | | | 143 | ------------------------------------------------------------------------------- |
D | text_line.h | | | 52 | ---------------------------------------------------- |
M | text_pango.c | | | 11 | ++++++----- |
M | text_stb.c | | | 34 | +++++++++++++++------------------- |
15 files changed, 186 insertions(+), 289 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,6 +1,6 @@
include config.mk
-OBJ += color.o util.o ltkd.o ini.o grid.o box.o scrollbar.o button.o label.o draw.o
+OBJ += memory.o color.o util.o ltkd.o ini.o grid.o box.o scrollbar.o button.o label.o draw.o
all: ltkd ltkc
@@ -16,4 +16,4 @@ ltkc: ltkc.o util.o
.PHONY: clean
clean:
- rm -f $(OBJ) ltkc.o ltkd ltkc ltk.sock *.core
+ rm -f *.o ltkd ltkc ltk.sock *.core
diff --git a/box.c b/box.c
@@ -29,6 +29,7 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
+#include "memory.h"
#include "color.h"
#include "ltk.h"
#include "util.h"
@@ -88,9 +89,7 @@ ltk_box_draw(ltk_box *box, ltk_rect clip) {
static ltk_box *
ltk_box_create(ltk_window *window, const char *id, ltk_orientation orient) {
- ltk_box *box = malloc(sizeof(ltk_box));
- if (!box)
- ltk_fatal("Unable to allocate memory for box.\n");
+ ltk_box *box = ltk_malloc(sizeof(ltk_box), "ltk_box_create");
ltk_fill_widget_defaults(&box->widget, id, window, <k_box_draw,
NULL, <k_box_destroy, 0, LTK_BOX);
@@ -119,11 +118,11 @@ ltk_box_destroy(ltk_box *box, int shallow) {
ptr->destroy(ptr, shallow);
}
}
- free(box->widgets);
+ ltk_free(box->widgets);
ltk_remove_widget(box->widget.window, box->widget.id);
- free(box->widget.id);
+ ltk_free(box->widget.id);
box->sc->widget.destroy(box->sc, 0);
- free(box);
+ ltk_free(box);
}
/* FIXME: Make this function name more consistent */
@@ -224,9 +223,7 @@ ltk_box_add(ltk_window *window, ltk_widget *widget, ltk_box *box, unsigned short
}
if (box->num_widgets >= box->num_alloc) {
size_t new_size = box->num_alloc > 0 ? box->num_alloc * 2 : 4;
- ltk_widget **new = realloc(box->widgets, new_size * sizeof(ltk_widget *));
- if (!new)
- ltk_fatal_errno("Unable to allocate memory for widgets in box.\n");
+ ltk_widget **new = ltk_realloc(box->widgets, new_size * sizeof(ltk_widget *), "ltk_box_add");
box->num_alloc = new_size;
box->widgets = new;
}
diff --git a/button.c b/button.c
@@ -30,6 +30,7 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
+#include "memory.h"
#include "color.h"
#include "ltk.h"
#include "util.h"
@@ -236,8 +237,7 @@ 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_errno("Unable to allocate memory for ltk_button.\n");
+ ltk_button *button = ltk_malloc(sizeof(ltk_button), "ltk_button_create");
ltk_fill_widget_defaults(&button->widget, id, window,
<k_button_draw, <k_button_change_state, <k_button_destroy, 1, LTK_BUTTON);
@@ -268,8 +268,8 @@ ltk_button_destroy(ltk_button *button, int shallow) {
}
ltk_text_line_destroy(button->tl);
ltk_remove_widget(button->widget.window, button->widget.id);
- free(button->widget.id);
- free(button);
+ ltk_free(button->widget.id);
+ ltk_free(button);
}
/* button <button id> create <text> */
diff --git a/config.mk b/config.mk
@@ -1,6 +1,6 @@
VERSION = -999
-CFLAGS = -D_POSIX_C_SOURCE=200809L -g -std=c99 -w -fcommon -Wall -Werror -Wextra `pkg-config --cflags x11 fontconfig` -pedantic
+CFLAGS = -DDEBUG -D_POSIX_C_SOURCE=200809L -g -std=c99 -w -fcommon -Wall -Werror -Wextra `pkg-config --cflags x11 fontconfig` -pedantic
LDFLAGS = -lm `pkg-config --libs x11 fontconfig`
# Comment when enabling pango rendering:
OBJ = stb_truetype.o text_stb.o
diff --git a/draw.c b/draw.c
@@ -30,6 +30,7 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
+#include "memory.h"
#include "color.h"
#include "ltk.h"
#include "util.h"
@@ -80,8 +81,7 @@ ltk_draw_draw(ltk_draw *draw) {
static ltk_draw *
ltk_draw_create(ltk_window *window, const char *id, int w, int h, const char *color) {
- ltk_draw *draw = malloc(sizeof(ltk_draw));
- if (!draw) ltk_fatal_errno("Unable to allocate memory for ltk_draw.\n");
+ ltk_draw *draw = ltk_malloc(sizeof(ltk_draw), ltk_draw_create);
ltk_fill_widget_defaults(&draw->widget, id, window,
<k_draw_draw, NULL, <k_draw_destroy, 1, LTK_DRAW);
@@ -90,7 +90,7 @@ ltk_draw_create(ltk_window *window, const char *id, int w, int h, const char *co
draw->widget.rect.h = h;
draw->pix = XCreatePixmap(window->dpy, window->xwindow, w, h, window->depth);
if (!ltk_create_xcolor(window, color, &draw->bg)) {
- free(draw);
+ ltk_free(draw);
ltk_fatal_errno("Unable to allocate XColor.\n");
}
draw->fg = draw->bg;
@@ -130,9 +130,9 @@ ltk_draw_destroy(ltk_draw *draw, int shallow) {
return;
}
ltk_remove_widget(draw->widget.window, draw->widget.id);
- free(draw->widget.id);
+ ltk_free(draw->widget.id);
XFreePixmap(draw->widget.window->dpy, draw->pix);
- free(draw);
+ ltk_free(draw);
}
static void
diff --git a/grid.c b/grid.c
@@ -36,6 +36,7 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
+#include "memory.h"
#include "color.h"
#include "ltk.h"
#include "util.h"
@@ -109,9 +110,7 @@ ltk_grid_draw(ltk_grid *grid, ltk_rect clip) {
static ltk_grid *
ltk_grid_create(ltk_window *window, const char *id, int rows, int columns) {
- ltk_grid *grid = malloc(sizeof(ltk_grid));
- if (!grid)
- ltk_fatal("Unable to allocate memory for grid.\n");
+ ltk_grid *grid = ltk_malloc(sizeof(ltk_grid), "ltk_grid_create");
ltk_fill_widget_defaults(&grid->widget, id, window, <k_grid_draw,
NULL, <k_grid_destroy, 0, LTK_GRID);
@@ -124,14 +123,14 @@ ltk_grid_create(ltk_window *window, const char *id, int rows, int columns) {
grid->rows = rows;
grid->columns = columns;
- grid->widget_grid = malloc(rows * columns * sizeof(ltk_widget));
- grid->row_heights = malloc(rows * sizeof(int));
- grid->column_widths = malloc(rows * sizeof(int));
- grid->row_weights = malloc(rows * sizeof(int));
- grid->column_weights = malloc(columns * sizeof(int));
+ grid->widget_grid = ltk_malloc(rows * columns * sizeof(ltk_widget), "ltk_grid_create");
+ grid->row_heights = ltk_malloc(rows * sizeof(int), "ltk_grid_create");
+ grid->column_widths = ltk_malloc(rows * sizeof(int), "ltk_grid_create");
+ grid->row_weights = ltk_malloc(rows * sizeof(int), "ltk_grid_create");
+ grid->column_weights = ltk_malloc(columns * sizeof(int), "ltk_grid_create");
/* Positions have one extra for the end */
- grid->row_pos = malloc((rows + 1) * sizeof(int));
- grid->column_pos = malloc((columns + 1) * sizeof(int));
+ grid->row_pos = ltk_malloc((rows + 1) * sizeof(int), "ltk_grid_create");
+ grid->column_pos = ltk_malloc((columns + 1) * sizeof(int), "ltk_grid_create");
/* FIXME: wow, that's horrible, this should just use memset */
int i;
for (i = 0; i < rows; i++) {
@@ -172,16 +171,16 @@ ltk_grid_destroy(ltk_grid *grid, int shallow) {
}
}
}
- free(grid->widget_grid);
- free(grid->row_heights);
- free(grid->column_widths);
- free(grid->row_weights);
- free(grid->column_weights);
- free(grid->row_pos);
- free(grid->column_pos);
+ ltk_free(grid->widget_grid);
+ ltk_free(grid->row_heights);
+ ltk_free(grid->column_widths);
+ ltk_free(grid->row_weights);
+ ltk_free(grid->column_weights);
+ ltk_free(grid->row_pos);
+ ltk_free(grid->column_pos);
ltk_remove_widget(grid->widget.window, grid->widget.id);
- free(grid->widget.id);
- free(grid);
+ ltk_free(grid->widget.id);
+ ltk_free(grid);
}
static void
diff --git a/label.c b/label.c
@@ -30,6 +30,7 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
+#include "memory.h"
#include "color.h"
#include "ltk.h"
#include "util.h"
@@ -94,8 +95,7 @@ ltk_label_draw(ltk_label *label, ltk_rect clip) {
static ltk_label *
ltk_label_create(ltk_window *window, const char *id, const char *text) {
char *text_copy;
- ltk_label *label = malloc(sizeof(ltk_label));
- if (!label) ltk_fatal_errno("Unable to allocate memory for ltk_label.\n");
+ ltk_label *label = ltk_malloc(sizeof(ltk_label), "ltk_label_create");
ltk_fill_widget_defaults(&label->widget, id, window,
<k_label_draw, NULL, <k_label_destroy, 1, LTK_LABEL);
@@ -126,8 +126,8 @@ ltk_label_destroy(ltk_label *label, int shallow) {
}
ltk_text_line_destroy(label->tl);
ltk_remove_widget(label->widget.window, label->widget.id);
- free(label->widget.id);
- free(label);
+ ltk_free(label->widget.id);
+ ltk_free(label);
}
/* label <label id> create <text> */
diff --git a/ltkd.c b/ltkd.c
@@ -47,6 +47,7 @@
#include "ini.h"
#include "khash.h"
+#include "memory.h"
#include "color.h"
#include "ltk.h"
#include "util.h"
@@ -257,10 +258,10 @@ ltk_mainloop(ltk_window *window) {
ltk_fatal_errno("Unable to queue event.\n");
}
}
- free(cur->data);
+ ltk_free(cur->data);
last = cur;
cur = cur->prev;
- free(last);
+ ltk_free(last);
} while (cur);
window->first_event = window->last_event = NULL;
}
@@ -324,9 +325,7 @@ get_sock_path(char *basedir, Window id) {
len = strlen(basedir);
/* FIXME: MAKE SURE THIS IS ACTUALLY BIG ENOUGH! */
- path = malloc(len + 20);
- if (!path)
- return NULL;
+ path = ltk_malloc(len + 20, "get_sock_path");
/* FIXME: also check for less than 0 */
if (snprintf(path, len + 20, "%s/%d.sock", basedir, id) >= len + 20)
ltk_fatal("Tell lumidify to fix his code.\n");
@@ -345,10 +344,10 @@ open_log(char *dir) {
return NULL;
f = fopen(path, "a");
if (!f) {
- free(path);
+ ltk_free(path);
return NULL;
}
- free(path);
+ ltk_free(path);
return f;
}
@@ -358,23 +357,23 @@ ltk_cleanup(void) {
if (listenfd >= 0)
close(listenfd);
if (ltk_dir)
- free(ltk_dir);
+ ltk_free(ltk_dir);
if (ltk_logfile)
fclose(ltk_logfile);
if (sock_path) {
unlink(sock_path);
- free(sock_path);
+ ltk_free(sock_path);
}
for (int i = 0; i < MAX_SOCK_CONNS; i++) {
if (sockets[i].fd >= 0)
close(sockets[i].fd);
if (sockets[i].read)
- free(sockets[i].read);
+ ltk_free(sockets[i].read);
if (sockets[i].to_write)
- free(sockets[i].to_write);
+ ltk_free(sockets[i].to_write);
if (sockets[i].tokens.tokens)
- free(sockets[i].tokens.tokens);
+ ltk_free(sockets[i].tokens.tokens);
}
if (widget_hash)
@@ -515,13 +514,11 @@ 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) {
/* FIXME: make it nicer and safer */
- struct ltk_event_queue *new = malloc(sizeof(struct ltk_event_queue));
- if (!new) ltk_fatal_errno("Unable to queue event.\n");
+ struct ltk_event_queue *new = ltk_malloc(sizeof(struct ltk_event_queue), "ltk_queue_event");
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_errno("Unable to queue event.\n");
+ new->data = ltk_malloc(id_len + data_len + 3, "ltk_queue_event");
strcpy(new->data, id);
new->data[id_len] = ' ';
strcpy(new->data + id_len + 1, data);
@@ -588,9 +585,7 @@ ltk_create_window(const char *title, int x, int y, unsigned int w, unsigned int
char *theme_path;
XWindowAttributes attrs;
- ltk_window *window = malloc(sizeof(ltk_window));
- if (!window)
- ltk_fatal_errno("Not enough memory left for window!\n");
+ ltk_window *window = ltk_malloc(sizeof(ltk_window), "ltk_create_window");
window->dpy = XOpenDisplay(NULL);
window->screen = DefaultScreen(window->dpy);
@@ -665,8 +660,8 @@ ltk_destroy_window(ltk_window *window) {
/* FIXME: This doesn't work because it can sometimes be a readonly
string from ltk_window_setup_theme_defaults! */
if (window->theme.font)
- free(window->theme.font);
- free(window);
+ ltk_free(window->theme.font);
+ ltk_free(window);
}
void
@@ -962,7 +957,7 @@ push_token(struct token_list *tl, char *token) {
if (tl->num_tokens >= tl->num_alloc) {
new_size = (tl->num_alloc * 2) > (tl->num_tokens + 1) ?
(tl->num_alloc * 2) : (tl->num_tokens + 1);
- char **new = realloc(tl->tokens, new_size * sizeof(char *));
+ char **new = ltk_realloc(tl->tokens, new_size * sizeof(char *), "push_token");
if (!new) return -1;
tl->tokens = new;
tl->num_alloc = new_size;
diff --git a/memory.c b/memory.c
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the Lumidify ToolKit (LTK)
+ * Copyright (c) 2021 lumidify <nobody@lumidify.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <stdarg.h>
+#include "color.h"
+#include "ltk.h"
+
+void *
+ltk_malloc(size_t size, const char *caller) {
+ void *ptr = malloc(size);
+ if (!ptr)
+ ltk_fatal("%s: out of memory.\n", caller);
+ #ifdef DEBUG
+ fprintf(stderr, "DEBUG: malloc: address %p, %zu bytes.\n", ptr, size);
+ #endif
+ return ptr;
+}
+
+void *
+ltk_calloc(size_t nmemb, size_t size, const char *caller) {
+ void *ptr = calloc(nmemb, size);
+ if (!ptr)
+ ltk_fatal("%s: out of memory.\n", caller);
+ #ifdef DEBUG
+ fprintf(stderr, "DEBUG: calloc: address %p, %zu bytes.\n", ptr, size);
+ #endif
+ return ptr;
+}
+
+void *
+ltk_realloc(void *ptr, size_t size, const char *caller) {
+ void *new_ptr = realloc(ptr, size);
+ if (!new_ptr)
+ ltk_fatal("%s: out of memory.\n", caller);
+ #ifdef DEBUG
+ fprintf(stderr, "DEBUG: realloc: old %p, new %p, %zu bytes.\n", ptr, new_ptr, size);
+ #endif
+ return new_ptr;
+}
+
+void
+ltk_free(void *ptr) {
+ #ifdef DEBUG
+ fprintf(stderr, "DEBUG: free: address %p\n", ptr);
+ #endif
+ free(ptr);
+}
diff --git a/memory.h b/memory.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the Lumidify ToolKit (LTK)
+ * Copyright (c) 2021 lumidify <nobody@lumidify.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _LTK_MEMORY_H_
+#define _LTK_MEMORY_H_
+
+/* FIXME: Move ltk_warn, etc. to util.* */
+
+void *ltk_malloc(size_t size, const char *caller);
+void *ltk_calloc(size_t nmemb, size_t size, const char *caller);
+void *ltk_realloc(void *ptr, size_t size, const char *caller);
+void ltk_free(void *ptr);
+
+#endif /* _LTK_MEMORY_H_ */
diff --git a/scrollbar.c b/scrollbar.c
@@ -30,6 +30,7 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
+#include "memory.h"
#include "color.h"
#include "ltk.h"
#include "util.h"
@@ -221,9 +222,7 @@ ltk_scrollbar_motion_notify(ltk_scrollbar *sc, XEvent event) {
ltk_scrollbar *
ltk_scrollbar_create(ltk_window *window, ltk_orientation orient, void (*callback)(void *), void *data) {
- ltk_scrollbar *sc = malloc(sizeof(ltk_scrollbar));
- if (!sc)
- ltk_fatal_errno("Unable to allocate memory for scrollbar.\n");
+ ltk_scrollbar *sc = ltk_malloc(sizeof(ltk_scrollbar), "ltk_scrollbar_create");
ltk_fill_widget_defaults(sc, NULL, window, <k_scrollbar_draw,
NULL, <k_scrollbar_destroy, 1, LTK_UNKNOWN);
sc->last_mouse_x = sc->last_mouse_y = 0;
@@ -245,5 +244,5 @@ ltk_scrollbar_create(ltk_window *window, ltk_orientation orient, void (*callback
static void
ltk_scrollbar_destroy(ltk_scrollbar *scrollbar, int shallow) {
- free(scrollbar);
+ ltk_free(scrollbar);
}
diff --git a/text_line.c b/text_line.c
@@ -1,143 +0,0 @@
-/*
- * This file is part of the Lumidify ToolKit (LTK)
- * Copyright (c) 2020 lumidify <nobody@lumidify.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include "text_common.h"
-#include "text_line.h"
-#include "util.h"
-
-void ltk_init_text(const char *default_font, Display *dpy, int screen, Colormap cm);
-void ltk_cleanup_text(void);
-
-LtkTextLine *ltk_text_line_create(Window window, uint16_t font_size, char *text, int width);
-void ltk_text_line_render(LtkTextLine *tl, LtkColor *bg, LtkColor *fg);
-void ltk_text_line_draw(LtkTextLine *tl, GC gc, int x, int y, ltk_rect clip);
-void ltk_text_line_set_width(LtkTextLine *tl, int width);
-void ltk_text_line_get_size(LtkTextLine *tl, int *w, int *h);
-void ltk_text_line_destroy(LtkTextLine *tl);
-
-static void ltk_text_line_create_glyphs(struct ltk_text_line *tl);
-static void ltk_text_line_draw_glyph(ltk_glyph *glyph, int xoff, int yoff,
- XImage *img, XColor fg);
-static XImage *ltk_create_ximage(Display *dpy, int w, int h, int depth,
- XColor bg);
-
-static XImage *
-ltk_create_ximage(Display *dpy, int w, int h, int depth, XColor bg) {
- XImage *img = XCreateImage(dpy, CopyFromParent, depth, ZPixmap, 0, NULL, w, h, 32, 0);
- img->data = calloc(img->bytes_per_line, img->height);
- XInitImage(img);
-
- int b;
- for (int i = 0; i < h; i++) {
- b = img->bytes_per_line * i;
- for (int j = 0; j < w; j++) {
- img->data[b++] = bg.blue / 257;
- img->data[b++] = bg.green / 257;
- img->data[b++] = bg.red / 257;
- b++;
- }
- }
-
- return img;
-}
-
-/* based on http://codemadness.org/git/dwm-font/file/drw.c.html#l315 */
-static void
-ltk_text_line_draw_glyph(ltk_glyph *glyph, int xoff, int yoff, XImage *img, XColor fg) {
- int x = glyph->x + xoff;
- int y = glyph->y + yoff;
- double a;
- int b;
- for (int i = 0; i < glyph->info->h; i++) {
- for (int j = 0; j < glyph->info->w; j++) {
- if (y + i >= img->height || x + j >= img->width ||
- y + i < 0 || x + i < 0)
- continue;
- b = (y + i) * img->bytes_per_line + (x + j) * 4;
- a = glyph->info->alphamap[i * glyph->info->w + j] / 255.0;
- img->data[b] = (fg.blue * a + (1 - a) * (uint16_t)img->data[b] * 257) / 257;
- img->data[b + 1] = (fg.green * a + (1 - a) * (uint16_t)img->data[b + 1] * 257) / 257;
- img->data[b + 2] = (fg.red * a + (1 - a) * (uint16_t)img->data[b + 2] * 257) / 257;
- }
- }
-}
-
-XImage *
-ltk_text_line_render(
- struct ltk_text_line *tl,
- Display *dpy,
- Window window,
- GC gc,
- Colormap colormap,
- XColor fg,
- XColor bg)
-{
- ltk_glyph *glyph;
-
- XWindowAttributes attrs;
- XGetWindowAttributes(dpy, window, &attrs);
- int depth = attrs.depth;
- /* FIXME: pass old image; if it has same dimensions, just clear it */
- XImage *img = ltk_create_ximage(dpy, tl->w, tl->h, depth, bg);
- for (int i = 0; i < tl->glyph_len; i++) {
- ltk_text_line_draw_glyph(&tl->glyphs[i], -tl->x_min, -tl->y_min, img, fg);
- }
- return img;
-}
-
-static void
-ltk_text_line_create_glyphs(LtkTextLine *tl) {
- int x_min, x_max, y_min, y_max;
- ltk_text_to_glyphs(tl->glyphs, tl->glyph_len, tl->text, tl->font_size,
- &x_min, &y_min, &x_max, &y_max);
- /* for drawing the glyphs at the right position on the image */
- tl->x_min = x_min;
- tl->y_min = y_min;
- tl->w = x_max - x_min;
- tl->h = y_max - y_min;
-}
-
-LtkTextLine *
-ltk_text_line_create(uint16_t font_size, char *text, int width) {
- LtkTextLine *line = malloc(sizeof(LtkTextLine));
- if (!line) ltk_err("ltk_text_line_create (basic)");
- line->text = text;
- line->glyph_len = u8_strlen(text);
- line->glyphs = malloc(line->glyph_len * sizeof(ltk_glyph));
- line->font_size = font_size;
- ltk_text_line_create_glyphs(line);
- return line;
-}
-
-void
-ltk_text_line_destroy(LtkTextLine *tl) {
- free(tl->text);
- /* FIXME: Reference count glyph infos */
- free(tl->glyphs);
- free(tl);
-}
diff --git a/text_line.h b/text_line.h
@@ -1,52 +0,0 @@
-/*
- * This file is part of the Lumidify ToolKit (LTK)
- * Copyright (c) 2020 lumidify <nobody@lumidify.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef _TEXT_LINE_H_
-#define _TEXT_LINE_H_
-
-/*
-Requires the following includes:
-<X11/Xlib.h>, <X11/Xutil.h>, <stdint.h>
-*/
-
-typedef struct {
- char *text;
- ltk_glyph *glyphs;
- size_t glyph_len;
- uint16_t font_size;
- int w;
- int h;
- int x_min;
- int y_min;
-} LtkTextLine;
-
-void ltk_init_text(const char *default_font, Display *dpy, int screen, Colormap cm);
-void ltk_cleanup_text(void);
-LtkTextLine *ltk_text_line_create(Window window, uint16_t font_size, char *text, int width);
-void ltk_text_line_render(LtkTextLine *tl, LtkColor *bg, LtkColor *fg);
-void ltk_text_line_draw(LtkTextLine *tl, GC gc, int x, int y);
-void ltk_text_line_set_width(LtkTextLine *tl, int width);
-void ltk_text_line_get_size(LtkTextLine *tl, int *w, int *h);
-void ltk_text_line_destroy(LtkTextLine *tl);
-
-#endif /* _TEXT_LINE_H_ */
diff --git a/text_pango.c b/text_pango.c
@@ -10,6 +10,7 @@
#include <pango/pangoxft.h>
+#include "memory.h"
#include "color.h"
#include "ltk.h"
#include "util.h"
@@ -49,7 +50,8 @@ ltk_init_text(const char *default_font, Display *dpy, int screen, Colormap cm) {
void
ltk_cleanup_text(void) {
- if (tm.default_font) free(tm.default_font);
+ /* FIXME: strdup, etc. wrapper */
+ if (tm.default_font) ltk_free(tm.default_font);
/* FIXME: destroy fontmap and context */
}
@@ -62,8 +64,7 @@ LtkTextLine *
ltk_text_line_create(Window window, uint16_t font_size, char *text, int width) {
if (!tm.context)
ltk_err("ltk_text_line_create (pango): text not initialized yet");
- LtkTextLine *line = malloc(sizeof(LtkTextLine));
- if (!line) ltk_err("ltk_text_line_create (pango)");
+ LtkTextLine *line = ltk_malloc(sizeof(LtkTextLine), "ltk_text_line_create");
line->text = text;
line->font_size = font_size;
line->layout = pango_layout_new(tm.context);
@@ -115,6 +116,6 @@ ltk_text_line_destroy(LtkTextLine *tl) {
g_object_unref(tl->layout);
XftDrawDestroy(tl->draw);
XFreePixmap(tm.dpy, tl->pixmap);
- free(tl->text);
- free(tl);
+ ltk_free(tl->text);
+ ltk_free(tl);
}
diff --git a/text_stb.c b/text_stb.c
@@ -35,6 +35,7 @@
#include "khash.h"
#include "stb_truetype.h" /* http://nothings.org/stb/stb_truetype.h */
+#include "memory.h"
#include "color.h"
#include "ltk.h"
#include "util.h"
@@ -200,8 +201,7 @@ void
ltk_init_text(const char *default_font, Display *dpy, int screen, Colormap cm) {
tm.fonts_bufsize = 1;
tm.glyph_cache = kh_init(glyphcache);
- tm.fonts = malloc(sizeof(LtkFont *));
- if (!tm.fonts) ltk_err("ltk_init_text");
+ tm.fonts = ltk_malloc(sizeof(LtkFont *), "ltk_init_text");
ltk_load_default_font(default_font);
tm.dpy = dpy;
tm.screen = screen;
@@ -224,8 +224,7 @@ ltk_cleanup_text(void) {
static LtkGlyphInfo *
ltk_create_glyph_info(LtkFont *font, int id, float scale) {
- LtkGlyphInfo *glyph = malloc(sizeof(LtkGlyphInfo));
- if (!glyph) ltk_err("ltk_create_glyph_info");
+ LtkGlyphInfo *glyph = ltk_malloc(sizeof(LtkGlyphInfo), "ltk_create_glyph_info");
glyph->id = id;
glyph->refs = 0;
@@ -239,8 +238,8 @@ ltk_create_glyph_info(LtkFont *font, int id, float scale) {
static void
ltk_destroy_glyph_info(LtkGlyphInfo *gi) {
- free(gi->alphamap);
- free(gi);
+ ltk_free(gi->alphamap);
+ ltk_free(gi);
}
static LtkGlyphInfo *
@@ -321,8 +320,7 @@ ltk_load_default_font(char *name) {
static LtkFont *
ltk_create_font(char *path, uint16_t id, int index) {
unsigned long len;
- LtkFont *font = malloc(sizeof(LtkFont));
- if (!font) ltk_err("ltk_create_font (stb)");
+ LtkFont *font = ltk_malloc(sizeof(LtkFont), "ltk_create_font");
char *contents = ltk_read_file(path, &len);
if (!contents)
ltk_fatal_errno("Unable to read font file %s\n", path);
@@ -341,16 +339,15 @@ ltk_create_font(char *path, uint16_t id, int index) {
static void
ltk_destroy_font(LtkFont *font) {
- free(font->info.data);
- free(font);
+ ltk_free(font->info.data);
+ ltk_free(font);
}
static LtkFont *
ltk_load_font(char *path, int index) {
LtkFont *font = ltk_create_font(path, tm.font_id_cur++, index);
if (tm.num_fonts == tm.fonts_bufsize) {
- LtkFont *new = realloc(tm.fonts, tm.fonts_bufsize * 2 * sizeof(LtkFont *));
- if (!new) ltk_err("ltk_load_font");
+ LtkFont *new = ltk_realloc(tm.fonts, tm.fonts_bufsize * 2 * sizeof(LtkFont *), "ltk_load_font");
tm.fonts = new;
tm.fonts_bufsize *= 2;
}
@@ -474,7 +471,7 @@ ltk_unref_glyphs(ltk_glyph *glyphs, int num_glyphs) {
static XImage *
ltk_create_ximage(int w, int h, int depth, XColor bg) {
XImage *img = XCreateImage(tm.dpy, CopyFromParent, depth, ZPixmap, 0, NULL, w, h, 32, 0);
- img->data = calloc(img->bytes_per_line, img->height);
+ img->data = ltk_calloc(img->bytes_per_line, img->height, "ltk_create_ximage");
XInitImage(img);
int b;
@@ -572,13 +569,12 @@ ltk_text_line_create_glyphs(LtkTextLine *tl) {
LtkTextLine *
ltk_text_line_create(Window window, uint16_t font_size, char *text, int width) {
- LtkTextLine *line = malloc(sizeof(LtkTextLine));
- if (!line) ltk_err("ltk_text_line_create (basic)");
+ LtkTextLine *line = ltk_malloc(sizeof(LtkTextLine), "ltk_text_line_create");
line->window = window;
line->img = NULL;
line->text = text;
line->glyph_len = u8_strlen(text);
- line->glyphs = malloc(line->glyph_len * sizeof(LtkGlyph));
+ line->glyphs = ltk_malloc(line->glyph_len * sizeof(LtkGlyph), "ltk_text_line_create");
line->font_size = font_size;
ltk_text_line_create_glyphs(line);
return line;
@@ -586,8 +582,8 @@ ltk_text_line_create(Window window, uint16_t font_size, char *text, int width) {
void
ltk_text_line_destroy(LtkTextLine *tl) {
- free(tl->text);
+ ltk_free(tl->text);
/* FIXME: Reference count glyph infos */
- free(tl->glyphs);
- free(tl);
+ ltk_free(tl->glyphs);
+ ltk_free(tl);
}