Instantly share code, notes, and snippets.
Last active
June 17, 2020 23:52
-
Save oibind/d17b79025765f53e99716fb1ee780c88 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/config.def.h b/config.def.h | |
index c0d7d74..4c2f69b 100644 | |
--- a/config.def.h | |
+++ b/config.def.h | |
@@ -6,6 +6,8 @@ static int topbar = 1; /* -b option; if 0, dmenu appears a | |
static const char *fonts[] = { | |
"monospace:size=14" | |
}; | |
+static const unsigned int bgalpha = 0xe0; | |
+static const unsigned int fgalpha = OPAQUE; | |
static const char *prompt = NULL; /* -p option; prompt to the left of input field */ | |
static const char *colors[SchemeLast][2] = { | |
/* fg bg */ | |
@@ -13,6 +15,13 @@ static const char *colors[SchemeLast][2] = { | |
[SchemeSel] = { "#eeeeee", "#005577" }, | |
[SchemeOut] = { "#000000", "#00ffff" }, | |
}; | |
+static const unsigned int alphas[SchemeLast][2] = { | |
+ /* fgalpha bgalphga */ | |
+ [SchemeNorm] = { fgalpha, bgalpha }, | |
+ [SchemeSel] = { fgalpha, bgalpha }, | |
+ [SchemeOut] = { fgalpha, bgalpha }, | |
+}; | |
+ | |
/* -l option; if nonzero, dmenu uses vertical list with given number of lines */ | |
static unsigned int lines = 0; | |
diff --git a/config.mk b/config.mk | |
index 0929b4a..260eeae 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/dmenu.c b/dmenu.c | |
index 6b8f51b..8f72f60 100644 | |
--- a/dmenu.c | |
+++ b/dmenu.c | |
@@ -25,6 +25,9 @@ | |
#define LENGTH(X) (sizeof X / sizeof X[0]) | |
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) | |
+/* define opaqueness */ | |
+#define OPAQUE 0xFFU | |
+ | |
/* enums */ | |
enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ | |
@@ -51,6 +54,10 @@ static Window root, parentwin, win; | |
static XIC xic; | |
static Drw *drw; | |
+static int usergb = 0; | |
+static Visual *visual; | |
+static int depth; | |
+static Colormap cmap; | |
static Clr *scheme[SchemeLast]; | |
#include "config.h" | |
@@ -58,6 +65,46 @@ static Clr *scheme[SchemeLast]; | |
static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; | |
static char *(*fstrstr)(const char *, const char *) = strstr; | |
+ | |
+static 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); | |
+ usergb = 1; | |
+ break; | |
+ } | |
+ } | |
+ | |
+ XFree(infos); | |
+ | |
+ if (! visual) { | |
+ visual = DefaultVisual(dpy, screen); | |
+ depth = DefaultDepth(dpy, screen); | |
+ cmap = DefaultColormap(dpy, screen); | |
+ } | |
+} | |
+ | |
static void | |
appenditem(struct item *item, struct item **list, struct item **last) | |
{ | |
@@ -597,7 +644,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[j], 2); | |
clip = XInternAtom(dpy, "CLIPBOARD", False); | |
utf8 = XInternAtom(dpy, "UTF8_STRING", False); | |
@@ -653,10 +700,12 @@ setup(void) | |
/* create menu window */ | |
swa.override_redirect = True; | |
swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; | |
+ swa.border_pixel = 0; | |
+ swa.colormap = cmap; | |
swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; | |
win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0, | |
- CopyFromParent, CopyFromParent, CopyFromParent, | |
- CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); | |
+ depth, InputOutput, visual, | |
+ CWOverrideRedirect | CWBackPixel | CWColormap | CWEventMask | CWBorderPixel, &swa); | |
XSetClassHint(dpy, win, &ch); | |
/* open input methods */ | |
@@ -742,7 +791,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; | |
diff --git a/drw.c b/drw.c | |
index 8fd1ca4..6ad9e2d 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 | |
@@ -193,21 +196,21 @@ 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 & 0x00FFFFFFFU) | 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; | |
@@ -217,7 +220,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; | |
} | |
@@ -273,9 +276,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.h b/drw.h | |
index 4c67419..4f66f0d 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 *visual, unsigned int depth, Colormap cmap); | |
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); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment