diff --git a/Makefile b/Makefile index eb579e4..e965595 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ INCS = `$(PKG_CONFIG) --cflags $(PKGS)` LIBS = `$(PKG_CONFIG) --libs $(PKGS)` # flags -EMCPPFLAGS = -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" +EMCPPFLAGS = -D_POSIX_C_SOURCE=200809L -D_GNU_SOURCE -DVERSION=\"$(VERSION)\" EMCFLAGS = -pedantic -Wall $(INCS) $(EMCPPFLAGS) $(CFLAGS) LDLIBS = $(LIBS) diff --git a/drwl.h b/drwl.h index 61fad24..92a3fbb 100644 --- a/drwl.h +++ b/drwl.h @@ -48,8 +48,6 @@ typedef struct { #define UTF8_INVALID 0xFFFD static const uint8_t utf8d[] = { - // The first part of the table maps bytes to character classes that - // to reduce the size of the transition table and create bitmasks. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -59,8 +57,6 @@ static const uint8_t utf8d[] = { 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, - // The second part is a transition table that maps a combination - // of a state of the automaton and a character class to a state. 0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12, 12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12, 12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12, @@ -88,10 +84,6 @@ drwl_init(void) return fcft_init(FCFT_LOG_COLORIZE_AUTO, 0, FCFT_LOG_CLASS_ERROR); } -/* - * Caller must call drwl_init before drwl_create, and - * drwl_destroy on returned context after finalizing usage. - */ static Drwl * drwl_create(void) { @@ -110,11 +102,6 @@ drwl_setfont(Drwl *drwl, Fnt *font) drwl->font = font; } -/* - * Returned font is set within the drawing context if given. - * Caller must call drwl_font_destroy on returned font when done using it, - * otherwise use drwl_destroy when instead given a drawing context. - */ static Fnt * drwl_font_create(Drwl *drwl, size_t count, const char *names[static count], const char *attributes) @@ -155,10 +142,6 @@ drwl_stride(unsigned int width) return (((PIXMAN_FORMAT_BPP(PIXMAN_a8r8g8b8) * width + 7) / 8 + 4 - 1) & -4); } -/* - * Caller must call drwl_finish_drawing when finished drawing. - * Parameter stride can be calculated using drwl_stride. - */ static void drwl_prepare_drawing(Drwl *drwl, unsigned int w, unsigned int h, uint32_t *bits, int stride) @@ -209,7 +192,7 @@ drwl_text(Drwl *drwl, pixman_color_t clr; pixman_image_t *fg_pix = NULL; int noellipsis = 0; - const struct fcft_glyph *glyph, *eg; + const struct fcft_glyph *glyph, *eg = NULL; int fcft_subpixel_mode = FCFT_SUBPIXEL_DEFAULT; if (!drwl || (render && (!drwl->scheme || !w || !drwl->pix)) || !text || !drwl->font) @@ -230,12 +213,13 @@ drwl_text(Drwl *drwl, if (render && (drwl->scheme[ColBg] & 0xFF) != 0xFF) fcft_subpixel_mode = FCFT_SUBPIXEL_NONE; - // U+2026 == … if (render) - eg = fcft_rasterize_char_utf32(drwl->font, 0x2026, fcft_subpixel_mode); + eg = fcft_rasterize_char_utf32(drwl->font, 0x2026 /* … */, fcft_subpixel_mode); for (const char *p = text, *pp; pp = p, *p; p++) { - for (state = UTF8_ACCEPT; *p && utf8decode(&state, &cp, *p) > UTF8_REJECT; p++); + for (state = UTF8_ACCEPT; *p && + utf8decode(&state, &cp, *p) > UTF8_REJECT; p++) + ; if (!*p || state == UTF8_REJECT) { cp = UTF8_INVALID; if (p > pp) @@ -253,8 +237,9 @@ drwl_text(Drwl *drwl, ty = y + (h - drwl->font->height) / 2 + drwl->font->ascent; - if (render && !noellipsis && x_kern + glyph->advance.x + eg->advance.x > w && *(p + 1) != '\0') { - // cannot fit ellipsis after current codepoint + if (render && !noellipsis && x_kern + glyph->advance.x + eg->advance.x > w && + *(p + 1) != '\0') { + /* cannot fit ellipsis after current codepoint */ if (drwl_text(drwl, 0, 0, 0, 0, 0, pp, 0) + x_kern <= w) { noellipsis = 1; } else { @@ -271,7 +256,7 @@ drwl_text(Drwl *drwl, x += x_kern; if (render && pixman_image_get_format(glyph->pix) == PIXMAN_a8r8g8b8) - // pre-rendered glyphs (eg. emoji) + /* pre-rendered glyphs (eg. emoji) */ pixman_image_composite32( PIXMAN_OP_OVER, glyph->pix, NULL, drwl->pix, 0, 0, 0, 0, x + glyph->x, ty - glyph->y, glyph->width, glyph->height); diff --git a/mew.c b/mew.c index 4aab9bf..dd9f593 100644 --- a/mew.c +++ b/mew.c @@ -272,10 +272,11 @@ drawmenu(void) { unsigned int curpos; struct item *item; - int x = 0, y = 0, w; + int x = 0, y = 0, w, stride; PoolBuf *buf; - if (!(buf = poolbuf_create(shm, mw, mh, 0))) + stride = drwl_stride(mw); + if (!(buf = poolbuf_create(shm, mw, mh, stride, 0))) die("poolbuf_create:"); drwl_prepare_drawing(drw, mw, mh, buf->data, buf->stride); diff --git a/poolbuf.h b/poolbuf.h index c057122..4cf3807 100644 --- a/poolbuf.h +++ b/poolbuf.h @@ -22,14 +22,16 @@ * 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 #include #include #include #include #include #include - -#include "drwl.h" +#ifdef __linux__ +#include +#endif typedef struct { struct wl_buffer *wl_buf; @@ -38,44 +40,6 @@ typedef struct { void *data; } PoolBuf; -#if defined(__linux__) || defined(___FreeBSD__) -#ifdef __linux__ -#include -#endif -#define __POOLBUF_HAS_MEMFD_CREATE -int memfd_create(const char *, unsigned); -#else -static void -randname(char *buf) -{ - struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - long r = ts.tv_nsec; - for (int i = 0; i < 6; ++i) { - buf[i] = 'A'+(r&15)+(r&16)*2; - r >>= 5; - } -} - -static int -create_shm(void) -{ - char name[] = "/drwl-XXXXXX"; - int retries = 100; - - do { - randname(name + sizeof(name) - 7); - --retries; - int fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0600); - if (fd >= 0) { - shm_unlink(name); - return fd; - } - } while (retries > 0 && errno == EEXIST); - return -1; -} -#endif - static void poolbuf_destroy(PoolBuf *buf) { @@ -95,23 +59,35 @@ static struct wl_buffer_listener poolbuf_buffer_listener = { .release = poolbuf_buffer_release, }; -/* Caller must call poolbuf_destroy after finalizing usage if norelease is passed */ static PoolBuf * -poolbuf_create(struct wl_shm *shm, int32_t width, int32_t height, int norelease) +poolbuf_create(struct wl_shm *shm, + int32_t width, int32_t height, int32_t stride, int norelease) { int fd; void *data; struct wl_shm_pool *shm_pool; struct wl_buffer *wl_buf; - int32_t stride = drwl_stride(width); int32_t size = stride * height; PoolBuf *buf; -#ifdef __POOLBUF_HAS_MEMFD_CREATE - fd = memfd_create("drwl-shm-buffer-pool", - MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_NOEXEC_SEAL); +#if defined(__linux__) || \ + ((defined(__FreeBSD__) && (__FreeBSD_version >= 1300048))) + fd = memfd_create("poolbuf-shm-buffer-pool", + MFD_CLOEXEC | MFD_ALLOW_SEALING | +#if defined(MFD_NOEXEC_SEAL) + MFD_NOEXEC_SEAL #else - fd = create_shm(); + 0 +#endif + ); +#else + char template[] = "/tmp/poolbuf-XXXXXX"; +#if defined(__OpenBSD__) + fd = shm_mkstemp(template); +#else + fd = mkostemp(template, O_CLOEXEC); +#endif + unlink(template); #endif if (fd < 0) return NULL; @@ -121,8 +97,7 @@ poolbuf_create(struct wl_shm *shm, int32_t width, int32_t height, int norelease) return NULL; } - data = mmap(NULL, size, - PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (data == MAP_FAILED) { close(fd); return NULL; @@ -130,7 +105,7 @@ poolbuf_create(struct wl_shm *shm, int32_t width, int32_t height, int norelease) shm_pool = wl_shm_create_pool(shm, fd, size); wl_buf = wl_shm_pool_create_buffer(shm_pool, 0, - width, height, stride, WL_SHM_FORMAT_ARGB8888); + width, height, stride, WL_SHM_FORMAT_ARGB8888); wl_shm_pool_destroy(shm_pool); close(fd);