summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.def.h20
-rw-r--r--config.def.h.orig4
-rw-r--r--config.h36
-rw-r--r--config.mk2
-rw-r--r--config.mk.orig31
-rw-r--r--diffs/dmenu-border-20201112-1a13d04.diff50
-rw-r--r--diffs/dmenu-caseinsensitive-20200523-db6093f.diff42
-rw-r--r--diffs/dmenu-fuzzyhighlight-4.9.diff152
-rw-r--r--diffs/dmenu-lineheight-5.0.diff106
-rw-r--r--diffs/dmenu-morecolor-20190922-4bf895b.diff47
-rwxr-xr-xdmenubin43080 -> 43288 bytes
-rw-r--r--dmenu.c72
-rw-r--r--dmenu.c.orig44
-rw-r--r--dmenu.obin37344 -> 38512 bytes
-rw-r--r--drw.c26
-rw-r--r--drw.c.orig436
-rw-r--r--drw.h9
-rw-r--r--drw.h.orig57
-rw-r--r--drw.obin10544 -> 10560 bytes
-rwxr-xr-xstestbin16408 -> 16408 bytes
20 files changed, 672 insertions, 462 deletions
diff --git a/config.def.h b/config.def.h
index f49c9d3..37a5b96 100644
--- a/config.def.h
+++ b/config.def.h
@@ -1,9 +1,10 @@
/* See LICENSE file for copyright and license details. */
/* Default settings; can be overriden by command line. */
+static const unsigned int alpha = 0x80; /* Amount of opacity. 0xff is opaque */
static int topbar = 0; /* -b option; if 0, dmenu appears at bottom */
static int centered = 1; /* -c option; centers dmenu on screen */
-static int min_width = 600; /* minimum width when centered */
+static int min_width = 500; /* minimum width when centered */
/* -fn option overrides fonts[0]; default X11 font or font set */
static const char *fonts[] = {
"Sauce Code Pro:size=11"
@@ -11,18 +12,29 @@ static const char *fonts[] = {
static const char *prompt = "RUN: ";//NULL; /* -p option; prompt to the left of input field */
static const char *colors[SchemeLast][2] = {
/* fg bg */
- [SchemeNorm] = { "#cccccc", "#282c34" },
+ //[SchemeNorm] = { "#cccccc", "#282c34" },
+ [SchemeNorm] = { "#cccccc", "#0e0911" },
[SchemeSel] = { "#1c1f24", "#c678dd" },
[SchemeSelHighlight] = { "#000000", "#51afef" },
[SchemeNormHighlight] = { "#000000", "#51afef" },
//[SchemeMid] = { "#000000", "#51afef" },
- [SchemeMid] = { "#cccccc", "#282c34" },
+ //[SchemeMid] = { "#cccccc", "#282c34" },
+ [SchemeMid] = { "#cccccc", "#0e0911" },
[SchemeOut] = { "#d7d7d7", "#1c1f24" },
};
+static const unsigned int alphas[SchemeLast][2] = {
+ [SchemeNorm] = { OPAQUE, alpha },
+ [SchemeSel] = { OPAQUE, OPAQUE },
+ [SchemeSelHighlight] = { OPAQUE, OPAQUE },
+ [SchemeNormHighlight] = { OPAQUE, OPAQUE },
+ [SchemeMid] = { OPAQUE, OPAQUE },
+ [SchemeOut] = { OPAQUE, OPAQUE },
+};
+
/* -l option; if nonzero, dmenu uses vertical list with given number of lines */
static unsigned int lines = 12;
-static unsigned int columns = 3;
+static unsigned int columns = 1;
/* -h option; minimum height of a menu line */
static unsigned int lineheight = 24;
static unsigned int min_lineheight = 24;
diff --git a/config.def.h.orig b/config.def.h.orig
index f79f09d..f49c9d3 100644
--- a/config.def.h.orig
+++ b/config.def.h.orig
@@ -3,7 +3,7 @@
static int topbar = 0; /* -b option; if 0, dmenu appears at bottom */
static int centered = 1; /* -c option; centers dmenu on screen */
-static int min_width = 400; /* minimum width when centered */
+static int min_width = 600; /* minimum width when centered */
/* -fn option overrides fonts[0]; default X11 font or font set */
static const char *fonts[] = {
"Sauce Code Pro:size=11"
@@ -22,10 +22,10 @@ static const char *colors[SchemeLast][2] = {
/* -l option; if nonzero, dmenu uses vertical list with given number of lines */
static unsigned int lines = 12;
+static unsigned int columns = 3;
/* -h option; minimum height of a menu line */
static unsigned int lineheight = 24;
static unsigned int min_lineheight = 24;
-
/*
* Characters not considered part of a word while deleting words
* for example: " /?\"&[]"
diff --git a/config.h b/config.h
deleted file mode 100644
index f49c9d3..0000000
--- a/config.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-/* Default settings; can be overriden by command line. */
-
-static int topbar = 0; /* -b option; if 0, dmenu appears at bottom */
-static int centered = 1; /* -c option; centers dmenu on screen */
-static int min_width = 600; /* minimum width when centered */
-/* -fn option overrides fonts[0]; default X11 font or font set */
-static const char *fonts[] = {
- "Sauce Code Pro:size=11"
-};
-static const char *prompt = "RUN: ";//NULL; /* -p option; prompt to the left of input field */
-static const char *colors[SchemeLast][2] = {
- /* fg bg */
- [SchemeNorm] = { "#cccccc", "#282c34" },
- [SchemeSel] = { "#1c1f24", "#c678dd" },
- [SchemeSelHighlight] = { "#000000", "#51afef" },
- [SchemeNormHighlight] = { "#000000", "#51afef" },
- //[SchemeMid] = { "#000000", "#51afef" },
- [SchemeMid] = { "#cccccc", "#282c34" },
- [SchemeOut] = { "#d7d7d7", "#1c1f24" },
-};
-
-/* -l option; if nonzero, dmenu uses vertical list with given number of lines */
-static unsigned int lines = 12;
-static unsigned int columns = 3;
-/* -h option; minimum height of a menu line */
-static unsigned int lineheight = 24;
-static unsigned int min_lineheight = 24;
-/*
- * Characters not considered part of a word while deleting words
- * for example: " /?\"&[]"
- */
-static const char worddelimiters[] = " ";
-
-/* Size of the window border */
-static unsigned int border_width = 1;
diff --git a/config.mk b/config.mk
index 05d5a3e..8531fb9 100644
--- a/config.mk
+++ b/config.mk
@@ -20,7 +20,7 @@ FREETYPEINC = /usr/include/freetype2
# includes and libs
INCS = -I$(X11INC) -I$(FREETYPEINC)
-LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS)
+LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) -lXrender
# flags
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS)
diff --git a/config.mk.orig b/config.mk.orig
new file mode 100644
index 0000000..05d5a3e
--- /dev/null
+++ b/config.mk.orig
@@ -0,0 +1,31 @@
+# dmenu version
+VERSION = 5.0
+
+# paths
+PREFIX = /usr/local
+MANPREFIX = $(PREFIX)/share/man
+
+X11INC = /usr/X11R6/include
+X11LIB = /usr/X11R6/lib
+
+# Xinerama, comment if you don't want it
+XINERAMALIBS = -lXinerama
+XINERAMAFLAGS = -DXINERAMA
+
+# freetype
+FREETYPELIBS = -lfontconfig -lXft
+FREETYPEINC = /usr/include/freetype2
+# OpenBSD (uncomment)
+#FREETYPEINC = $(X11INC)/freetype2
+
+# includes and libs
+INCS = -I$(X11INC) -I$(FREETYPEINC)
+LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS)
+
+# flags
+CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS)
+CFLAGS = -std=c99 -pedantic -Wall -Os $(INCS) $(CPPFLAGS)
+LDFLAGS = $(LIBS)
+
+# compiler and linker
+CC = cc
diff --git a/diffs/dmenu-border-20201112-1a13d04.diff b/diffs/dmenu-border-20201112-1a13d04.diff
deleted file mode 100644
index bea0cee..0000000
--- a/diffs/dmenu-border-20201112-1a13d04.diff
+++ /dev/null
@@ -1,50 +0,0 @@
-From d0c3fc8a634c153856cd41438f705175a21ec69a Mon Sep 17 00:00:00 2001
-From: braskin <benjaminiraskin@gmail.com>
-Date: Thu, 12 Nov 2020 10:13:29 -0500
-Subject: [PATCH] fixed border width draw for topbar
-
----
- config.def.h | 3 +++
- dmenu.c | 6 +++++-
- 2 files changed, 8 insertions(+), 1 deletion(-)
-
-diff --git a/config.def.h b/config.def.h
-index 1edb647..dd3eb31 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -21,3 +21,6 @@ static unsigned int lines = 0;
- * for example: " /?\"&[]"
- */
- static const char worddelimiters[] = " ";
-+
-+/* Size of the window border */
-+static unsigned int border_width = 0;
-diff --git a/dmenu.c b/dmenu.c
-index 65f25ce..716e655 100644
---- a/dmenu.c
-+++ b/dmenu.c
-@@ -659,9 +659,11 @@ setup(void)
- swa.override_redirect = True;
- swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
- swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
-- win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
-+ win = XCreateWindow(dpy, parentwin, x, y - (topbar ? 0 : border_width * 2), mw - border_width * 2, mh, border_width,
- CopyFromParent, CopyFromParent, CopyFromParent,
- CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
-+ if (border_width)
-+ XSetWindowBorder(dpy, win, scheme[SchemeSel][ColBg].pixel);
- XSetClassHint(dpy, win, &ch);
-
-
-@@ -733,6 +735,8 @@ main(int argc, char *argv[])
- colors[SchemeSel][ColFg] = argv[++i];
- else if (!strcmp(argv[i], "-w")) /* embedding window id */
- embed = argv[++i];
-+ else if (!strcmp(argv[i], "-bw"))
-+ border_width = atoi(argv[++i]); /* border width */
- else
- usage();
-
---
-2.25.1
-
diff --git a/diffs/dmenu-caseinsensitive-20200523-db6093f.diff b/diffs/dmenu-caseinsensitive-20200523-db6093f.diff
deleted file mode 100644
index 939a2e8..0000000
--- a/diffs/dmenu-caseinsensitive-20200523-db6093f.diff
+++ /dev/null
@@ -1,42 +0,0 @@
-From 54acbdf72083a5eae5783eed42e162424ab2cec2 Mon Sep 17 00:00:00 2001
-From: Kim Torgersen <kim@torgersen.se>
-Date: Sat, 23 May 2020 14:48:28 +0200
-Subject: [PATCH] case-insensitive item matching default, case-sensitive option
- (-s)
-
----
- dmenu.c | 11 ++++++-----
- 1 file changed, 6 insertions(+), 5 deletions(-)
-
-diff --git a/dmenu.c b/dmenu.c
-index 65f25ce..855df59 100644
---- a/dmenu.c
-+++ b/dmenu.c
-@@ -55,8 +55,9 @@ static Clr *scheme[SchemeLast];
-
- #include "config.h"
-
--static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
--static char *(*fstrstr)(const char *, const char *) = strstr;
-+static char * cistrstr(const char *s, const char *sub);
-+static int (*fstrncmp)(const char *, const char *, size_t) = strncasecmp;
-+static char *(*fstrstr)(const char *, const char *) = cistrstr;
-
- static void
- appenditem(struct item *item, struct item **list, struct item **last)
-@@ -709,9 +710,9 @@ main(int argc, char *argv[])
- topbar = 0;
- else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */
- fast = 1;
-- else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
-- fstrncmp = strncasecmp;
-- fstrstr = cistrstr;
-+ else if (!strcmp(argv[i], "-s")) { /* case-sensitive item matching */
-+ fstrncmp = strncmp;
-+ fstrstr = strstr;
- } else if (i + 1 == argc)
- usage();
- /* these options take one argument */
---
-2.26.2
-
diff --git a/diffs/dmenu-fuzzyhighlight-4.9.diff b/diffs/dmenu-fuzzyhighlight-4.9.diff
deleted file mode 100644
index 58d5c6f..0000000
--- a/diffs/dmenu-fuzzyhighlight-4.9.diff
+++ /dev/null
@@ -1,152 +0,0 @@
-Author: Chris Noxz <chris@noxz.tech>
-note: This patch is meant to be used together with fuzzymatch
-
-diff -upN dmenu-4.9/config.def.h dmenu-4.9-fuzzyhighlight/config.def.h
---- dmenu-4.9/config.def.h 2019-02-02 13:55:02.000000000 +0100
-+++ dmenu-4.9-fuzzyhighlight/config.def.h 2020-04-04 10:26:36.990890854 +0200
-@@ -11,6 +11,8 @@ static const char *colors[SchemeLast][2]
- /* fg bg */
- [SchemeNorm] = { "#bbbbbb", "#222222" },
- [SchemeSel] = { "#eeeeee", "#005577" },
-+ [SchemeSelHighlight] = { "#ffc978", "#005577" },
-+ [SchemeNormHighlight] = { "#ffc978", "#222222" },
- [SchemeOut] = { "#000000", "#00ffff" },
- };
- /* -l option; if nonzero, dmenu uses vertical list with given number of lines */
-diff -upN dmenu-4.9/dmenu.1 dmenu-4.9-fuzzyhighlight/dmenu.1
---- dmenu-4.9/dmenu.1 2019-02-02 13:55:02.000000000 +0100
-+++ dmenu-4.9-fuzzyhighlight/dmenu.1 2020-04-04 10:30:16.430054933 +0200
-@@ -20,6 +20,14 @@ dmenu \- dynamic menu
- .IR color ]
- .RB [ \-sf
- .IR color ]
-+.RB [ \-nhb
-+.IR color ]
-+.RB [ \-nhf
-+.IR color ]
-+.RB [ \-shb
-+.IR color ]
-+.RB [ \-shf
-+.IR color ]
- .RB [ \-w
- .IR windowid ]
- .P
-@@ -75,6 +83,18 @@ defines the selected background color.
- .BI \-sf " color"
- defines the selected foreground color.
- .TP
-+.BI \-nhb " color"
-+defines the normal highlight background color.
-+.TP
-+.BI \-nhf " color"
-+defines the normal highlight foreground color.
-+.TP
-+.BI \-shb " color"
-+defines the selected highlight background color.
-+.TP
-+.BI \-shf " color"
-+defines the selected highlight foreground color.
-+.TP
- .B \-v
- prints version information to stdout, then exits.
- .TP
-diff -upN dmenu-4.9/dmenu.c dmenu-4.9-fuzzyhighlight/dmenu.c
---- dmenu-4.9/dmenu.c 2019-02-02 13:55:02.000000000 +0100
-+++ dmenu-4.9-fuzzyhighlight/dmenu.c 2020-04-04 10:27:43.888026309 +0200
-@@ -26,7 +26,9 @@
- #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
-
- /* enums */
--enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */
-+enum { SchemeNorm, SchemeSel, SchemeNormHighlight, SchemeSelHighlight,
-+ SchemeOut, SchemeLast }; /* color schemes */
-+
-
- struct item {
- char *text;
-@@ -113,9 +115,49 @@ cistrstr(const char *s, const char *sub)
- return NULL;
- }
-
-+static void
-+drawhighlights(struct item *item, int x, int y, int maxw)
-+{
-+ int i, indent;
-+ char *highlight;
-+ char c;
-+
-+ if (!(strlen(item->text) && strlen(text)))
-+ return;
-+
-+ drw_setscheme(drw, scheme[item == sel
-+ ? SchemeSelHighlight
-+ : SchemeNormHighlight]);
-+ for (i = 0, highlight = item->text; *highlight && text[i];) {
-+ if (*highlight == text[i]) {
-+ /* get indentation */
-+ c = *highlight;
-+ *highlight = '\0';
-+ indent = TEXTW(item->text);
-+ *highlight = c;
-+
-+ /* highlight character */
-+ c = highlight[1];
-+ highlight[1] = '\0';
-+ drw_text(
-+ drw,
-+ x + indent - (lrpad / 2),
-+ y,
-+ MIN(maxw - indent, TEXTW(highlight) - lrpad),
-+ bh, 0, highlight, 0
-+ );
-+ highlight[1] = c;
-+ i++;
-+ }
-+ highlight++;
-+ }
-+}
-+
-+
- static int
- drawitem(struct item *item, int x, int y, int w)
- {
-+ int r;
- if (item == sel)
- drw_setscheme(drw, scheme[SchemeSel]);
- else if (item->out)
-@@ -123,7 +165,9 @@ drawitem(struct item *item, int x, int y
- else
- drw_setscheme(drw, scheme[SchemeNorm]);
-
-- return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0);
-+ r = drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0);
-+ drawhighlights(item, x, y, w);
-+ return r;
- }
-
- static void
-@@ -683,7 +727,8 @@ static void
- usage(void)
- {
- fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
-- " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr);
-+ " [-nb color] [-nf color] [-sb color] [-sf color]\n"
-+ " [-nhb color] [-nhf color] [-shb color] [-shf color] [-w windowid]\n", stderr);
- exit(1);
- }
-
-@@ -724,6 +769,14 @@ main(int argc, char *argv[])
- colors[SchemeSel][ColBg] = argv[++i];
- else if (!strcmp(argv[i], "-sf")) /* selected foreground color */
- colors[SchemeSel][ColFg] = argv[++i];
-+ else if (!strcmp(argv[i], "-nhb")) /* normal hi background color */
-+ colors[SchemeNormHighlight][ColBg] = argv[++i];
-+ else if (!strcmp(argv[i], "-nhf")) /* normal hi foreground color */
-+ colors[SchemeNormHighlight][ColFg] = argv[++i];
-+ else if (!strcmp(argv[i], "-shb")) /* selected hi background color */
-+ colors[SchemeSelHighlight][ColBg] = argv[++i];
-+ else if (!strcmp(argv[i], "-shf")) /* selected hi foreground color */
-+ colors[SchemeSelHighlight][ColFg] = argv[++i];
- else if (!strcmp(argv[i], "-w")) /* embedding window id */
- embed = argv[++i];
- else
diff --git a/diffs/dmenu-lineheight-5.0.diff b/diffs/dmenu-lineheight-5.0.diff
deleted file mode 100644
index 3b0df3d..0000000
--- a/diffs/dmenu-lineheight-5.0.diff
+++ /dev/null
@@ -1,106 +0,0 @@
-From ba103e38ea4ab07f9a3ee90627714b9bea17c329 Mon Sep 17 00:00:00 2001
-From: pskry <peter@skrypalle.dk>
-Date: Sun, 8 Nov 2020 22:04:22 +0100
-Subject: [PATCH] Add an option which defines the lineheight
-
-Despite both the panel and dmenu using the same font (a Terminus 12),
-dmenu is shorter and the panel is visible from under the dmenu bar.
-The appearance can be even more distracting when using similar colors
-for background and selections. With the option added by this patch,
-dmenu can be launched with a '-h 24', thus completely covering the panel.
----
- config.def.h | 3 +++
- dmenu.1 | 5 +++++
- dmenu.c | 11 ++++++++---
- 3 files changed, 16 insertions(+), 3 deletions(-)
-
-diff --git a/config.def.h b/config.def.h
-index 1edb647..4394dec 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -15,6 +15,9 @@ static const char *colors[SchemeLast][2] = {
- };
- /* -l option; if nonzero, dmenu uses vertical list with given number of lines */
- static unsigned int lines = 0;
-+/* -h option; minimum height of a menu line */
-+static unsigned int lineheight = 0;
-+static unsigned int min_lineheight = 8;
-
- /*
- * Characters not considered part of a word while deleting words
-diff --git a/dmenu.1 b/dmenu.1
-index 323f93c..f2a82b4 100644
---- a/dmenu.1
-+++ b/dmenu.1
-@@ -6,6 +6,8 @@ dmenu \- dynamic menu
- .RB [ \-bfiv ]
- .RB [ \-l
- .IR lines ]
-+.RB [ \-h
-+.IR height ]
- .RB [ \-m
- .IR monitor ]
- .RB [ \-p
-@@ -50,6 +52,9 @@ dmenu matches menu items case insensitively.
- .BI \-l " lines"
- dmenu lists items vertically, with the given number of lines.
- .TP
-+.BI \-h " height"
-+dmenu uses a menu line of at least 'height' pixels tall, but no less than 8.
-+.TP
- .BI \-m " monitor"
- dmenu is displayed on the monitor number supplied. Monitor numbers are starting
- from 0.
-diff --git a/dmenu.c b/dmenu.c
-index 65f25ce..f2a4047 100644
---- a/dmenu.c
-+++ b/dmenu.c
-@@ -131,7 +131,7 @@ drawmenu(void)
- {
- unsigned int curpos;
- struct item *item;
-- int x = 0, y = 0, w;
-+ int x = 0, y = 0, fh = drw->fonts->h, w;
-
- drw_setscheme(drw, scheme[SchemeNorm]);
- drw_rect(drw, 0, 0, mw, mh, 1, 1);
-@@ -148,7 +148,7 @@ drawmenu(void)
- curpos = TEXTW(text) - TEXTW(&text[cursor]);
- if ((curpos += lrpad / 2 - 1) < w) {
- drw_setscheme(drw, scheme[SchemeNorm]);
-- drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0);
-+ drw_rect(drw, x + curpos, 2 + (bh - fh) / 2, 2, fh - 4, 1, 0);
- }
-
- if (lines > 0) {
-@@ -609,6 +609,7 @@ setup(void)
-
- /* calculate menu geometry */
- bh = drw->fonts->h + 2;
-+ bh = MAX(bh,lineheight); /* make a menu line AT LEAST 'lineheight' tall */
- lines = MAX(lines, 0);
- mh = (lines + 1) * bh;
- #ifdef XINERAMA
-@@ -689,7 +690,7 @@ setup(void)
- static void
- usage(void)
- {
-- fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
-+ fputs("usage: dmenu [-bfiv] [-l lines] [-h height] [-p prompt] [-fn font] [-m monitor]\n"
- " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr);
- exit(1);
- }
-@@ -717,6 +718,10 @@ main(int argc, char *argv[])
- /* these options take one argument */
- else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */
- lines = atoi(argv[++i]);
-+ else if (!strcmp(argv[i], "-h")) { /* minimum height of one menu line */
-+ lineheight = atoi(argv[++i]);
-+ lineheight = MAX(lineheight, min_lineheight);
-+ }
- else if (!strcmp(argv[i], "-m"))
- mon = atoi(argv[++i]);
- else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */
---
-2.29.2
-
diff --git a/diffs/dmenu-morecolor-20190922-4bf895b.diff b/diffs/dmenu-morecolor-20190922-4bf895b.diff
deleted file mode 100644
index 539e9c1..0000000
--- a/diffs/dmenu-morecolor-20190922-4bf895b.diff
+++ /dev/null
@@ -1,47 +0,0 @@
-From 4bf895be219ae00394a5cde901dc43ec6dcb3759 Mon Sep 17 00:00:00 2001
-From: Tanner Babcock <babkock@gmail.com>
-Date: Sun, 22 Sep 2019 03:07:26 -0500
-Subject: [PATCH] Additional color scheme, for adjacent entries
-
----
- config.def.h | 1 +
- dmenu.c | 4 +++-
- 2 files changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/config.def.h b/config.def.h
-index 1edb647..767c88f 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -12,6 +12,7 @@ static const char *colors[SchemeLast][2] = {
- [SchemeNorm] = { "#bbbbbb", "#222222" },
- [SchemeSel] = { "#eeeeee", "#005577" },
- [SchemeOut] = { "#000000", "#00ffff" },
-+ [SchemeMid] = { "#eeeeee", "#770000" },
- };
- /* -l option; if nonzero, dmenu uses vertical list with given number of lines */
- static unsigned int lines = 0;
-diff --git a/dmenu.c b/dmenu.c
-index 65f25ce..0a5c08d 100644
---- a/dmenu.c
-+++ b/dmenu.c
-@@ -26,7 +26,7 @@
- #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
-
- /* enums */
--enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */
-+enum { SchemeNorm, SchemeSel, SchemeOut, SchemeMid, SchemeLast }; /* color schemes */
-
- struct item {
- char *text;
-@@ -118,6 +118,8 @@ drawitem(struct item *item, int x, int y, int w)
- {
- if (item == sel)
- drw_setscheme(drw, scheme[SchemeSel]);
-+ else if (item->left == sel || item->right == sel)
-+ drw_setscheme(drw, scheme[SchemeMid]);
- else if (item->out)
- drw_setscheme(drw, scheme[SchemeOut]);
- else
---
-2.23.0
-
diff --git a/dmenu b/dmenu
index d979fa7..e14245a 100755
--- a/dmenu
+++ b/dmenu
Binary files differ
diff --git a/dmenu.c b/dmenu.c
index 0757615..0b4d7d6 100644
--- a/dmenu.c
+++ b/dmenu.c
@@ -10,10 +10,12 @@
#include <X11/Xlib.h>
#include <X11/Xatom.h>
+#include <X11/Xproto.h>
#include <X11/Xutil.h>
#ifdef XINERAMA
#include <X11/extensions/Xinerama.h>
#endif
+#include <X11/extensions/Xrender.h>
#include <X11/Xft/Xft.h>
#include "drw.h"
@@ -25,6 +27,8 @@
#define LENGTH(X) (sizeof X / sizeof X[0])
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
+#define OPAQUE 0xffu
+
/* enums */
// <<<<<<<
enum { SchemeNorm, SchemeSel, SchemeNormHighlight, SchemeSelHighlight,
@@ -59,11 +63,22 @@ static XIC xic;
static Drw *drw;
static Clr *scheme[SchemeLast];
+static int useargb = 0;
+static Visual *visual;
+static int depth;
+static Colormap cmap;
+
#include "config.h"
+//<<<<<<<
static char * cistrstr(const char *s, const char *sub);
-static int (*fstrncmp)(const char *, const char *, size_t) = strncasecmp;
-static char *(*fstrstr)(const char *, const char *) = cistrstr;
+//static int (*fstrncmp)(const char *, const char *, size_t) = strncasecmp;
+//static char *(*fstrstr)(const char *, const char *) = cistrstr;
+//=======
+static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
+static char *(*fstrstr)(const char *, const char *) = strstr;
+static void xinitvisual();
+//>>>>>>>
static void
appenditem(struct item *item, struct item **list, struct item **last)
@@ -712,7 +727,7 @@ setup(void)
#endif
/* init appearance */
for (j = 0; j < SchemeLast; j++)
- scheme[j] = drw_scm_create(drw, colors[j], 2);
+ scheme[j] = drw_scm_create(drw, colors[j], alphas[i], 2);
clip = XInternAtom(dpy, "CLIPBOARD", False);
utf8 = XInternAtom(dpy, "UTF8_STRING", False);
@@ -782,11 +797,16 @@ setup(void)
/* create menu window */
swa.override_redirect = True;
- swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
+ swa.background_pixel = 0;
+ swa.border_pixel = 0;
+ swa.colormap = cmap;
swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
win = XCreateWindow(dpy, parentwin, x, y - (topbar ? 0 : border_width * 2), mw - border_width * 2, mh, border_width,
- CopyFromParent, CopyFromParent, CopyFromParent,
- CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
+ //CopyFromParent, CopyFromParent, CopyFromParent,
+ depth, CopyFromParent, visual,
+ //CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
+ CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWColormap | CWEventMask, &swa);
+// win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
if (border_width)
XSetWindowBorder(dpy, win, scheme[SchemeSel][ColBg].pixel);
XSetClassHint(dpy, win, &ch);
@@ -900,7 +920,8 @@ main(int argc, char *argv[])
if (!XGetWindowAttributes(dpy, parentwin, &wa))
die("could not get embedding window attributes: 0x%lx",
parentwin);
- drw = drw_create(dpy, screen, root, wa.width, wa.height);
+ xinitvisual();
+ drw = drw_create(dpy, screen, root, wa.width, wa.height, visual, depth, cmap);
if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
die("no fonts could be loaded.");
lrpad = drw->fonts->h;
@@ -922,3 +943,40 @@ main(int argc, char *argv[])
return 1; /* unreachable */
}
+
+void
+xinitvisual()
+{
+ XVisualInfo *infos;
+ XRenderPictFormat *fmt;
+ int nitems;
+ int i;
+
+ XVisualInfo tpl = {
+ .screen = screen,
+ .depth = 32,
+ .class = TrueColor
+ };
+ long masks = VisualScreenMask | VisualDepthMask | VisualClassMask;
+
+ infos = XGetVisualInfo(dpy, masks, &tpl, &nitems);
+ visual = NULL;
+ for(i = 0; i < nitems; i ++) {
+ fmt = XRenderFindVisualFormat(dpy, infos[i].visual);
+ if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) {
+ visual = infos[i].visual;
+ depth = infos[i].depth;
+ cmap = XCreateColormap(dpy, root, visual, AllocNone);
+ useargb = 1;
+ break;
+ }
+ }
+
+ XFree(infos);
+
+ if (! visual) {
+ visual = DefaultVisual(dpy, screen);
+ depth = DefaultDepth(dpy, screen);
+ cmap = DefaultColormap(dpy, screen);
+ }
+}
diff --git a/dmenu.c.orig b/dmenu.c.orig
index 69a5e07..0757615 100644
--- a/dmenu.c.orig
+++ b/dmenu.c.orig
@@ -377,6 +377,8 @@ keypress(XKeyEvent *ev)
int len;
KeySym ksym;
Status status;
+ int i, offscreen = 0;
+ struct item *tmpsel;
len = XmbLookupString(xic, ev, buf, sizeof buf, &ksym, &status);
switch (status) {
@@ -503,6 +505,27 @@ insert:
calcoffsets();
break;
case XK_Left:
+ if (columns > 1) {
+ if (!sel)
+ return;
+ tmpsel = sel;
+ for (i = 0; i < lines; i++) {
+ if (!tmpsel->left || tmpsel->left->right != tmpsel) {
+ if (offscreen)
+ break;
+ return;
+ }
+ if (tmpsel == curr)
+ offscreen = 1;
+ tmpsel = tmpsel->left;
+ }
+ sel = tmpsel;
+ if (offscreen) {
+ curr = prev;
+ calcoffsets();
+ }
+ break;
+ }
if (cursor > 0 && (!sel || !sel->left || lines > 0)) {
cursor = nextrune(-1);
break;
@@ -539,6 +562,27 @@ insert:
sel->out = 1;
break;
case XK_Right:
+ if (columns > 1) {
+ if (!sel)
+ return;
+ tmpsel = sel;
+ for (i = 0; i < lines; i++) {
+ if (!tmpsel->right || tmpsel->right->left != tmpsel) {
+ if (offscreen)
+ break;
+ return;
+ }
+ tmpsel = tmpsel->right;
+ if (tmpsel == next)
+ offscreen = 1;
+ }
+ sel = tmpsel;
+ if (offscreen) {
+ curr = next;
+ calcoffsets();
+ }
+ break;
+ }
if (text[cursor] != '\0') {
cursor = nextrune(+1);
break;
diff --git a/dmenu.o b/dmenu.o
index f43df1e..2706d40 100644
--- a/dmenu.o
+++ b/dmenu.o
Binary files differ
diff --git a/drw.c b/drw.c
index 4cdbcbe..fe3aadd 100644
--- a/drw.c
+++ b/drw.c
@@ -61,7 +61,7 @@ utf8decode(const char *c, long *u, size_t clen)
}
Drw *
-drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
+drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap)
{
Drw *drw = ecalloc(1, sizeof(Drw));
@@ -70,8 +70,11 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h
drw->root = root;
drw->w = w;
drw->h = h;
- drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
- drw->gc = XCreateGC(dpy, root, 0, NULL);
+ drw->visual = visual;
+ drw->depth = depth;
+ drw->cmap = cmap;
+ drw->drawable = XCreatePixmap(dpy, root, w, h, depth);
+ drw->gc = XCreateGC(dpy, drw->drawable, 0, NULL);
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
return drw;
@@ -87,7 +90,7 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h)
drw->h = h;
if (drw->drawable)
XFreePixmap(drw->dpy, drw->drawable);
- drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
+ drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, drw->depth);
}
void
@@ -194,21 +197,22 @@ drw_fontset_free(Fnt *font)
}
void
-drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
+drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha)
{
if (!drw || !dest || !clrname)
return;
- if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
- DefaultColormap(drw->dpy, drw->screen),
+ if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap,
clrname, dest))
die("error, cannot allocate color '%s'", clrname);
+
+ dest->pixel = (dest->pixel & 0x00ffffffU) | (alpha << 24);
}
/* Wrapper to create color schemes. The caller has to call free(3) on the
* returned color scheme when done using it. */
Clr *
-drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
+drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount)
{
size_t i;
Clr *ret;
@@ -218,7 +222,7 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
return NULL;
for (i = 0; i < clrcount; i++)
- drw_clr_create(drw, &ret[i], clrnames[i]);
+ drw_clr_create(drw, &ret[i], clrnames[i], alphas[i]);
return ret;
}
@@ -274,9 +278,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
} else {
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
- d = XftDrawCreate(drw->dpy, drw->drawable,
- DefaultVisual(drw->dpy, drw->screen),
- DefaultColormap(drw->dpy, drw->screen));
+ d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap);
x += lpad;
w -= lpad;
}
diff --git a/drw.c.orig b/drw.c.orig
new file mode 100644
index 0000000..4cdbcbe
--- /dev/null
+++ b/drw.c.orig
@@ -0,0 +1,436 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xlib.h>
+#include <X11/Xft/Xft.h>
+
+#include "drw.h"
+#include "util.h"
+
+#define UTF_INVALID 0xFFFD
+#define UTF_SIZ 4
+
+static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
+static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
+static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
+static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
+
+static long
+utf8decodebyte(const char c, size_t *i)
+{
+ for (*i = 0; *i < (UTF_SIZ + 1); ++(*i))
+ if (((unsigned char)c & utfmask[*i]) == utfbyte[*i])
+ return (unsigned char)c & ~utfmask[*i];
+ return 0;
+}
+
+static size_t
+utf8validate(long *u, size_t i)
+{
+ if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
+ *u = UTF_INVALID;
+ for (i = 1; *u > utfmax[i]; ++i)
+ ;
+ return i;
+}
+
+static size_t
+utf8decode(const char *c, long *u, size_t clen)
+{
+ size_t i, j, len, type;
+ long udecoded;
+
+ *u = UTF_INVALID;
+ if (!clen)
+ return 0;
+ udecoded = utf8decodebyte(c[0], &len);
+ if (!BETWEEN(len, 1, UTF_SIZ))
+ return 1;
+ for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
+ udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
+ if (type)
+ return j;
+ }
+ if (j < len)
+ return 0;
+ *u = udecoded;
+ utf8validate(u, len);
+
+ return len;
+}
+
+Drw *
+drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
+{
+ Drw *drw = ecalloc(1, sizeof(Drw));
+
+ drw->dpy = dpy;
+ drw->screen = screen;
+ drw->root = root;
+ drw->w = w;
+ drw->h = h;
+ drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
+ drw->gc = XCreateGC(dpy, root, 0, NULL);
+ XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
+
+ return drw;
+}
+
+void
+drw_resize(Drw *drw, unsigned int w, unsigned int h)
+{
+ if (!drw)
+ return;
+
+ drw->w = w;
+ drw->h = h;
+ if (drw->drawable)
+ XFreePixmap(drw->dpy, drw->drawable);
+ drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
+}
+
+void
+drw_free(Drw *drw)
+{
+ XFreePixmap(drw->dpy, drw->drawable);
+ XFreeGC(drw->dpy, drw->gc);
+ drw_fontset_free(drw->fonts);
+ free(drw);
+}
+
+/* This function is an implementation detail. Library users should use
+ * drw_fontset_create instead.
+ */
+static Fnt *
+xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
+{
+ Fnt *font;
+ XftFont *xfont = NULL;
+ FcPattern *pattern = NULL;
+
+ if (fontname) {
+ /* Using the pattern found at font->xfont->pattern does not yield the
+ * same substitution results as using the pattern returned by
+ * FcNameParse; using the latter results in the desired fallback
+ * behaviour whereas the former just results in missing-character
+ * rectangles being drawn, at least with some fonts. */
+ if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {
+ fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname);
+ return NULL;
+ }
+ if (!(pattern = FcNameParse((FcChar8 *) fontname))) {
+ fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname);
+ XftFontClose(drw->dpy, xfont);
+ return NULL;
+ }
+ } else if (fontpattern) {
+ if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) {
+ fprintf(stderr, "error, cannot load font from pattern.\n");
+ return NULL;
+ }
+ } else {
+ die("no font specified.");
+ }
+
+ /* Do not allow using color fonts. This is a workaround for a BadLength
+ * error from Xft with color glyphs. Modelled on the Xterm workaround. See
+ * https://bugzilla.redhat.com/show_bug.cgi?id=1498269
+ * https://lists.suckless.org/dev/1701/30932.html
+ * https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349
+ * and lots more all over the internet.
+ */
+ FcBool iscol;
+ if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) {
+ XftFontClose(drw->dpy, xfont);
+ return NULL;
+ }
+
+ font = ecalloc(1, sizeof(Fnt));
+ font->xfont = xfont;
+ font->pattern = pattern;
+ font->h = xfont->ascent + xfont->descent;
+ font->dpy = drw->dpy;
+
+ return font;
+}
+
+static void
+xfont_free(Fnt *font)
+{
+ if (!font)
+ return;
+ if (font->pattern)
+ FcPatternDestroy(font->pattern);
+ XftFontClose(font->dpy, font->xfont);
+ free(font);
+}
+
+Fnt*
+drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
+{
+ Fnt *cur, *ret = NULL;
+ size_t i;
+
+ if (!drw || !fonts)
+ return NULL;
+
+ for (i = 1; i <= fontcount; i++) {
+ if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) {
+ cur->next = ret;
+ ret = cur;
+ }
+ }
+ return (drw->fonts = ret);
+}
+
+void
+drw_fontset_free(Fnt *font)
+{
+ if (font) {
+ drw_fontset_free(font->next);
+ xfont_free(font);
+ }
+}
+
+void
+drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
+{
+ if (!drw || !dest || !clrname)
+ return;
+
+ if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
+ DefaultColormap(drw->dpy, drw->screen),
+ clrname, dest))
+ die("error, cannot allocate color '%s'", clrname);
+}
+
+/* Wrapper to create color schemes. The caller has to call free(3) on the
+ * returned color scheme when done using it. */
+Clr *
+drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
+{
+ size_t i;
+ Clr *ret;
+
+ /* need at least two colors for a scheme */
+ if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
+ return NULL;
+
+ for (i = 0; i < clrcount; i++)
+ drw_clr_create(drw, &ret[i], clrnames[i]);
+ return ret;
+}
+
+void
+drw_setfontset(Drw *drw, Fnt *set)
+{
+ if (drw)
+ drw->fonts = set;
+}
+
+void
+drw_setscheme(Drw *drw, Clr *scm)
+{
+ if (drw)
+ drw->scheme = scm;
+}
+
+void
+drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
+{
+ if (!drw || !drw->scheme)
+ return;
+ XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
+ if (filled)
+ XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
+ else
+ XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
+}
+
+int
+drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
+{
+ char buf[1024];
+ int ty;
+ unsigned int ew;
+ XftDraw *d = NULL;
+ Fnt *usedfont, *curfont, *nextfont;
+ size_t i, len;
+ int utf8strlen, utf8charlen, render = x || y || w || h;
+ long utf8codepoint = 0;
+ const char *utf8str;
+ FcCharSet *fccharset;
+ FcPattern *fcpattern;
+ FcPattern *match;
+ XftResult result;
+ int charexists = 0;
+
+ if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
+ return 0;
+
+ if (!render) {
+ w = ~w;
+ } else {
+ XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
+ XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
+ d = XftDrawCreate(drw->dpy, drw->drawable,
+ DefaultVisual(drw->dpy, drw->screen),
+ DefaultColormap(drw->dpy, drw->screen));
+ x += lpad;
+ w -= lpad;
+ }
+
+ usedfont = drw->fonts;
+ while (1) {
+ utf8strlen = 0;
+ utf8str = text;
+ nextfont = NULL;
+ while (*text) {
+ utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
+ for (curfont = drw->fonts; curfont; curfont = curfont->next) {
+ charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
+ if (charexists) {
+ if (curfont == usedfont) {
+ utf8strlen += utf8charlen;
+ text += utf8charlen;
+ } else {
+ nextfont = curfont;
+ }
+ break;
+ }
+ }
+
+ if (!charexists || nextfont)
+ break;
+ else
+ charexists = 0;
+ }
+
+ if (utf8strlen) {
+ drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL);
+ /* shorten text if necessary */
+ for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--)
+ drw_font_getexts(usedfont, utf8str, len, &ew, NULL);
+
+ if (len) {
+ memcpy(buf, utf8str, len);
+ buf[len] = '\0';
+ if (len < utf8strlen)
+ for (i = len; i && i > len - 3; buf[--i] = '.')
+ ; /* NOP */
+
+ if (render) {
+ ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
+ XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
+ usedfont->xfont, x, ty, (XftChar8 *)buf, len);
+ }
+ x += ew;
+ w -= ew;
+ }
+ }
+
+ if (!*text) {
+ break;
+ } else if (nextfont) {
+ charexists = 0;
+ usedfont = nextfont;
+ } else {
+ /* Regardless of whether or not a fallback font is found, the
+ * character must be drawn. */
+ charexists = 1;
+
+ fccharset = FcCharSetCreate();
+ FcCharSetAddChar(fccharset, utf8codepoint);
+
+ if (!drw->fonts->pattern) {
+ /* Refer to the comment in xfont_create for more information. */
+ die("the first font in the cache must be loaded from a font string.");
+ }
+
+ fcpattern = FcPatternDuplicate(drw->fonts->pattern);
+ FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
+ FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
+ FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);
+
+ FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
+ FcDefaultSubstitute(fcpattern);
+ match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result);
+
+ FcCharSetDestroy(fccharset);
+ FcPatternDestroy(fcpattern);
+
+ if (match) {
+ usedfont = xfont_create(drw, NULL, match);
+ if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) {
+ for (curfont = drw->fonts; curfont->next; curfont = curfont->next)
+ ; /* NOP */
+ curfont->next = usedfont;
+ } else {
+ xfont_free(usedfont);
+ usedfont = drw->fonts;
+ }
+ }
+ }
+ }
+ if (d)
+ XftDrawDestroy(d);
+
+ return x + (render ? w : 0);
+}
+
+void
+drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
+{
+ if (!drw)
+ return;
+
+ XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);
+ XSync(drw->dpy, False);
+}
+
+unsigned int
+drw_fontset_getwidth(Drw *drw, const char *text)
+{
+ if (!drw || !drw->fonts || !text)
+ return 0;
+ return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
+}
+
+void
+drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
+{
+ XGlyphInfo ext;
+
+ if (!font || !text)
+ return;
+
+ XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext);
+ if (w)
+ *w = ext.xOff;
+ if (h)
+ *h = font->h;
+}
+
+Cur *
+drw_cur_create(Drw *drw, int shape)
+{
+ Cur *cur;
+
+ if (!drw || !(cur = ecalloc(1, sizeof(Cur))))
+ return NULL;
+
+ cur->cursor = XCreateFontCursor(drw->dpy, shape);
+
+ return cur;
+}
+
+void
+drw_cur_free(Drw *drw, Cur *cursor)
+{
+ if (!cursor)
+ return;
+
+ XFreeCursor(drw->dpy, cursor->cursor);
+ free(cursor);
+}
diff --git a/drw.h b/drw.h
index 4c67419..f6fa5cd 100644
--- a/drw.h
+++ b/drw.h
@@ -20,6 +20,9 @@ typedef struct {
Display *dpy;
int screen;
Window root;
+ Visual *visual;
+ unsigned int depth;
+ Colormap cmap;
Drawable drawable;
GC gc;
Clr *scheme;
@@ -27,7 +30,7 @@ typedef struct {
} Drw;
/* Drawable abstraction */
-Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
+Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual*, unsigned int, Colormap);
void drw_resize(Drw *drw, unsigned int w, unsigned int h);
void drw_free(Drw *drw);
@@ -38,8 +41,8 @@ unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
/* Colorscheme abstraction */
-void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
-Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
+void drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha);
+Clr *drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount);
/* Cursor abstraction */
Cur *drw_cur_create(Drw *drw, int shape);
diff --git a/drw.h.orig b/drw.h.orig
new file mode 100644
index 0000000..4c67419
--- /dev/null
+++ b/drw.h.orig
@@ -0,0 +1,57 @@
+/* See LICENSE file for copyright and license details. */
+
+typedef struct {
+ Cursor cursor;
+} Cur;
+
+typedef struct Fnt {
+ Display *dpy;
+ unsigned int h;
+ XftFont *xfont;
+ FcPattern *pattern;
+ struct Fnt *next;
+} Fnt;
+
+enum { ColFg, ColBg }; /* Clr scheme index */
+typedef XftColor Clr;
+
+typedef struct {
+ unsigned int w, h;
+ Display *dpy;
+ int screen;
+ Window root;
+ Drawable drawable;
+ GC gc;
+ Clr *scheme;
+ Fnt *fonts;
+} Drw;
+
+/* Drawable abstraction */
+Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
+void drw_resize(Drw *drw, unsigned int w, unsigned int h);
+void drw_free(Drw *drw);
+
+/* Fnt abstraction */
+Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
+void drw_fontset_free(Fnt* set);
+unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
+void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
+
+/* Colorscheme abstraction */
+void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
+Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
+
+/* Cursor abstraction */
+Cur *drw_cur_create(Drw *drw, int shape);
+void drw_cur_free(Drw *drw, Cur *cursor);
+
+/* Drawing context manipulation */
+void drw_setfontset(Drw *drw, Fnt *set);
+void drw_setscheme(Drw *drw, Clr *scm);
+
+/* Drawing functions */
+void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
+int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert);
+
+/* Map functions */
+void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);
diff --git a/drw.o b/drw.o
index 6022adb..242f739 100644
--- a/drw.o
+++ b/drw.o
Binary files differ
diff --git a/stest b/stest
index b48e071..6894d63 100755
--- a/stest
+++ b/stest
Binary files differ