parse resources before command-line options
This commit is contained in:
		
							
								
								
									
										206
									
								
								xmenu.c
									
									
									
									
									
								
							
							
						
						
									
										206
									
								
								xmenu.c
									
									
									
									
									
								
							| @@ -23,6 +23,8 @@ static int screen; | ||||
| static Visual *visual; | ||||
| static Window rootwin; | ||||
| static Colormap colormap; | ||||
| static XrmDatabase xdb; | ||||
| static char *xrm; | ||||
| static struct DC dc; | ||||
| static struct Monitor mon; | ||||
| static Atom utf8string; | ||||
| @@ -87,6 +89,85 @@ error: | ||||
| 	errx(1, "improper position: %s", optarg); | ||||
| } | ||||
|  | ||||
| /* get configuration from X resources */ | ||||
| static void | ||||
| getresources(void) | ||||
| { | ||||
| 	char *type; | ||||
| 	XrmValue xval; | ||||
|  | ||||
| 	if (xrm == NULL || xdb == NULL) | ||||
| 		return; | ||||
|  | ||||
| 	if (XrmGetResource(xdb, "xmenu.borderWidth", "*", &type, &xval) == True) | ||||
| 		GETNUM(config.border_pixels, xval.addr) | ||||
| 	if (XrmGetResource(xdb, "xmenu.separatorWidth", "*", &type, &xval) == True) | ||||
| 		GETNUM(config.separator_pixels, xval.addr) | ||||
| 	if (XrmGetResource(xdb, "xmenu.height", "*", &type, &xval) == True) | ||||
| 		GETNUM(config.height_pixels, xval.addr) | ||||
| 	if (XrmGetResource(xdb, "xmenu.width", "*", &type, &xval) == True) | ||||
| 		GETNUM(config.width_pixels, xval.addr) | ||||
| 	if (XrmGetResource(xdb, "xmenu.gap", "*", &type, &xval) == True) | ||||
| 		GETNUM(config.gap_pixels, xval.addr) | ||||
| 	if (XrmGetResource(xdb, "xmenu.background", "*", &type, &xval) == True) | ||||
| 		config.background_color = xval.addr; | ||||
| 	if (XrmGetResource(xdb, "xmenu.foreground", "*", &type, &xval) == True) | ||||
| 		config.foreground_color = xval.addr; | ||||
| 	if (XrmGetResource(xdb, "xmenu.selbackground", "*", &type, &xval) == True) | ||||
| 		config.selbackground_color = xval.addr; | ||||
| 	if (XrmGetResource(xdb, "xmenu.selforeground", "*", &type, &xval) == True) | ||||
| 		config.selforeground_color = xval.addr; | ||||
| 	if (XrmGetResource(xdb, "xmenu.separator", "*", &type, &xval) == True) | ||||
| 		config.separator_color = xval.addr; | ||||
| 	if (XrmGetResource(xdb, "xmenu.border", "*", &type, &xval) == True) | ||||
| 		config.border_color = xval.addr; | ||||
| 	if (XrmGetResource(xdb, "xmenu.font", "*", &type, &xval) == True) | ||||
| 		config.font = xval.addr; | ||||
| 	if (XrmGetResource(xdb, "xmenu.alignment", "*", &type, &xval) == True) { | ||||
| 		if (strcasecmp(xval.addr, "center") == 0) | ||||
| 			config.alignment = CenterAlignment; | ||||
| 		else if (strcasecmp(xval.addr, "left") == 0) | ||||
| 			config.alignment = LeftAlignment; | ||||
| 		else if (strcasecmp(xval.addr, "right") == 0) | ||||
| 			config.alignment = RightAlignment; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* get configuration from command-line options */ | ||||
| static char * | ||||
| getoptions(int argc, char *argv[]) | ||||
| { | ||||
| 	int ch; | ||||
|  | ||||
| 	while ((ch = getopt(argc, argv, "ip:rw")) != -1) { | ||||
| 		switch (ch) { | ||||
| 		case 'i': | ||||
| 			iflag = 1; | ||||
| 			break; | ||||
| 		case 'p': | ||||
| 			pflag = 1; | ||||
| 			parseposition(optarg); | ||||
| 			break; | ||||
| 		case 'r': | ||||
| 			rflag = 1; | ||||
| 			break; | ||||
| 		case 'w': | ||||
| 			wflag = 1; | ||||
| 			break; | ||||
| 		default: | ||||
| 			usage(); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	argc -= optind; | ||||
| 	argv += optind; | ||||
| 	if (argc > 1) | ||||
| 		usage(); | ||||
| 	else if (argc == 1) | ||||
| 		return *argv; | ||||
| 	return PROGNAME; | ||||
| } | ||||
|  | ||||
| /* parse font string */ | ||||
| static void | ||||
| parsefonts(const char *s) | ||||
| @@ -183,63 +264,6 @@ initmonitor(void) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* read xrdb for configuration options */ | ||||
| static void | ||||
| initresources(void) | ||||
| { | ||||
| 	long n; | ||||
| 	char *type; | ||||
| 	char *xrm; | ||||
| 	XrmDatabase xdb; | ||||
| 	XrmValue xval; | ||||
|  | ||||
| 	XrmInitialize(); | ||||
| 	if ((xrm = XResourceManagerString(dpy)) == NULL) | ||||
| 		return; | ||||
|  | ||||
| 	xdb = XrmGetStringDatabase(xrm); | ||||
|  | ||||
| 	if (XrmGetResource(xdb, "xmenu.borderWidth", "*", &type, &xval) == True) | ||||
| 		if ((n = strtol(xval.addr, NULL, 10)) > 0) | ||||
| 			config.border_pixels = n; | ||||
| 	if (XrmGetResource(xdb, "xmenu.separatorWidth", "*", &type, &xval) == True) | ||||
| 		if ((n = strtol(xval.addr, NULL, 10)) > 0) | ||||
| 			config.separator_pixels = n; | ||||
| 	if (XrmGetResource(xdb, "xmenu.height", "*", &type, &xval) == True) | ||||
| 		if ((n = strtol(xval.addr, NULL, 10)) > 0) | ||||
| 			config.height_pixels = n; | ||||
| 	if (XrmGetResource(xdb, "xmenu.width", "*", &type, &xval) == True) | ||||
| 		if ((n = strtol(xval.addr, NULL, 10)) > 0) | ||||
| 			config.width_pixels = n; | ||||
| 	if (XrmGetResource(xdb, "xmenu.gap", "*", &type, &xval) == True) | ||||
| 		if ((n = strtol(xval.addr, NULL, 10)) > 0) | ||||
| 			config.gap_pixels = n; | ||||
| 	if (XrmGetResource(xdb, "xmenu.background", "*", &type, &xval) == True) | ||||
| 		config.background_color = strdup(xval.addr); | ||||
| 	if (XrmGetResource(xdb, "xmenu.foreground", "*", &type, &xval) == True) | ||||
| 		config.foreground_color = strdup(xval.addr); | ||||
| 	if (XrmGetResource(xdb, "xmenu.selbackground", "*", &type, &xval) == True) | ||||
| 		config.selbackground_color = strdup(xval.addr); | ||||
| 	if (XrmGetResource(xdb, "xmenu.selforeground", "*", &type, &xval) == True) | ||||
| 		config.selforeground_color = strdup(xval.addr); | ||||
| 	if (XrmGetResource(xdb, "xmenu.separator", "*", &type, &xval) == True) | ||||
| 		config.separator_color = strdup(xval.addr); | ||||
| 	if (XrmGetResource(xdb, "xmenu.border", "*", &type, &xval) == True) | ||||
| 		config.border_color = strdup(xval.addr); | ||||
| 	if (XrmGetResource(xdb, "xmenu.font", "*", &type, &xval) == True) | ||||
| 		config.font = strdup(xval.addr); | ||||
| 	if (XrmGetResource(xdb, "xmenu.alignment", "*", &type, &xval) == True) { | ||||
| 		if (strcasecmp(xval.addr, "center") == 0) | ||||
| 			config.alignment = CenterAlignment; | ||||
| 		else if (strcasecmp(xval.addr, "left") == 0) | ||||
| 			config.alignment = LeftAlignment; | ||||
| 		else if (strcasecmp(xval.addr, "right") == 0) | ||||
| 			config.alignment = RightAlignment; | ||||
| 	} | ||||
|  | ||||
| 	XrmDestroyDatabase(xdb); | ||||
| } | ||||
|  | ||||
| /* init draw context */ | ||||
| static void | ||||
| initdc(void) | ||||
| @@ -745,6 +769,14 @@ grabkeyboard(void) | ||||
| 	errx(1, "could not grab keyboard"); | ||||
| } | ||||
|  | ||||
| /* ungrab pointer and keyboard */ | ||||
| static void | ||||
| ungrab(void) | ||||
| { | ||||
| 	XUngrabPointer(dpy, CurrentTime); | ||||
| 	XUngrabKeyboard(dpy, CurrentTime); | ||||
| } | ||||
|  | ||||
| /* load and scale icon */ | ||||
| static Imlib_Image | ||||
| loadicon(const char *file) | ||||
| @@ -1238,27 +1270,21 @@ cleanmenu(struct Menu *menu) | ||||
| 	free(menu); | ||||
| } | ||||
|  | ||||
| /* cleanup X and exit */ | ||||
| /* cleanup draw context */ | ||||
| static void | ||||
| cleanup(void) | ||||
| cleandc(void) | ||||
| { | ||||
| 	size_t i; | ||||
|  | ||||
| 	XUngrabPointer(dpy, CurrentTime); | ||||
| 	XUngrabKeyboard(dpy, CurrentTime); | ||||
|  | ||||
| 	XftColorFree(dpy, visual, colormap, &dc.normal[ColorBG]); | ||||
| 	XftColorFree(dpy, visual, colormap, &dc.normal[ColorFG]); | ||||
| 	XftColorFree(dpy, visual, colormap, &dc.selected[ColorBG]); | ||||
| 	XftColorFree(dpy, visual, colormap, &dc.selected[ColorFG]); | ||||
| 	XftColorFree(dpy, visual, colormap, &dc.separator); | ||||
| 	XftColorFree(dpy, visual, colormap, &dc.border); | ||||
|  | ||||
| 	for (i = 0; i < dc.nfonts; i++) | ||||
| 		XftFontClose(dpy, dc.fonts[i]); | ||||
|  | ||||
| 	XFreeGC(dpy, dc.gc); | ||||
| 	XCloseDisplay(dpy); | ||||
| } | ||||
|  | ||||
| /* xmenu: generate menu from stdin and print selected entry to stdout */ | ||||
| @@ -1267,33 +1293,6 @@ main(int argc, char *argv[]) | ||||
| { | ||||
| 	struct Menu *rootmenu; | ||||
| 	XClassHint classh; | ||||
| 	int ch; | ||||
|  | ||||
| 	while ((ch = getopt(argc, argv, "ip:rw")) != -1) { | ||||
| 		switch (ch) { | ||||
| 		case 'i': | ||||
| 			iflag = 1; | ||||
| 			break; | ||||
| 		case 'p': | ||||
| 			pflag = 1; | ||||
| 			parseposition(optarg); | ||||
| 			break; | ||||
| 		case 'r': | ||||
| 			rflag = 1; | ||||
| 			break; | ||||
| 		case 'w': | ||||
| 			wflag = 1; | ||||
| 			break; | ||||
| 		default: | ||||
| 			usage(); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	argc -= optind; | ||||
| 	argv += optind; | ||||
|  | ||||
| 	if (argc > 1) | ||||
| 		usage(); | ||||
|  | ||||
| 	/* open connection to server and set X variables */ | ||||
| 	if ((dpy = XOpenDisplay(NULL)) == NULL) | ||||
| @@ -1302,6 +1301,14 @@ main(int argc, char *argv[]) | ||||
| 	visual = DefaultVisual(dpy, screen); | ||||
| 	rootwin = RootWindow(dpy, screen); | ||||
| 	colormap = DefaultColormap(dpy, screen); | ||||
| 	XrmInitialize(); | ||||
| 	if ((xrm = XResourceManagerString(dpy)) != NULL) | ||||
| 		xdb = XrmGetStringDatabase(xrm); | ||||
|  | ||||
| 	/* get configuration */ | ||||
| 	getresources(); | ||||
| 	classh.res_class = PROGNAME; | ||||
| 	classh.res_name = getoptions(argc, argv); | ||||
|  | ||||
| 	/* imlib2 stuff */ | ||||
| 	if (!iflag) { | ||||
| @@ -1314,18 +1321,10 @@ main(int argc, char *argv[]) | ||||
|  | ||||
| 	/* initializers */ | ||||
| 	initmonitor(); | ||||
| 	initresources(); | ||||
| 	initdc(); | ||||
| 	initiconsize(); | ||||
| 	initatoms(); | ||||
|  | ||||
| 	/* set window class */ | ||||
| 	classh.res_class = PROGNAME; | ||||
| 	if (argc == 1) | ||||
| 		classh.res_name = *argv; | ||||
| 	else | ||||
| 		classh.res_name = PROGNAME; | ||||
|  | ||||
| 	/* generate menus and set them up */ | ||||
| 	rootmenu = parsestdin(); | ||||
| 	if (rootmenu == NULL) | ||||
| @@ -1341,9 +1340,12 @@ main(int argc, char *argv[]) | ||||
| 	/* run event loop */ | ||||
| 	run(rootmenu); | ||||
|  | ||||
| 	/* freeing stuff */ | ||||
| 	/* clean stuff */ | ||||
| 	ungrab(); | ||||
| 	cleanmenu(rootmenu); | ||||
| 	cleanup(); | ||||
| 	cleandc(); | ||||
| 	XrmDestroyDatabase(xdb); | ||||
| 	XCloseDisplay(dpy); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|   | ||||
							
								
								
									
										5
									
								
								xmenu.h
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								xmenu.h
									
									
									
									
									
								
							| @@ -11,6 +11,11 @@ enum {LeftAlignment, CenterAlignment, RightAlignment}; | ||||
| #define MAX(x,y)            ((x)>(y)?(x):(y)) | ||||
| #define MIN(x,y)            ((x)<(y)?(x):(y)) | ||||
| #define BETWEEN(x, a, b)    ((a) <= (x) && (x) <= (b)) | ||||
| #define GETNUM(n, s) { \ | ||||
| 	unsigned long __TMP__; \ | ||||
| 	if ((__TMP__ = strtoul((s), NULL, 10)) < INT_MAX) \ | ||||
| 		(n) = __TMP__; \ | ||||
| 	} | ||||
|  | ||||
| /* color enum */ | ||||
| enum {ColorFG, ColorBG, ColorLast}; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user