URI: 
       tAdd double buffering - ltk - Socket-based GUI for X11 (WIP)
  HTML git clone git://lumidify.org/ltk.git (fast, but not encrypted)
  HTML git clone https://lumidify.org/git/ltk.git (encrypted, but very slow)
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit adc45f7ba5398d573a017db1a1b7c9044d3a3455
   DIR parent 5295095706d12ad5306360f812a51d46f023c86e
  HTML Author: lumidify <nobody@lumidify.org>
       Date:   Sun, 26 Dec 2021 11:02:45 +0100
       
       Add double buffering
       
       Diffstat:
         M LICENSE                             |       2 +-
         M Makefile                            |       4 ++--
         M TODO                                |       1 +
         M src/box.c                           |       2 +-
         M src/box.h                           |       2 +-
         M src/button.c                        |       2 +-
         M src/button.h                        |       2 +-
         M src/color.c                         |       2 +-
         M src/color.h                         |       2 +-
         M src/draw.c                          |      16 ++++++++--------
         M src/draw.h                          |       2 +-
         M src/graphics.c                      |       5 +++--
         M src/graphics.h                      |       2 +-
         M src/grid.c                          |       2 +-
         M src/grid.h                          |       2 +-
         M src/label.c                         |       2 +-
         M src/label.h                         |       2 +-
         M src/ltk.h                           |       6 +++++-
         M src/ltkc.c                          |       2 +-
         M src/ltkd.c                          |      96 ++++++++++++++++++++++++++------
         M src/memory.c                        |       2 +-
         M src/memory.h                        |       2 +-
         M src/rect.c                          |       2 +-
         M src/rect.h                          |       2 +-
         M src/scrollbar.c                     |       6 +++---
         M src/scrollbar.h                     |       2 +-
         M src/strtonum.c                      |       2 +-
         M src/text.h                          |       2 +-
         M src/text_pango.c                    |       3 ++-
         M src/text_stb.c                      |       2 +-
         M src/util.c                          |       3 ++-
         M src/util.h                          |       2 +-
         M src/widget.c                        |       9 ++++++---
         M src/widget.h                        |       2 +-
       
       34 files changed, 136 insertions(+), 61 deletions(-)
       ---
   DIR diff --git a/LICENSE b/LICENSE
       t@@ -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.
        
   DIR diff --git a/Makefile b/Makefile
       t@@ -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
        
   DIR diff --git a/TODO b/TODO
       t@@ -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)
   DIR diff --git a/src/box.c b/src/box.c
       t@@ -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.
         *
   DIR diff --git a/src/box.h b/src/box.h
       t@@ -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.
         *
   DIR diff --git a/src/button.c b/src/button.c
       t@@ -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.
         *
   DIR diff --git a/src/button.h b/src/button.h
       t@@ -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.
         *
   DIR diff --git a/src/color.c b/src/color.c
       t@@ -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.
         *
   DIR diff --git a/src/color.h b/src/color.h
       t@@ -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.
         *
   DIR diff --git a/src/draw.c b/src/draw.c
       t@@ -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.
         *
       t@@ -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);
        }
        
        
       t@@ -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");
       t@@ -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);
       t@@ -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);
        }
        
       t@@ -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
       t@@ -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);
                }
        }
        
   DIR diff --git a/src/draw.h b/src/draw.h
       t@@ -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.
         *
   DIR diff --git a/src/graphics.c b/src/graphics.c
       t@@ -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.
         *
       t@@ -16,6 +16,7 @@
        
        #include <X11/Xlib.h>
        #include <X11/Xutil.h>
       +#include <stdint.h>
        
        #include "color.h"
        #include "rect.h"
       t@@ -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
                );
   DIR diff --git a/src/graphics.h b/src/graphics.h
       t@@ -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.
         *
   DIR diff --git a/src/grid.c b/src/grid.c
       t@@ -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.
         *
   DIR diff --git a/src/grid.h b/src/grid.h
       t@@ -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.
         *
   DIR diff --git a/src/label.c b/src/label.c
       t@@ -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.
         *
   DIR diff --git a/src/label.h b/src/label.h
       t@@ -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.
         *
   DIR diff --git a/src/ltk.h b/src/ltk.h
       t@@ -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.
         *
       t@@ -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,
       t@@ -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;
   DIR diff --git a/src/ltkc.c b/src/ltkc.c
       t@@ -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.
         *
   DIR diff --git a/src/ltkd.c b/src/ltkd.c
       t@@ -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.
         *
       t@@ -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
       t@@ -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");
       t@@ -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;
       t@@ -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;
        }
   DIR diff --git a/src/memory.c b/src/memory.c
       t@@ -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.
         *
   DIR diff --git a/src/memory.h b/src/memory.h
       t@@ -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.
         *
   DIR diff --git a/src/rect.c b/src/rect.c
       t@@ -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.
         *
   DIR diff --git a/src/rect.h b/src/rect.h
       t@@ -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.
         *
   DIR diff --git a/src/scrollbar.c b/src/scrollbar.c
       t@@ -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.
         *
       t@@ -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
       t@@ -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);
        }
        
   DIR diff --git a/src/scrollbar.h b/src/scrollbar.h
       t@@ -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.
         *
   DIR diff --git a/src/strtonum.c b/src/strtonum.c
       t@@ -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.
         *
   DIR diff --git a/src/text.h b/src/text.h
       t@@ -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.
         *
   DIR diff --git a/src/text_pango.c b/src/text_pango.c
       t@@ -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.
         *
       t@@ -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);
        }
   DIR diff --git a/src/text_stb.c b/src/text_stb.c
       t@@ -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.
         *
   DIR diff --git a/src/util.c b/src/util.c
       t@@ -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.
         *
       t@@ -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;
   DIR diff --git a/src/util.h b/src/util.h
       t@@ -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.
         *
   DIR diff --git a/src/widget.c b/src/widget.c
       t@@ -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.
         *
       t@@ -19,6 +21,7 @@
        
        #include <X11/Xlib.h>
        #include <X11/Xutil.h>
       +#include <stdint.h>
        
        #include "rect.h"
        #include "widget.h"
       t@@ -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;
       t@@ -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;
        }
        
   DIR diff --git a/src/widget.h b/src/widget.h
       t@@ -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.
         *