added dmenu.h, common.c
							parent
							
								
									29e8faed6c
								
							
						
					
					
						commit
						855a566319
					
				
							
								
								
									
										10
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										10
									
								
								Makefile
								
								
								
								
							|  | @ -3,7 +3,7 @@ | ||||||
| 
 | 
 | ||||||
| include config.mk | include config.mk | ||||||
| 
 | 
 | ||||||
| SRC = dinput.c dmenu.c | SRC = dinput.c dmenu.c common.c | ||||||
| OBJ = ${SRC:.c=.o} | OBJ = ${SRC:.c=.o} | ||||||
| 
 | 
 | ||||||
| all: options dinput dmenu | all: options dinput dmenu | ||||||
|  | @ -24,9 +24,13 @@ config.h: | ||||||
| 	@echo creating $@ from config.def.h | 	@echo creating $@ from config.def.h | ||||||
| 	@cp config.def.h $@ | 	@cp config.def.h $@ | ||||||
| 
 | 
 | ||||||
| .o: | dinput: dinput.o common.o | ||||||
| 	@echo CC -o $@ | 	@echo CC -o $@ | ||||||
| 	@${CC} -o $@ $< ${LDFLAGS} | 	@${CC} -o $@ $+ ${LDFLAGS} | ||||||
|  | 
 | ||||||
|  | dmenu: dmenu.o common.o | ||||||
|  | 	@echo CC -o $@ | ||||||
|  | 	@${CC} -o $@ $+ ${LDFLAGS} | ||||||
| 
 | 
 | ||||||
| clean: | clean: | ||||||
| 	@echo cleaning | 	@echo cleaning | ||||||
|  |  | ||||||
|  | @ -0,0 +1,129 @@ | ||||||
|  | /* See LICENSE file for copyright and license details. */ | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <X11/keysym.h> | ||||||
|  | #ifdef XINERAMA | ||||||
|  | #include <X11/extensions/Xinerama.h> | ||||||
|  | #endif | ||||||
|  | #include "dmenu.h" | ||||||
|  | 
 | ||||||
|  | /* variables */ | ||||||
|  | char *prompt = NULL; | ||||||
|  | char text[4096] = ""; | ||||||
|  | int promptw = 0; | ||||||
|  | int screen; | ||||||
|  | unsigned int numlockmask = 0; | ||||||
|  | unsigned int mw, mh; | ||||||
|  | unsigned long normcol[ColLast]; | ||||||
|  | unsigned long selcol[ColLast]; | ||||||
|  | Bool topbar = True; | ||||||
|  | DC dc; | ||||||
|  | Display *dpy; | ||||||
|  | Window win, root; | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | grabkeyboard(void) { | ||||||
|  | 	unsigned int len; | ||||||
|  | 
 | ||||||
|  | 	for(len = 1000; len; len--) { | ||||||
|  | 		if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) | ||||||
|  | 		== GrabSuccess) | ||||||
|  | 			return; | ||||||
|  | 		usleep(1000); | ||||||
|  | 	} | ||||||
|  | 	exit(EXIT_FAILURE); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | run(void) { | ||||||
|  | 	XEvent ev; | ||||||
|  | 
 | ||||||
|  | 	/* main event loop */ | ||||||
|  | 	XSync(dpy, False); | ||||||
|  | 	while(!XNextEvent(dpy, &ev)) | ||||||
|  | 		switch(ev.type) { | ||||||
|  | 		case KeyPress: | ||||||
|  | 			kpress(&ev.xkey); | ||||||
|  | 			break; | ||||||
|  | 		case Expose: | ||||||
|  | 			if(ev.xexpose.count == 0) | ||||||
|  | 				drawbar(); | ||||||
|  | 			break; | ||||||
|  | 		case VisibilityNotify: | ||||||
|  | 			if(ev.xvisibility.state != VisibilityUnobscured) | ||||||
|  | 				XRaiseWindow(dpy, win); | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	exit(EXIT_FAILURE); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | setup(unsigned int lines) { | ||||||
|  | 	int i, j, x, y; | ||||||
|  | #if XINERAMA | ||||||
|  | 	int n; | ||||||
|  | 	XineramaScreenInfo *info = NULL; | ||||||
|  | #endif | ||||||
|  | 	XModifierKeymap *modmap; | ||||||
|  | 	XSetWindowAttributes wa; | ||||||
|  | 
 | ||||||
|  | 	/* init modifier map */ | ||||||
|  | 	modmap = XGetModifierMapping(dpy); | ||||||
|  | 	for(i = 0; i < 8; i++) | ||||||
|  | 		for(j = 0; j < modmap->max_keypermod; j++) { | ||||||
|  | 			if(modmap->modifiermap[i * modmap->max_keypermod + j] | ||||||
|  | 			== XKeysymToKeycode(dpy, XK_Num_Lock)) | ||||||
|  | 				numlockmask = (1 << i); | ||||||
|  | 		} | ||||||
|  | 	XFreeModifiermap(modmap); | ||||||
|  | 
 | ||||||
|  | 	dc.dpy = dpy; | ||||||
|  | 	normcol[ColBG] = getcolor(&dc, normbgcolor); | ||||||
|  | 	normcol[ColFG] = getcolor(&dc, normfgcolor); | ||||||
|  | 	selcol[ColBG] = getcolor(&dc, selbgcolor); | ||||||
|  | 	selcol[ColFG] = getcolor(&dc, selfgcolor); | ||||||
|  | 	initfont(&dc, font); | ||||||
|  | 
 | ||||||
|  | 	/* input window */ | ||||||
|  | 	wa.override_redirect = True; | ||||||
|  | 	wa.background_pixmap = ParentRelative; | ||||||
|  | 	wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; | ||||||
|  | 
 | ||||||
|  | 	/* input window geometry */ | ||||||
|  | 	mh = (dc.font.height + 2) * (lines + 1); | ||||||
|  | #if XINERAMA | ||||||
|  | 	if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { | ||||||
|  | 		i = 0; | ||||||
|  | 		if(n > 1) { | ||||||
|  | 			int di; | ||||||
|  | 			unsigned int dui; | ||||||
|  | 			Window dummy; | ||||||
|  | 			if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui)) | ||||||
|  | 				for(i = 0; i < n; i++) | ||||||
|  | 					if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) | ||||||
|  | 						break; | ||||||
|  | 		} | ||||||
|  | 		x = info[i].x_org; | ||||||
|  | 		y = topbar ? info[i].y_org : info[i].y_org + info[i].height - mh; | ||||||
|  | 		mw = info[i].width; | ||||||
|  | 		XFree(info); | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | #endif | ||||||
|  | 	{ | ||||||
|  | 		x = 0; | ||||||
|  | 		y = topbar ? 0 : DisplayHeight(dpy, screen) - mh; | ||||||
|  | 		mw = DisplayWidth(dpy, screen); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	win = XCreateWindow(dpy, root, x, y, mw, mh, 0, | ||||||
|  | 			DefaultDepth(dpy, screen), CopyFromParent, | ||||||
|  | 			DefaultVisual(dpy, screen), | ||||||
|  | 			CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); | ||||||
|  | 
 | ||||||
|  | 	setupdraw(&dc, win); | ||||||
|  | 	if(prompt) | ||||||
|  | 		promptw = MIN(textw(&dc, prompt), mw / 5); | ||||||
|  | 	XMapRaised(dpy, win); | ||||||
|  | } | ||||||
							
								
								
									
										11
									
								
								config.def.h
								
								
								
								
							
							
						
						
									
										11
									
								
								config.def.h
								
								
								
								
							|  | @ -1,9 +1,8 @@ | ||||||
| /* See LICENSE file for copyright and license details. */ | /* See LICENSE file for copyright and license details. */ | ||||||
| 
 | 
 | ||||||
| /* appearance */ | /* appearance */ | ||||||
| const char *font        = "-*-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*"; | static const char *font        = "-*-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*"; | ||||||
| const char *normbgcolor = "#cccccc"; | static const char *normbgcolor = "#cccccc"; | ||||||
| const char *normfgcolor = "#000000"; | static const char *normfgcolor = "#000000"; | ||||||
| const char *selbgcolor  = "#0066ff"; | static const char *selbgcolor  = "#0066ff"; | ||||||
| const char *selfgcolor  = "#ffffff"; | static const char *selfgcolor  = "#ffffff"; | ||||||
| unsigned int spaceitem  = 30; /* px between menu items */ |  | ||||||
|  |  | ||||||
							
								
								
									
										150
									
								
								dinput.c
								
								
								
								
							
							
						
						
									
										150
									
								
								dinput.c
								
								
								
								
							|  | @ -4,45 +4,16 @@ | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <unistd.h> |  | ||||||
| #include <X11/keysym.h> | #include <X11/keysym.h> | ||||||
| #include <X11/Xlib.h> | #include <X11/Xlib.h> | ||||||
| #include <X11/Xutil.h> | #include <X11/Xutil.h> | ||||||
| #ifdef XINERAMA | #include "dmenu.h" | ||||||
| #include <X11/extensions/Xinerama.h> |  | ||||||
| #endif |  | ||||||
| #include <draw.h> |  | ||||||
| 
 |  | ||||||
| /* macros */ |  | ||||||
| #define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH)) |  | ||||||
| #define MIN(a, b)               ((a) < (b) ? (a) : (b)) |  | ||||||
| #define MAX(a, b)               ((a) > (b) ? (a) : (b)) |  | ||||||
| #define IS_UTF8_1ST_CHAR(c)     ((((c) & 0xc0) == 0xc0) || !((c) & 0x80)) |  | ||||||
| 
 | 
 | ||||||
| /* forward declarations */ | /* forward declarations */ | ||||||
| static void cleanup(void); | static void cleanup(void); | ||||||
| static void drawinput(void); |  | ||||||
| static void grabkeyboard(void); |  | ||||||
| static void kpress(XKeyEvent *e); |  | ||||||
| static void run(void); |  | ||||||
| static void setup(void); |  | ||||||
| 
 |  | ||||||
| #include "config.h" |  | ||||||
| 
 | 
 | ||||||
| /* variables */ | /* variables */ | ||||||
| static char *prompt = NULL; |  | ||||||
| static char text[4096]; |  | ||||||
| static int promptw = 0; |  | ||||||
| static int screen; |  | ||||||
| static size_t cursor = 0; | static size_t cursor = 0; | ||||||
| static unsigned int numlockmask = 0; |  | ||||||
| static unsigned int mw, mh; |  | ||||||
| static unsigned long normcol[ColLast]; |  | ||||||
| static unsigned long selcol[ColLast]; |  | ||||||
| static Bool topbar = True; |  | ||||||
| static DC dc; |  | ||||||
| static Display *dpy; |  | ||||||
| static Window win, root; |  | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| cleanup(void) { | cleanup(void) { | ||||||
|  | @ -53,7 +24,7 @@ cleanup(void) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| drawinput(void) | drawbar(void) | ||||||
| { | { | ||||||
| 	dc.x = 0; | 	dc.x = 0; | ||||||
| 	dc.y = 0; | 	dc.y = 0; | ||||||
|  | @ -72,19 +43,6 @@ drawinput(void) | ||||||
| 	commitdraw(&dc, win); | 	commitdraw(&dc, win); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void |  | ||||||
| grabkeyboard(void) { |  | ||||||
| 	unsigned int len; |  | ||||||
| 
 |  | ||||||
| 	for(len = 1000; len; len--) { |  | ||||||
| 		if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) |  | ||||||
| 		== GrabSuccess) |  | ||||||
| 			return; |  | ||||||
| 		usleep(1000); |  | ||||||
| 	} |  | ||||||
| 	exit(EXIT_FAILURE); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void | void | ||||||
| kpress(XKeyEvent *e) { | kpress(XKeyEvent *e) { | ||||||
| 	char buf[sizeof text]; | 	char buf[sizeof text]; | ||||||
|  | @ -207,101 +165,7 @@ kpress(XKeyEvent *e) { | ||||||
| 		while(cursor++ < len && !IS_UTF8_1ST_CHAR(text[cursor])); | 		while(cursor++ < len && !IS_UTF8_1ST_CHAR(text[cursor])); | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
| 	drawinput(); | 	drawbar(); | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void |  | ||||||
| run(void) { |  | ||||||
| 	XEvent ev; |  | ||||||
| 
 |  | ||||||
| 	/* main event loop */ |  | ||||||
| 	XSync(dpy, False); |  | ||||||
| 	while(!XNextEvent(dpy, &ev)) |  | ||||||
| 		switch(ev.type) { |  | ||||||
| 		case KeyPress: |  | ||||||
| 			kpress(&ev.xkey); |  | ||||||
| 			break; |  | ||||||
| 		case Expose: |  | ||||||
| 			if(ev.xexpose.count == 0) |  | ||||||
| 				drawinput(); |  | ||||||
| 			break; |  | ||||||
| 		case VisibilityNotify: |  | ||||||
| 			if(ev.xvisibility.state != VisibilityUnobscured) |  | ||||||
| 				XRaiseWindow(dpy, win); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 	exit(EXIT_FAILURE); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void |  | ||||||
| setup(void) { |  | ||||||
| 	int i, j, x, y; |  | ||||||
| #if XINERAMA |  | ||||||
| 	int n; |  | ||||||
| 	XineramaScreenInfo *info = NULL; |  | ||||||
| #endif |  | ||||||
| 	XModifierKeymap *modmap; |  | ||||||
| 	XSetWindowAttributes wa; |  | ||||||
| 
 |  | ||||||
| 	/* init modifier map */ |  | ||||||
| 	modmap = XGetModifierMapping(dpy); |  | ||||||
| 	for(i = 0; i < 8; i++) |  | ||||||
| 		for(j = 0; j < modmap->max_keypermod; j++) { |  | ||||||
| 			if(modmap->modifiermap[i * modmap->max_keypermod + j] |  | ||||||
| 			== XKeysymToKeycode(dpy, XK_Num_Lock)) |  | ||||||
| 				numlockmask = (1 << i); |  | ||||||
| 		} |  | ||||||
| 	XFreeModifiermap(modmap); |  | ||||||
| 
 |  | ||||||
| 	dc.dpy = dpy; |  | ||||||
| 	normcol[ColBG] = getcolor(&dc, normbgcolor); |  | ||||||
| 	normcol[ColFG] = getcolor(&dc, normfgcolor); |  | ||||||
| 	selcol[ColBG] = getcolor(&dc, selbgcolor); |  | ||||||
| 	selcol[ColFG] = getcolor(&dc, selfgcolor); |  | ||||||
| 	initfont(&dc, font); |  | ||||||
| 
 |  | ||||||
| 	/* input window */ |  | ||||||
| 	wa.override_redirect = True; |  | ||||||
| 	wa.background_pixmap = ParentRelative; |  | ||||||
| 	wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; |  | ||||||
| 
 |  | ||||||
| 	/* input window geometry */ |  | ||||||
| 	mh = dc.font.height + 2; |  | ||||||
| #if XINERAMA |  | ||||||
| 	if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { |  | ||||||
| 		i = 0; |  | ||||||
| 		if(n > 1) { |  | ||||||
| 			int di; |  | ||||||
| 			unsigned int dui; |  | ||||||
| 			Window dummy; |  | ||||||
| 			if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui)) |  | ||||||
| 				for(i = 0; i < n; i++) |  | ||||||
| 					if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) |  | ||||||
| 						break; |  | ||||||
| 		} |  | ||||||
| 		x = info[i].x_org; |  | ||||||
| 		y = topbar ? info[i].y_org : info[i].y_org + info[i].height - mh; |  | ||||||
| 		mw = info[i].width; |  | ||||||
| 		XFree(info); |  | ||||||
| 	} |  | ||||||
| 	else |  | ||||||
| #endif |  | ||||||
| 	{ |  | ||||||
| 		x = 0; |  | ||||||
| 		y = topbar ? 0 : DisplayHeight(dpy, screen) - mh; |  | ||||||
| 		mw = DisplayWidth(dpy, screen); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	win = XCreateWindow(dpy, root, x, y, mw, mh, 0, |  | ||||||
| 			DefaultDepth(dpy, screen), CopyFromParent, |  | ||||||
| 			DefaultVisual(dpy, screen), |  | ||||||
| 			CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); |  | ||||||
| 
 |  | ||||||
| 	setupdraw(&dc, win); |  | ||||||
| 	if(prompt) |  | ||||||
| 		promptw = MIN(textw(&dc, prompt), mw / 5); |  | ||||||
| 	cursor = strlen(text); |  | ||||||
| 	XMapRaised(dpy, win); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | int | ||||||
|  | @ -336,11 +200,13 @@ main(int argc, char *argv[]) { | ||||||
| 			if(++i < argc) selfgcolor = argv[i]; | 			if(++i < argc) selfgcolor = argv[i]; | ||||||
| 		} | 		} | ||||||
| 		else if(!strcmp(argv[i], "-v")) { | 		else if(!strcmp(argv[i], "-v")) { | ||||||
| 			printf("dinput-"VERSION", © 2006-2010 dinput engineers, see LICENSE for details\n"); | 			printf("dinput-"VERSION", © 2006-2010 dmenu engineers, see LICENSE for details\n"); | ||||||
| 			exit(EXIT_SUCCESS); | 			exit(EXIT_SUCCESS); | ||||||
| 		} | 		} | ||||||
| 		else if(!*text) | 		else if(!*text) { | ||||||
| 			strncpy(text, argv[i], sizeof text); | 			strncpy(text, argv[i], sizeof text); | ||||||
|  | 			cursor = strlen(text); | ||||||
|  | 		} | ||||||
| 		else { | 		else { | ||||||
| 			fputs("usage: dinput [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n" | 			fputs("usage: dinput [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n" | ||||||
| 			      "              [-p <prompt>] [-sb <color>] [-sf <color>] [-v] [<text>]\n", stderr); | 			      "              [-p <prompt>] [-sb <color>] [-sf <color>] [-v] [<text>]\n", stderr); | ||||||
|  | @ -356,7 +222,7 @@ main(int argc, char *argv[]) { | ||||||
| 	root = RootWindow(dpy, screen); | 	root = RootWindow(dpy, screen); | ||||||
| 
 | 
 | ||||||
| 	grabkeyboard(); | 	grabkeyboard(); | ||||||
| 	setup(); | 	setup(0); | ||||||
| 	run(); | 	run(); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										188
									
								
								dmenu.c
								
								
								
								
							
							
						
						
									
										188
									
								
								dmenu.c
								
								
								
								
							|  | @ -8,16 +8,7 @@ | ||||||
| #include <X11/keysym.h> | #include <X11/keysym.h> | ||||||
| #include <X11/Xlib.h> | #include <X11/Xlib.h> | ||||||
| #include <X11/Xutil.h> | #include <X11/Xutil.h> | ||||||
| #ifdef XINERAMA | #include "dmenu.h" | ||||||
| #include <X11/extensions/Xinerama.h> |  | ||||||
| #endif |  | ||||||
| #include <draw.h> |  | ||||||
| 
 |  | ||||||
| /* macros */ |  | ||||||
| #define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH)) |  | ||||||
| #define MIN(a, b)               ((a) < (b) ? (a) : (b)) |  | ||||||
| #define MAX(a, b)               ((a) > (b) ? (a) : (b)) |  | ||||||
| #define IS_UTF8_1ST_CHAR(c)     ((((c) & 0xc0) == 0xc0) || !((c) & 0x80)) |  | ||||||
| 
 | 
 | ||||||
| typedef struct Item Item; | typedef struct Item Item; | ||||||
| struct Item { | struct Item { | ||||||
|  | @ -33,41 +24,22 @@ static void calcoffsetsv(void); | ||||||
| static char *cistrstr(const char *s, const char *sub); | static char *cistrstr(const char *s, const char *sub); | ||||||
| static void cleanup(void); | static void cleanup(void); | ||||||
| static void dinput(void); | static void dinput(void); | ||||||
| static void drawmenu(void); |  | ||||||
| static void drawmenuh(void); | static void drawmenuh(void); | ||||||
| static void drawmenuv(void); | static void drawmenuv(void); | ||||||
| static void grabkeyboard(void); | static void match(void); | ||||||
| static void kpress(XKeyEvent *e); |  | ||||||
| static void match(char *pattern); |  | ||||||
| static void readstdin(void); | static void readstdin(void); | ||||||
| static void run(void); |  | ||||||
| static void setup(void); |  | ||||||
| 
 |  | ||||||
| #include "config.h" |  | ||||||
| 
 | 
 | ||||||
| /* variables */ | /* variables */ | ||||||
| static char **argp = NULL; | static char **argp = NULL; | ||||||
| static char *maxname = NULL; | static char *maxname = NULL; | ||||||
| static char *prompt = NULL; | static unsigned int cmdw = 0; | ||||||
| static char text[4096]; |  | ||||||
| static int cmdw = 0; |  | ||||||
| static int promptw = 0; |  | ||||||
| static int screen; |  | ||||||
| static unsigned int lines = 0; | static unsigned int lines = 0; | ||||||
| static unsigned int numlockmask = 0; |  | ||||||
| static unsigned int mw, mh; |  | ||||||
| static unsigned long normcol[ColLast]; |  | ||||||
| static unsigned long selcol[ColLast]; |  | ||||||
| static Bool topbar = True; |  | ||||||
| static DC dc; |  | ||||||
| static Display *dpy; |  | ||||||
| static Item *allitems = NULL;  /* first of all items */ | static Item *allitems = NULL;  /* first of all items */ | ||||||
| static Item *item = NULL;      /* first of pattern matching items */ | static Item *item = NULL;      /* first of pattern matching items */ | ||||||
| static Item *sel = NULL; | static Item *sel = NULL; | ||||||
| static Item *next = NULL; | static Item *next = NULL; | ||||||
| static Item *prev = NULL; | static Item *prev = NULL; | ||||||
| static Item *curr = NULL; | static Item *curr = NULL; | ||||||
| static Window win, root; |  | ||||||
| static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; | static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; | ||||||
| static char *(*fstrstr)(const char *, const char *) = strstr; | static char *(*fstrstr)(const char *, const char *) = strstr; | ||||||
| static void (*calcoffsets)(void) = calcoffsetsh; | static void (*calcoffsets)(void) = calcoffsetsh; | ||||||
|  | @ -85,14 +57,13 @@ appenditem(Item *i, Item **list, Item **last) { | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| calcoffsetsh(void) { | calcoffsetsh(void) { | ||||||
| 	unsigned int x; | 	unsigned int w, x; | ||||||
| 
 | 
 | ||||||
| 	x = promptw + cmdw + (2 * spaceitem); | 	w = promptw + cmdw + textw(&dc, "<") + textw(&dc, ">"); | ||||||
| 	for(next = curr; next; next = next->right) | 	for(x = w, next = curr; next; next = next->right) | ||||||
| 		if((x += MIN(textw(&dc, next->text), mw / 3)) > mw) | 		if((x += MIN(textw(&dc, next->text), mw / 3)) > mw) | ||||||
| 			break; | 			break; | ||||||
| 	x = promptw + cmdw + (2 * spaceitem); | 	for(x = w, prev = curr; prev && prev->left; prev = prev->left) | ||||||
| 	for(prev = curr; prev && prev->left; prev = prev->left) |  | ||||||
| 		if((x += MIN(textw(&dc, prev->left->text), mw / 3)) > mw) | 		if((x += MIN(textw(&dc, prev->left->text), mw / 3)) > mw) | ||||||
| 			break; | 			break; | ||||||
| } | } | ||||||
|  | @ -157,7 +128,7 @@ dinput(void) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| drawmenu(void) { | drawbar(void) { | ||||||
| 	dc.x = 0; | 	dc.x = 0; | ||||||
| 	dc.y = 0; | 	dc.y = 0; | ||||||
| 	dc.w = mw; | 	dc.w = mw; | ||||||
|  | @ -188,7 +159,7 @@ drawmenuh(void) { | ||||||
| 	Item *i; | 	Item *i; | ||||||
| 
 | 
 | ||||||
| 	dc.x += cmdw; | 	dc.x += cmdw; | ||||||
| 	dc.w = spaceitem; | 	dc.w = textw(&dc, "<"); | ||||||
| 	drawtext(&dc, curr->left ? "<" : NULL, normcol); | 	drawtext(&dc, curr->left ? "<" : NULL, normcol); | ||||||
| 	dc.x += dc.w; | 	dc.x += dc.w; | ||||||
| 	for(i = curr; i != next; i = i->right) { | 	for(i = curr; i != next; i = i->right) { | ||||||
|  | @ -196,7 +167,7 @@ drawmenuh(void) { | ||||||
| 		drawtext(&dc, i->text, (sel == i) ? selcol : normcol); | 		drawtext(&dc, i->text, (sel == i) ? selcol : normcol); | ||||||
| 		dc.x += dc.w; | 		dc.x += dc.w; | ||||||
| 	} | 	} | ||||||
| 	dc.w = spaceitem; | 	dc.w = textw(&dc, ">"); | ||||||
| 	dc.x = mw - dc.w; | 	dc.x = mw - dc.w; | ||||||
| 	drawtext(&dc, next ? ">" : NULL, normcol); | 	drawtext(&dc, next ? ">" : NULL, normcol); | ||||||
| } | } | ||||||
|  | @ -217,19 +188,6 @@ drawmenuv(void) { | ||||||
| 	XMoveResizeWindow(dpy, win, wa.x, wa.y + (topbar ? 0 : wa.height - mh), mw, mh); | 	XMoveResizeWindow(dpy, win, wa.x, wa.y + (topbar ? 0 : wa.height - mh), mw, mh); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void |  | ||||||
| grabkeyboard(void) { |  | ||||||
| 	unsigned int len; |  | ||||||
| 
 |  | ||||||
| 	for(len = 1000; len; len--) { |  | ||||||
| 		if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) |  | ||||||
| 		== GrabSuccess) |  | ||||||
| 			return; |  | ||||||
| 		usleep(1000); |  | ||||||
| 	} |  | ||||||
| 	exit(EXIT_FAILURE); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void | void | ||||||
| kpress(XKeyEvent *e) { | kpress(XKeyEvent *e) { | ||||||
| 	char buf[sizeof text]; | 	char buf[sizeof text]; | ||||||
|  | @ -285,7 +243,7 @@ kpress(XKeyEvent *e) { | ||||||
| 			break; | 			break; | ||||||
| 		case XK_u: | 		case XK_u: | ||||||
| 			text[0] = '\0'; | 			text[0] = '\0'; | ||||||
| 			match(text); | 			match(); | ||||||
| 			break; | 			break; | ||||||
| 		case XK_w: | 		case XK_w: | ||||||
| 			if(len == 0) | 			if(len == 0) | ||||||
|  | @ -294,7 +252,7 @@ kpress(XKeyEvent *e) { | ||||||
| 			while(i-- > 0 && text[i] == ' '); | 			while(i-- > 0 && text[i] == ' '); | ||||||
| 			while(i-- > 0 && text[i] != ' '); | 			while(i-- > 0 && text[i] != ' '); | ||||||
| 			text[++i] = '\0'; | 			text[++i] = '\0'; | ||||||
| 			match(text); | 			match(); | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -304,7 +262,7 @@ kpress(XKeyEvent *e) { | ||||||
| 		if(num && !iscntrl((int) buf[0])) { | 		if(num && !iscntrl((int) buf[0])) { | ||||||
| 			memcpy(text + len, buf, num + 1); | 			memcpy(text + len, buf, num + 1); | ||||||
| 			len += num; | 			len += num; | ||||||
| 			match(text); | 			match(); | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| 	case XK_BackSpace: | 	case XK_BackSpace: | ||||||
|  | @ -313,7 +271,7 @@ kpress(XKeyEvent *e) { | ||||||
| 		for(i = 1; len - i > 0 && !IS_UTF8_1ST_CHAR(text[len - i]); i++); | 		for(i = 1; len - i > 0 && !IS_UTF8_1ST_CHAR(text[len - i]); i++); | ||||||
| 		len -= i; | 		len -= i; | ||||||
| 		text[len] = '\0'; | 		text[len] = '\0'; | ||||||
| 		match(text); | 		match(); | ||||||
| 		break; | 		break; | ||||||
| 	case XK_End: | 	case XK_End: | ||||||
| 		while(next) { | 		while(next) { | ||||||
|  | @ -373,24 +331,22 @@ kpress(XKeyEvent *e) { | ||||||
| 		dinput(); | 		dinput(); | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
| 	drawmenu(); | 	drawbar(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| match(char *pattern) { | match(void) { | ||||||
| 	unsigned int plen; | 	unsigned int len; | ||||||
| 	Item *i, *itemend, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; | 	Item *i, *itemend, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; | ||||||
| 
 | 
 | ||||||
| 	if(!pattern) | 	len = strlen(text); | ||||||
| 		return; |  | ||||||
| 	plen = strlen(pattern); |  | ||||||
| 	item = lexact = lprefix = lsubstr = itemend = exactend = prefixend = substrend = NULL; | 	item = lexact = lprefix = lsubstr = itemend = exactend = prefixend = substrend = NULL; | ||||||
| 	for(i = allitems; i; i = i->next) | 	for(i = allitems; i; i = i->next) | ||||||
| 		if(!fstrncmp(pattern, i->text, plen + 1)) | 		if(!fstrncmp(text, i->text, len + 1)) | ||||||
| 			appenditem(i, &lexact, &exactend); | 			appenditem(i, &lexact, &exactend); | ||||||
| 		else if(!fstrncmp(pattern, i->text, plen)) | 		else if(!fstrncmp(text, i->text, len)) | ||||||
| 			appenditem(i, &lprefix, &prefixend); | 			appenditem(i, &lprefix, &prefixend); | ||||||
| 		else if(fstrstr(i->text, pattern)) | 		else if(fstrstr(i->text, text)) | ||||||
| 			appenditem(i, &lsubstr, &substrend); | 			appenditem(i, &lsubstr, &substrend); | ||||||
| 	if(lexact) { | 	if(lexact) { | ||||||
| 		item = lexact; | 		item = lexact; | ||||||
|  | @ -444,103 +400,6 @@ readstdin(void) { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void |  | ||||||
| run(void) { |  | ||||||
| 	XEvent ev; |  | ||||||
| 
 |  | ||||||
| 	/* main event loop */ |  | ||||||
| 	XSync(dpy, False); |  | ||||||
| 	while(!XNextEvent(dpy, &ev)) |  | ||||||
| 		switch(ev.type) { |  | ||||||
| 		case KeyPress: |  | ||||||
| 			kpress(&ev.xkey); |  | ||||||
| 			break; |  | ||||||
| 		case Expose: |  | ||||||
| 			if(ev.xexpose.count == 0) |  | ||||||
| 				drawmenu(); |  | ||||||
| 			break; |  | ||||||
| 		case VisibilityNotify: |  | ||||||
| 			if(ev.xvisibility.state != VisibilityUnobscured) |  | ||||||
| 				XRaiseWindow(dpy, win); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 	exit(EXIT_FAILURE); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void |  | ||||||
| setup(void) { |  | ||||||
| 	int i, j, x, y; |  | ||||||
| #if XINERAMA |  | ||||||
| 	int n; |  | ||||||
| 	XineramaScreenInfo *info = NULL; |  | ||||||
| #endif |  | ||||||
| 	XModifierKeymap *modmap; |  | ||||||
| 	XSetWindowAttributes wa; |  | ||||||
| 
 |  | ||||||
| 	/* init modifier map */ |  | ||||||
| 	modmap = XGetModifierMapping(dpy); |  | ||||||
| 	for(i = 0; i < 8; i++) |  | ||||||
| 		for(j = 0; j < modmap->max_keypermod; j++) { |  | ||||||
| 			if(modmap->modifiermap[i * modmap->max_keypermod + j] |  | ||||||
| 			== XKeysymToKeycode(dpy, XK_Num_Lock)) |  | ||||||
| 				numlockmask = (1 << i); |  | ||||||
| 		} |  | ||||||
| 	XFreeModifiermap(modmap); |  | ||||||
| 
 |  | ||||||
| 	dc.dpy = dpy; |  | ||||||
| 	normcol[ColBG] = getcolor(&dc, normbgcolor); |  | ||||||
| 	normcol[ColFG] = getcolor(&dc, normfgcolor); |  | ||||||
| 	selcol[ColBG] = getcolor(&dc, selbgcolor); |  | ||||||
| 	selcol[ColFG] = getcolor(&dc, selfgcolor); |  | ||||||
| 	initfont(&dc, font); |  | ||||||
| 
 |  | ||||||
| 	/* menu window */ |  | ||||||
| 	wa.override_redirect = True; |  | ||||||
| 	wa.background_pixmap = ParentRelative; |  | ||||||
| 	wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; |  | ||||||
| 
 |  | ||||||
| 	/* menu window geometry */ |  | ||||||
| 	mh = (dc.font.height + 2) * (lines + 1); |  | ||||||
| #if XINERAMA |  | ||||||
| 	if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { |  | ||||||
| 		i = 0; |  | ||||||
| 		if(n > 1) { |  | ||||||
| 			int di; |  | ||||||
| 			unsigned int dui; |  | ||||||
| 			Window dummy; |  | ||||||
| 			if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui)) |  | ||||||
| 				for(i = 0; i < n; i++) |  | ||||||
| 					if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) |  | ||||||
| 						break; |  | ||||||
| 		} |  | ||||||
| 		x = info[i].x_org; |  | ||||||
| 		y = topbar ? info[i].y_org : info[i].y_org + info[i].height - mh; |  | ||||||
| 		mw = info[i].width; |  | ||||||
| 		XFree(info); |  | ||||||
| 	} |  | ||||||
| 	else |  | ||||||
| #endif |  | ||||||
| 	{ |  | ||||||
| 		x = 0; |  | ||||||
| 		y = topbar ? 0 : mh - DisplayHeight(dpy, screen); |  | ||||||
| 		mw = DisplayWidth(dpy, screen); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	win = XCreateWindow(dpy, root, x, y, mw, mh, 0, |  | ||||||
| 			DefaultDepth(dpy, screen), CopyFromParent, |  | ||||||
| 			DefaultVisual(dpy, screen), |  | ||||||
| 			CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); |  | ||||||
| 
 |  | ||||||
| 	setupdraw(&dc, win); |  | ||||||
| 	if(maxname) |  | ||||||
| 		cmdw = MIN(textw(&dc, maxname), mw / 3); |  | ||||||
| 	if(prompt) |  | ||||||
| 		promptw = MIN(textw(&dc, prompt), mw / 5); |  | ||||||
| 	text[0] = '\0'; |  | ||||||
| 	match(text); |  | ||||||
| 	XMapRaised(dpy, win); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| int | int | ||||||
| main(int argc, char *argv[]) { | main(int argc, char *argv[]) { | ||||||
| 	unsigned int i; | 	unsigned int i; | ||||||
|  | @ -600,7 +459,10 @@ main(int argc, char *argv[]) { | ||||||
| 
 | 
 | ||||||
| 	readstdin(); | 	readstdin(); | ||||||
| 	grabkeyboard(); | 	grabkeyboard(); | ||||||
| 	setup(); | 	setup(lines); | ||||||
|  | 	if(maxname) | ||||||
|  | 		cmdw = MIN(textw(&dc, maxname), mw / 3); | ||||||
|  | 	match(); | ||||||
| 	run(); | 	run(); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,30 @@ | ||||||
|  | #include <X11/Xlib.h> | ||||||
|  | #include <draw.h> | ||||||
|  | #include "config.h" | ||||||
|  | 
 | ||||||
|  | /* macros */ | ||||||
|  | #define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH)) | ||||||
|  | #define MIN(a, b)               ((a) < (b) ? (a) : (b)) | ||||||
|  | #define MAX(a, b)               ((a) > (b) ? (a) : (b)) | ||||||
|  | #define IS_UTF8_1ST_CHAR(c)     ((((c) & 0xc0) == 0xc0) || !((c) & 0x80)) | ||||||
|  | 
 | ||||||
|  | /* forward declarations */ | ||||||
|  | void drawbar(void); | ||||||
|  | void grabkeyboard(void); | ||||||
|  | void kpress(XKeyEvent *e); | ||||||
|  | void run(void); | ||||||
|  | void setup(unsigned int lines); | ||||||
|  | 
 | ||||||
|  | /* variables */ | ||||||
|  | extern char *prompt; | ||||||
|  | extern char text[4096]; | ||||||
|  | extern int promptw; | ||||||
|  | extern int screen; | ||||||
|  | extern unsigned int numlockmask; | ||||||
|  | extern unsigned int mw, mh; | ||||||
|  | extern unsigned long normcol[ColLast]; | ||||||
|  | extern unsigned long selcol[ColLast]; | ||||||
|  | extern Bool topbar; | ||||||
|  | extern DC dc; | ||||||
|  | extern Display *dpy; | ||||||
|  | extern Window win, root; | ||||||
		Loading…
	
		Reference in New Issue