commit adc45f7ba5398d573a017db1a1b7c9044d3a3455
parent 5295095706d12ad5306360f812a51d46f023c86e
Author: lumidify <nobody@lumidify.org>
Date:   Sun, 26 Dec 2021 11:02:45 +0100
Add double buffering
Diffstat:
34 files changed, 136 insertions(+), 61 deletions(-)
diff --git a/LICENSE b/LICENSE
@@ -6,7 +6,7 @@ ISC License
 The Lumidify ToolKit (LTK)
 Copyright (c) 2016-2021 lumidify <nobody@lumidify.org>
 
-Permission to use, copy, modify, and distribute this software for any
+Permission to use, copy, modify, and/or distribute this software for any
 purpose with or without fee is hereby granted, provided that the above
 copyright notice and this permission notice appear in all copies.
 
diff --git a/Makefile b/Makefile
@@ -12,8 +12,8 @@ USE_PANGO = 0
 # FIXME: When using _POSIX_C_SOURCE on OpenBSD, strtonum isn't defined anymore -
 # should strtonum just only be used from the local copy?
 
-CFLAGS += -DUSE_PANGO=$(USE_PANGO) -DDEV=$(DEV) -std=c99 `pkg-config --cflags x11 fontconfig` -D_POSIX_C_SOURCE=200809L
-LDFLAGS += -lm `pkg-config --libs x11 fontconfig`
+CFLAGS += -DUSE_PANGO=$(USE_PANGO) -DDEV=$(DEV) -std=c99 `pkg-config --cflags x11 fontconfig xext` -D_POSIX_C_SOURCE=200809L
+LDFLAGS += -lm `pkg-config --libs x11 fontconfig xext`
 
 # Note: this macro magic for debugging and pango rendering seems ugly; it should probably be changed
 
diff --git a/TODO b/TODO
@@ -24,3 +24,4 @@ Random stuff:
   program can do the normal GUI stuff, but everything can still be
   edited on-the-fly, and text can be retrieved (e.g. for a screen-
   reader).
+* Maybe allow option to use Xresources (see https://datenwolf.net/missing.html)
diff --git a/src/box.c b/src/box.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2021 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
diff --git a/src/box.h b/src/box.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2021 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
diff --git a/src/button.c b/src/button.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2016, 2017, 2018, 2020 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
diff --git a/src/button.h b/src/button.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2016, 2017, 2018, 2020 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
diff --git a/src/color.c b/src/color.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2021 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
diff --git a/src/color.h b/src/color.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2021 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
diff --git a/src/draw.c b/src/draw.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2020 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
@@ -84,7 +84,7 @@ ltk_draw_draw(ltk_widget *self, ltk_rect clip_rect) {
 	ltk_draw *draw = (ltk_draw *)self;
 	ltk_window *window = draw->widget.window;
 	ltk_rect rect = draw->widget.rect;
-	XCopyArea(window->dpy, draw->pix, window->xwindow, window->gc, 0, 0, rect.w, rect.h, rect.x, rect.y);
+	XCopyArea(window->dpy, draw->pix, window->drawable, window->gc, 0, 0, rect.w, rect.h, rect.x, rect.y);
 }
 
 
@@ -95,7 +95,7 @@ ltk_draw_create(ltk_window *window, const char *id, int w, int h, const char *co
 	ltk_fill_widget_defaults(&draw->widget, id, window, &vtable, w, h);
 	draw->widget.rect.w = w;
 	draw->widget.rect.h = h;
-	draw->pix = XCreatePixmap(window->dpy, window->xwindow, w, h, window->depth);
+	draw->pix = XCreatePixmap(window->dpy, window->drawable, w, h, window->depth);
 	if (!ltk_create_xcolor(window, color, &draw->bg)) {
 		ltk_free(draw);
 		ltk_fatal_errno("Unable to allocate XColor.\n");
@@ -123,7 +123,7 @@ ltk_draw_resize(ltk_widget *self) {
 	new_h = (int)h < rect.h ? rect.h : (int)h;
 	if (new_w < w && new_h < h)
 		return;
-	Pixmap tmp = XCreatePixmap(window->dpy, window->xwindow,
+	Pixmap tmp = XCreatePixmap(window->dpy, window->drawable,
 	    new_w, new_h, window->depth);
 	XSetForeground(window->dpy, window->gc, draw->bg.pixel);
 	XFillRectangle(window->dpy, tmp, window->gc, 0, 0, new_w, new_h);
@@ -154,7 +154,7 @@ ltk_draw_clear(ltk_window *window, ltk_draw *draw) {
 	unsigned int w, h, bw, d;
 	XGetGeometry(window->dpy, draw->pix, &win, &x, &y, &w, &h, &bw, &d);
 	XSetForeground(window->dpy, window->gc, draw->bg.pixel);
-	XFillRectangle(window->dpy, window->xwindow, window->gc, 0, 0, w, h);
+	XFillRectangle(window->dpy, window->drawable, window->gc, 0, 0, w, h);
 	ltk_draw_draw((ltk_widget *)draw, draw->widget.rect);
 }
 
@@ -181,7 +181,7 @@ ltk_draw_line(ltk_window *window, ltk_draw *draw, int x1, int y1, int x2, int y2
 	if (y1 > rect.y + rect.h) y1 = rect.y + rect.h;
 	if (x2 > rect.x + rect.w) x2 = rect.x + rect.w;
 	if (y2 > rect.y + rect.h) y2 = rect.y + rect.h;
-	XDrawLine(window->dpy, window->xwindow, window->gc, x1, y1, x2, y2);
+	XDrawLine(window->dpy, window->drawable, window->gc, x1, y1, x2, y2);
 }
 
 static void
@@ -195,11 +195,11 @@ ltk_draw_rect(ltk_window *window, ltk_draw *draw, int x, int y, int w, int h, in
 	h_win = y + h > rect.h ? rect.h - y : h;
 	if (fill) {
 		XFillRectangle(window->dpy, draw->pix, window->gc, x, y, w, h);
-		XFillRectangle(window->dpy, window->xwindow, window->gc, x_win, y_win, w_win, h_win);
+		XFillRectangle(window->dpy, window->drawable, window->gc, x_win, y_win, w_win, h_win);
 	} else {
 		XSetLineAttributes(window->dpy, window->gc, 2, LineSolid, CapButt, JoinMiter);
 		XDrawRectangle(window->dpy, draw->pix, window->gc, x, y, w, h);
-		XDrawRectangle(window->dpy, window->xwindow, window->gc, x_win, y_win, w_win, h_win);
+		XDrawRectangle(window->dpy, window->drawable, window->gc, x_win, y_win, w_win, h_win);
 	}
 }
 
diff --git a/src/draw.h b/src/draw.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2020 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
diff --git a/src/graphics.c b/src/graphics.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2021 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
@@ -16,6 +16,7 @@
 
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
+#include <stdint.h>
 
 #include "color.h"
 #include "rect.h"
@@ -50,7 +51,7 @@ ltk_copy_clipped(ltk_widget *widget, ltk_rect clip) {
 	if (clip_final.w <= 0 || clip_final.h <= 0)
 		return;
 	XCopyArea(
-	    win->dpy, widget->pixmap, win->xwindow, win->gc,
+	    win->dpy, widget->pixmap, win->drawable, win->gc,
 	    clip_final.x - widget->rect.x, clip_final.y - widget->rect.y,
 	    clip_final.w, clip_final.h, clip_final.x, clip_final.y
 	);
diff --git a/src/graphics.h b/src/graphics.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2021 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
diff --git a/src/grid.c b/src/grid.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2016, 2017, 2018, 2020, 2021 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
diff --git a/src/grid.h b/src/grid.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2016, 2017, 2018, 2020 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
diff --git a/src/label.c b/src/label.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2021 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
diff --git a/src/label.h b/src/label.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2021 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
diff --git a/src/ltk.h b/src/ltk.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2016, 2017, 2018 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
@@ -20,6 +20,7 @@
 /* Requires the following includes: <X11/Xlib.h>, <X11/Xutil.h>, "widget.h" */
 
 #include <stdint.h>
+#include <X11/extensions/Xdbe.h>
 
 typedef enum {
 	LTK_EVENT_RESIZE = 1 << 0,
@@ -54,11 +55,14 @@ struct ltk_event_queue {
 
 typedef struct ltk_window {
 	Display *dpy;
+	Visual *vis;
 	Colormap cm;
 	GC gc;
 	int screen;
 	Atom wm_delete_msg;
 	Window xwindow;
+	XdbeBackBuffer back_buf;
+	Drawable drawable;
 	int depth;
 	ltk_widget *root_widget;
 	ltk_widget *active_widget;
diff --git a/src/ltkc.c b/src/ltkc.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2021 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
diff --git a/src/ltkd.c b/src/ltkd.c
@@ -7,7 +7,7 @@
 /*
  * Copyright (c) 2016, 2017, 2018, 2020, 2021 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
@@ -473,11 +473,24 @@ ltk_redraw_window(ltk_window *window) {
 		window->dirty_rect.w -= window->dirty_rect.x + window->dirty_rect.w - window->rect.w;
 	if (window->dirty_rect.y + window->dirty_rect.h > window->rect.h)
 		window->dirty_rect.h -= window->dirty_rect.y + window->dirty_rect.h - window->rect.h;
-	XClearArea(window->dpy, window->xwindow, window->dirty_rect.x, window->dirty_rect.y, window->dirty_rect.w, window->dirty_rect.h, False);
+	XSetForeground(window->dpy, window->gc, window->theme.bg.xcolor.pixel);
+	/* FIXME: this should use window->dirty_rect, but that doesn't work
+	   properly with double buffering */
+	XFillRectangle(
+		window->dpy, window->drawable, window->gc,
+		window->rect.x, window->rect.y,
+		window->rect.w, window->rect.h
+	);
 	if (!window->root_widget) return;
 	ptr = window->root_widget;
 	if (ptr)
-		ptr->vtable->draw(ptr, window->dirty_rect);
+		ptr->vtable->draw(ptr, window->rect);
+	XdbeSwapInfo swap_info;
+	swap_info.swap_window = window->xwindow;
+	swap_info.swap_action = XdbeBackground;
+	if (!XdbeSwapBuffers(window->dpy, &swap_info, 1))
+		ltk_fatal("Unable to swap buffers.\n");
+	XFlush(window->dpy);
 }
 
 static void
@@ -515,12 +528,44 @@ ltk_window_other_event(ltk_window *window, XEvent event) {
 static ltk_window *
 ltk_create_window(const char *title, int x, int y, unsigned int w, unsigned int h) {
 	char *theme_path;
-	XWindowAttributes attrs;
+	XSetWindowAttributes attrs;
 
 	ltk_window *window = ltk_malloc(sizeof(ltk_window));
 
 	window->dpy = XOpenDisplay(NULL);
 	window->screen = DefaultScreen(window->dpy);
+	/* based on http://wili.cc/blog/xdbe.html */
+	int major, minor, found = 0;
+	if (XdbeQueryExtension(window->dpy, &major, &minor)) {
+		int num_screens = 1;
+		Drawable screens[] = {DefaultRootWindow(window->dpy)};
+		XdbeScreenVisualInfo *info = XdbeGetVisualInfo(
+		    window->dpy, screens, &num_screens
+		);
+		if (!info || num_screens < 1 || info->count < 1) {
+			ltk_fatal("No visuals support Xdbe.");
+		}
+		XVisualInfo xvisinfo_templ;
+		/* we know there's at least one */
+		xvisinfo_templ.visualid = info->visinfo[0].visual;
+		/* FIXME: proper screen number? */
+		xvisinfo_templ.screen = 0;
+		xvisinfo_templ.depth = info->visinfo[0].depth;
+		int matches;
+		XVisualInfo *xvisinfo_match = XGetVisualInfo(
+		    window->dpy,
+		    VisualIDMask | VisualScreenMask | VisualDepthMask,
+		    &xvisinfo_templ, &matches
+		);
+		if (!xvisinfo_match || matches < 1) {
+			ltk_fatal("Couldn't match a Visual with double buffering.\n");
+		}
+		window->vis = xvisinfo_match->visual;
+		found = 1;
+	} else {
+		window->vis = DefaultVisual(window->dpy, window->screen);
+		ltk_warn("No Xdbe support.\n");
+	}
 	//printf("%d   %d\n", WidthOfScreen(XDefaultScreenOfDisplay(window->dpy)), WidthMMOfScreen(XDefaultScreenOfDisplay(window->dpy)));
 	window->cm = DefaultColormap(window->dpy, window->screen);
 	theme_path = ltk_strcat_useful(ltk_dir, "/theme.ini");
@@ -530,17 +575,40 @@ ltk_create_window(const char *title, int x, int y, unsigned int w, unsigned int 
 	ltk_load_theme(window, theme_path);
 	window->wm_delete_msg = XInternAtom(window->dpy, "WM_DELETE_WINDOW", False);
 
-	window->xwindow =
-	    XCreateSimpleWindow(window->dpy, DefaultRootWindow(window->dpy), x, y,
-				w, h, window->theme.border_width,
-				window->theme.fg.xcolor.pixel, window->theme.bg.xcolor.pixel);
-	XGetWindowAttributes(window->dpy, window->xwindow, &attrs);
-	window->depth = attrs.depth;
+	memset(&attrs, 0, sizeof(attrs));
+	attrs.background_pixel = window->theme.bg.xcolor.pixel;
+	attrs.colormap = window->cm;
+	attrs.border_pixel = window->theme.fg.xcolor.pixel;
+	/* this causes the window contents to be kept
+	 * when it is resized, leading to less flicker */
+	attrs.bit_gravity = NorthWestGravity;
+	attrs.event_mask =
+		ExposureMask | KeyPressMask | KeyReleaseMask |
+		ButtonPressMask | ButtonReleaseMask |
+		StructureNotifyMask | PointerMotionMask;
+	window->depth = DefaultDepth(window->dpy, window->screen);
+	window->xwindow = XCreateWindow(
+	    window->dpy, DefaultRootWindow(window->dpy), x, y,
+	    w, h, window->theme.border_width, window->depth,
+	    InputOutput, window->vis,
+	    CWBackPixel | CWColormap | CWBitGravity | CWEventMask | CWBorderPixel, &attrs
+	);
+
+	if (found) {
+		window->back_buf = XdbeAllocateBackBufferName(
+			window->dpy, window->xwindow, XdbeBackground
+		);
+	} else {
+		window->back_buf = window->xwindow;
+	}
+	window->drawable = window->back_buf;
 	window->gc = XCreateGC(window->dpy, window->xwindow, 0, 0);
 	XSetForeground(window->dpy, window->gc, window->theme.fg.xcolor.pixel);
 	XSetBackground(window->dpy, window->gc, window->theme.bg.xcolor.pixel);
-	XSetStandardProperties(window->dpy, window->xwindow, title, NULL, None,
-			       NULL, 0, NULL);
+	XSetStandardProperties(
+		window->dpy, window->xwindow,
+		title, NULL, None, NULL, 0, NULL
+	);
 	XSetWMProtocols(window->dpy, window->xwindow, &window->wm_delete_msg, 1);
 	window->root_widget = NULL;
 	window->active_widget = NULL;
@@ -563,10 +631,6 @@ ltk_create_window(const char *title, int x, int y, unsigned int w, unsigned int 
 
 	XClearWindow(window->dpy, window->xwindow);
 	XMapRaised(window->dpy, window->xwindow);
-	XSelectInput(window->dpy, window->xwindow,
-		     ExposureMask | KeyPressMask | KeyReleaseMask |
-		     ButtonPressMask | ButtonReleaseMask |
-		     StructureNotifyMask | PointerMotionMask);
 
 	return window;
 }
diff --git a/src/memory.c b/src/memory.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2021 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
diff --git a/src/memory.h b/src/memory.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2021 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
diff --git a/src/rect.c b/src/rect.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2021 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
diff --git a/src/rect.h b/src/rect.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2021 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
diff --git a/src/scrollbar.c b/src/scrollbar.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2021 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
@@ -138,7 +138,7 @@ ltk_scrollbar_draw(ltk_widget *self, ltk_rect clip) {
 		ltk_fatal("No style found for current scrollbar state.\n");
 	}
 	XSetForeground(window->dpy, window->gc, bg->xcolor.pixel);
-	XFillRectangle(window->dpy, window->xwindow, window->gc,
+	XFillRectangle(window->dpy, window->drawable, window->gc,
 	    rect.x, rect.y, rect.w, rect.h);
 	XSetForeground(window->dpy, window->gc, fg->xcolor.pixel);
 	/* FIXME: maybe too much calculation in draw function - move to
@@ -162,7 +162,7 @@ ltk_scrollbar_draw(ltk_widget *self, ltk_rect clip) {
 	}
 	if (handle_w <= 0 || handle_h <= 0)
 		return;
-	XFillRectangle(window->dpy, window->xwindow, window->gc,
+	XFillRectangle(window->dpy, window->drawable, window->gc,
 	    handle_x, handle_y, handle_w, handle_h);
 }
 
diff --git a/src/scrollbar.h b/src/scrollbar.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2021 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
diff --git a/src/strtonum.c b/src/strtonum.c
@@ -4,7 +4,7 @@
  * Copyright (c) 2004 Ted Unangst and Todd Miller
  * All rights reserved.
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
diff --git a/src/text.h b/src/text.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2021 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
diff --git a/src/text_pango.c b/src/text_pango.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2021 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
@@ -85,6 +85,7 @@ ltk_text_line_set_width(ltk_text_line *tl, int width) {
 	}
 	XWindowAttributes attrs;
 	XGetWindowAttributes(tm.dpy, tl->window, &attrs);
+	/* FIXME: use visual from ltk_window */
 	tl->pixmap = XCreatePixmap(tm.dpy, tl->window, tl->w, tl->h, attrs.depth);
 	tl->draw = XftDrawCreate(tm.dpy, tl->pixmap, DefaultVisual(tm.dpy, tm.screen), tm.cm);
 }
diff --git a/src/text_stb.c b/src/text_stb.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2017, 2018, 2020 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
diff --git a/src/util.c b/src/util.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2021 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
@@ -27,6 +27,7 @@
 #include "memory.h"
 
 /* FIXME: Should these functions really fail on memory error? */
+/* FIXME: *len should be long, not unsigned long! */
 char *
 ltk_read_file(const char *path, unsigned long *len) {
 	FILE *f;
diff --git a/src/util.h b/src/util.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2021 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
diff --git a/src/widget.c b/src/widget.c
@@ -1,8 +1,10 @@
+/* FIXME: pixmap cache */
+/* FIXME: store coordinates relative to parent widget */
 /* FIXME: Destroy function for widget to destroy pixmap! */
 /*
  * Copyright (c) 2021 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
@@ -19,6 +21,7 @@
 
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
+#include <stdint.h>
 
 #include "rect.h"
 #include "widget.h"
@@ -71,7 +74,7 @@ ltk_fill_widget_defaults(ltk_widget *widget, const char *id, ltk_window *window,
 	widget->pix_w = w;
 	widget->pix_h = h;
 	if (vtable->needs_pixmap)
-		widget->pixmap = XCreatePixmap(window->dpy, window->xwindow, w, h, window->depth);
+		widget->pixmap = XCreatePixmap(window->dpy, window->drawable, w, h, window->depth);
 
 	/* FIXME: possibly check that draw and destroy aren't NULL */
 	widget->vtable = vtable;
@@ -111,7 +114,7 @@ ltk_widget_resize(ltk_widget *widget) {
 	if (new_w == pw && new_h == ph)
 		return;
 	XFreePixmap(w->dpy, widget->pixmap);
-	widget->pixmap = XCreatePixmap(w->dpy, w->xwindow, new_w, new_h, w->depth);
+	widget->pixmap = XCreatePixmap(w->dpy, w->drawable, new_w, new_h, w->depth);
 	widget->dirty = 1;
 }
 
diff --git a/src/widget.h b/src/widget.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2021 lumidify <nobody@lumidify.org>
  *
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *