Compare commits
8 Commits
Author | SHA1 | Date |
---|---|---|
|
8df553e004 | |
|
7ab0cb5ef0 | |
|
0fe460dbd4 | |
|
dfbbf7f6e1 | |
|
ba1a347dca | |
|
bcbc1ef5c4 | |
|
689d9bfcf6 | |
|
e42c036634 |
10
Makefile
10
Makefile
|
@ -6,13 +6,7 @@ include config.mk
|
||||||
SRC = drw.c dmenu.c stest.c util.c
|
SRC = drw.c dmenu.c stest.c util.c
|
||||||
OBJ = $(SRC:.c=.o)
|
OBJ = $(SRC:.c=.o)
|
||||||
|
|
||||||
all: options dmenu stest
|
all: dmenu stest
|
||||||
|
|
||||||
options:
|
|
||||||
@echo dmenu build options:
|
|
||||||
@echo "CFLAGS = $(CFLAGS)"
|
|
||||||
@echo "LDFLAGS = $(LDFLAGS)"
|
|
||||||
@echo "CC = $(CC)"
|
|
||||||
|
|
||||||
.c.o:
|
.c.o:
|
||||||
$(CC) -c $(CFLAGS) $<
|
$(CC) -c $(CFLAGS) $<
|
||||||
|
@ -61,4 +55,4 @@ uninstall:
|
||||||
$(DESTDIR)$(MANPREFIX)/man1/dmenu.1\
|
$(DESTDIR)$(MANPREFIX)/man1/dmenu.1\
|
||||||
$(DESTDIR)$(MANPREFIX)/man1/stest.1
|
$(DESTDIR)$(MANPREFIX)/man1/stest.1
|
||||||
|
|
||||||
.PHONY: all options clean dist install uninstall
|
.PHONY: all clean dist install uninstall
|
||||||
|
|
29
dmenu.c
29
dmenu.c
|
@ -22,7 +22,6 @@
|
||||||
/* macros */
|
/* macros */
|
||||||
#define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \
|
#define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \
|
||||||
* MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org)))
|
* MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org)))
|
||||||
#define LENGTH(X) (sizeof X / sizeof X[0])
|
|
||||||
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
|
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
|
||||||
|
|
||||||
/* enums */
|
/* enums */
|
||||||
|
@ -324,19 +323,19 @@ movewordedge(int dir)
|
||||||
static void
|
static void
|
||||||
keypress(XKeyEvent *ev)
|
keypress(XKeyEvent *ev)
|
||||||
{
|
{
|
||||||
char buf[32];
|
char buf[64];
|
||||||
int len;
|
int len;
|
||||||
KeySym ksym;
|
KeySym ksym = NoSymbol;
|
||||||
Status status;
|
Status status;
|
||||||
|
|
||||||
len = XmbLookupString(xic, ev, buf, sizeof buf, &ksym, &status);
|
len = XmbLookupString(xic, ev, buf, sizeof buf, &ksym, &status);
|
||||||
switch (status) {
|
switch (status) {
|
||||||
default: /* XLookupNone, XBufferOverflow */
|
default: /* XLookupNone, XBufferOverflow */
|
||||||
return;
|
return;
|
||||||
case XLookupChars:
|
case XLookupChars: /* composed string from input method */
|
||||||
goto insert;
|
goto insert;
|
||||||
case XLookupKeySym:
|
case XLookupKeySym:
|
||||||
case XLookupBoth:
|
case XLookupBoth: /* a KeySym and a string are returned: use keysym */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -550,19 +549,24 @@ static void
|
||||||
readstdin(void)
|
readstdin(void)
|
||||||
{
|
{
|
||||||
char *line = NULL;
|
char *line = NULL;
|
||||||
size_t i, junk, size = 0;
|
size_t i, itemsiz = 0, linesiz = 0;
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
|
|
||||||
/* read each line from stdin and add it to the item list */
|
/* read each line from stdin and add it to the item list */
|
||||||
for (i = 0; (len = getline(&line, &junk, stdin)) != -1; i++, line = NULL) {
|
for (i = 0; (len = getline(&line, &linesiz, stdin)) != -1; i++) {
|
||||||
if (i + 1 >= size / sizeof *items)
|
if (i + 1 >= itemsiz) {
|
||||||
if (!(items = realloc(items, (size += BUFSIZ))))
|
itemsiz += 256;
|
||||||
die("cannot realloc %zu bytes:", size);
|
if (!(items = realloc(items, itemsiz * sizeof(*items))))
|
||||||
|
die("cannot realloc %zu bytes:", itemsiz * sizeof(*items));
|
||||||
|
}
|
||||||
if (line[len - 1] == '\n')
|
if (line[len - 1] == '\n')
|
||||||
line[len - 1] = '\0';
|
line[len - 1] = '\0';
|
||||||
items[i].text = line;
|
if (!(items[i].text = strdup(line)))
|
||||||
|
die("strdup:");
|
||||||
|
|
||||||
items[i].out = 0;
|
items[i].out = 0;
|
||||||
}
|
}
|
||||||
|
free(line);
|
||||||
if (items)
|
if (items)
|
||||||
items[i].text = NULL;
|
items[i].text = NULL;
|
||||||
lines = MIN(lines, i);
|
lines = MIN(lines, i);
|
||||||
|
@ -680,7 +684,7 @@ setup(void)
|
||||||
swa.override_redirect = True;
|
swa.override_redirect = True;
|
||||||
swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
|
swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
|
||||||
swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
|
swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
|
||||||
win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
|
win = XCreateWindow(dpy, root, x, y, mw, mh, 0,
|
||||||
CopyFromParent, CopyFromParent, CopyFromParent,
|
CopyFromParent, CopyFromParent, CopyFromParent,
|
||||||
CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
|
CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
|
||||||
XSetClassHint(dpy, win, &ch);
|
XSetClassHint(dpy, win, &ch);
|
||||||
|
@ -695,6 +699,7 @@ setup(void)
|
||||||
|
|
||||||
XMapRaised(dpy, win);
|
XMapRaised(dpy, win);
|
||||||
if (embed) {
|
if (embed) {
|
||||||
|
XReparentWindow(dpy, win, parentwin, x, y);
|
||||||
XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask);
|
XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask);
|
||||||
if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) {
|
if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) {
|
||||||
for (i = 0; i < du && dws[i] != win; ++i)
|
for (i = 0; i < du && dws[i] != win; ++i)
|
||||||
|
|
23
drw.c
23
drw.c
|
@ -238,8 +238,8 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int
|
||||||
int
|
int
|
||||||
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
|
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
|
||||||
{
|
{
|
||||||
int i, ty, ellipsis_x = 0;
|
int ty, ellipsis_x = 0;
|
||||||
unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len;
|
unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len, hash, h0, h1;
|
||||||
XftDraw *d = NULL;
|
XftDraw *d = NULL;
|
||||||
Fnt *usedfont, *curfont, *nextfont;
|
Fnt *usedfont, *curfont, *nextfont;
|
||||||
int utf8strlen, utf8charlen, render = x || y || w || h;
|
int utf8strlen, utf8charlen, render = x || y || w || h;
|
||||||
|
@ -251,9 +251,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
||||||
XftResult result;
|
XftResult result;
|
||||||
int charexists = 0, overflow = 0;
|
int charexists = 0, overflow = 0;
|
||||||
/* keep track of a couple codepoints for which we have no match. */
|
/* keep track of a couple codepoints for which we have no match. */
|
||||||
enum { nomatches_len = 64 };
|
static unsigned int nomatches[128], ellipsis_width;
|
||||||
static struct { long codepoint[nomatches_len]; unsigned int idx; } nomatches;
|
|
||||||
static unsigned int ellipsis_width = 0;
|
|
||||||
|
|
||||||
if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts)
|
if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -338,11 +336,14 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
||||||
* character must be drawn. */
|
* character must be drawn. */
|
||||||
charexists = 1;
|
charexists = 1;
|
||||||
|
|
||||||
for (i = 0; i < nomatches_len; ++i) {
|
hash = (unsigned int)utf8codepoint;
|
||||||
/* avoid calling XftFontMatch if we know we won't find a match */
|
hash = ((hash >> 16) ^ hash) * 0x21F0AAAD;
|
||||||
if (utf8codepoint == nomatches.codepoint[i])
|
hash = ((hash >> 15) ^ hash) * 0xD35A2D97;
|
||||||
goto no_match;
|
h0 = ((hash >> 15) ^ hash) % LENGTH(nomatches);
|
||||||
}
|
h1 = (hash >> 17) % LENGTH(nomatches);
|
||||||
|
/* avoid expensive XftFontMatch call when we know we won't find a match */
|
||||||
|
if (nomatches[h0] == utf8codepoint || nomatches[h1] == utf8codepoint)
|
||||||
|
goto no_match;
|
||||||
|
|
||||||
fccharset = FcCharSetCreate();
|
fccharset = FcCharSetCreate();
|
||||||
FcCharSetAddChar(fccharset, utf8codepoint);
|
FcCharSetAddChar(fccharset, utf8codepoint);
|
||||||
|
@ -371,7 +372,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
||||||
curfont->next = usedfont;
|
curfont->next = usedfont;
|
||||||
} else {
|
} else {
|
||||||
xfont_free(usedfont);
|
xfont_free(usedfont);
|
||||||
nomatches.codepoint[++nomatches.idx % nomatches_len] = utf8codepoint;
|
nomatches[nomatches[h0] ? h1 : h0] = utf8codepoint;
|
||||||
no_match:
|
no_match:
|
||||||
usedfont = drw->fonts;
|
usedfont = drw->fonts;
|
||||||
}
|
}
|
||||||
|
|
1
util.h
1
util.h
|
@ -3,6 +3,7 @@
|
||||||
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
||||||
#define MIN(A, B) ((A) < (B) ? (A) : (B))
|
#define MIN(A, B) ((A) < (B) ? (A) : (B))
|
||||||
#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
|
#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
|
||||||
|
#define LENGTH(X) (sizeof (X) / sizeof (X)[0])
|
||||||
|
|
||||||
void die(const char *fmt, ...);
|
void die(const char *fmt, ...);
|
||||||
void *ecalloc(size_t nmemb, size_t size);
|
void *ecalloc(size_t nmemb, size_t size);
|
||||||
|
|
Loading…
Reference in New Issue