From: Daniel Liu Date: Thu, 30 Jul 2020 03:31:32 +0000 (-0400) Subject: xresources X-Git-Url: https://git.danieliu.xyz/?p=dwm.git;a=commitdiff_plain;h=e4db2af451d1b7838ffc7c65f855eb38b40f7cc6;hp=-c xresources --- e4db2af451d1b7838ffc7c65f855eb38b40f7cc6 diff --combined dwm.c index 527bea2,02db465..4edd7ce --- a/dwm.c +++ b/dwm.c @@@ -29,7 -29,6 +29,7 @@@ #include #include #include +#include #include #include #include @@@ -37,6 -36,7 +37,7 @@@ #include #include #include + #include #ifdef XINERAMA #include #endif /* XINERAMA */ @@@ -143,6 -143,19 +144,19 @@@ typedef struct int monitor; } Rule; + /* Xresources preferences */ + enum resource_type { + STRING = 0, + INTEGER = 1, + FLOAT = 2 + }; + + typedef struct { + char *name; + enum resource_type type; + void *dst; + } ResourcePref; + /* function declarations */ static void applyrules(Client *c); static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); @@@ -196,7 -209,6 +210,7 @@@ static void resizeclient(Client *c, in static void resizemouse(const Arg *arg); static void restack(Monitor *m); static void run(void); +static void runautostart(void); static void scan(void); static int sendevent(Client *c, Atom proto); static void sendmon(Client *c, Monitor *m); @@@ -238,13 -250,11 +252,15 @@@ static int xerror(Display *dpy, XErrorE static int xerrordummy(Display *dpy, XErrorEvent *ee); static int xerrorstart(Display *dpy, XErrorEvent *ee); static void zoom(const Arg *arg); + static void load_xresources(void); + static void resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst); /* variables */ +static const char autostartblocksh[] = "autostart_blocking.sh"; +static const char autostartsh[] = "autostart.sh"; static const char broken[] = "broken"; +static const char dwmdir[] = "dwm"; +static const char localshare[] = ".local/share"; static char stext[256]; static int screen; static int sw, sh; /* X display screen geometry width, height */ @@@ -1390,83 -1400,6 +1406,83 @@@ run(void handler[ev.type](&ev); /* call handler */ } +void +runautostart(void) +{ + char *pathpfx; + char *path; + char *xdgdatahome; + char *home; + struct stat sb; + + if ((home = getenv("HOME")) == NULL) + /* this is almost impossible */ + return; + + /* if $XDG_DATA_HOME is set and not empty, use $XDG_DATA_HOME/dwm, + * otherwise use ~/.local/share/dwm as autostart script directory + */ + xdgdatahome = getenv("XDG_DATA_HOME"); + if (xdgdatahome != NULL && *xdgdatahome != '\0') { + /* space for path segments, separators and nul */ + pathpfx = ecalloc(1, strlen(xdgdatahome) + strlen(dwmdir) + 2); + + if (sprintf(pathpfx, "%s/%s", xdgdatahome, dwmdir) <= 0) { + free(pathpfx); + return; + } + } else { + /* space for path segments, separators and nul */ + pathpfx = ecalloc(1, strlen(home) + strlen(localshare) + + strlen(dwmdir) + 3); + + if (sprintf(pathpfx, "%s/%s/%s", home, localshare, dwmdir) < 0) { + free(pathpfx); + return; + } + } + + /* check if the autostart script directory exists */ + if (! (stat(pathpfx, &sb) == 0 && S_ISDIR(sb.st_mode))) { + /* the XDG conformant path does not exist or is no directory + * so we try ~/.dwm instead + */ + char *pathpfx_new = realloc(pathpfx, strlen(home) + strlen(dwmdir) + 3); + if(pathpfx_new == NULL) { + free(pathpfx); + return; + } + pathpfx = pathpfx_new; + + if (sprintf(pathpfx, "%s/.%s", home, dwmdir) <= 0) { + free(pathpfx); + return; + } + } + + /* try the blocking script first */ + path = ecalloc(1, strlen(pathpfx) + strlen(autostartblocksh) + 2); + if (sprintf(path, "%s/%s", pathpfx, autostartblocksh) <= 0) { + free(path); + free(pathpfx); + } + + if (access(path, X_OK) == 0) + system(path); + + /* now the non-blocking script */ + if (sprintf(path, "%s/%s", pathpfx, autostartsh) <= 0) { + free(path); + free(pathpfx); + } + + if (access(path, X_OK) == 0) + system(strcat(path, " &")); + + free(pathpfx); + free(path); +} + void scan(void) { @@@ -2223,6 -2156,60 +2239,60 @@@ zoom(const Arg *arg pop(c); } + void + resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst) + { + char *sdst = NULL; + int *idst = NULL; + float *fdst = NULL; + + sdst = dst; + idst = dst; + fdst = dst; + + char fullname[256]; + char *type; + XrmValue ret; + + snprintf(fullname, sizeof(fullname), "%s.%s", "dwm", name); + fullname[sizeof(fullname) - 1] = '\0'; + + XrmGetResource(db, fullname, "*", &type, &ret); + if (!(ret.addr == NULL || strncmp("String", type, 64))) + { + switch (rtype) { + case STRING: + strcpy(sdst, ret.addr); + break; + case INTEGER: + *idst = strtoul(ret.addr, NULL, 10); + break; + case FLOAT: + *fdst = strtof(ret.addr, NULL); + break; + } + } + } + + void + load_xresources(void) + { + Display *display; + char *resm; + XrmDatabase db; + ResourcePref *p; + + display = XOpenDisplay(NULL); + resm = XResourceManagerString(display); + if (!resm) + return; + + db = XrmGetStringDatabase(resm); + for (p = resources; p < resources + LENGTH(resources); p++) + resource_load(db, p->name, p->type, p->dst); + XCloseDisplay(display); + } + int main(int argc, char *argv[]) { @@@ -2235,13 -2222,14 +2305,15 @@@ if (!(dpy = XOpenDisplay(NULL))) die("dwm: cannot open display"); checkotherwm(); + XrmInitialize(); + load_xresources(); setup(); #ifdef __OpenBSD__ if (pledge("stdio rpath proc exec", NULL) == -1) die("pledge"); #endif /* __OpenBSD__ */ scan(); + runautostart(); run(); cleanup(); XCloseDisplay(dpy);