commit 5440d9166a67ff7f69efda1a9e3e3ebaa6255034
parent c2c4fca49a16ab20986e905d793aa484ca662abf
Author: Lucas de Sena <lucas@seninha.org>
Date: Sat, 8 Apr 2023 15:12:24 -0300
use quarks for querying resources
Diffstat:
M | shod.c | | | 28 | ++++++++++++++++++++++++---- |
M | shod.h | | | 45 | +++++++++++++++++++++++++++++++++++++++++++++ |
M | xdraw.c | | | 114 | ++++++++++++++++++++++++++++++++++++++++++------------------------------------- |
M | xevents.c | | | 199 | ++++++++++++++++++++++++++++++++++++++++++------------------------------------- |
M | xutil.c | | | 13 | +++++++++++++ |
M | xutil.h | | | 1 | + |
6 files changed, 249 insertions(+), 151 deletions(-)
diff --git a/shod.c b/shod.c
@@ -183,6 +183,28 @@ initcursors(void)
wm.cursors[CURSOR_PIRATE] = XCreateFontCursor(dpy, XC_pirate);
}
+static void
+initxrm(void)
+{
+ static struct {
+ const char *class, *name;
+ } resourceids[NRESOURCES] = {
+#define X(res, s1, s2) [res] = { .class = s1, .name = s2, },
+ RESOURCES
+#undef X
+ };
+ int i;
+
+ XrmInitialize();
+ wm.application.class = XrmPermStringToQuark("Shod");
+ wm.application.name = XrmPermStringToQuark("shod");
+ for (i = 0; i < NRESOURCES; i++) {
+ wm.resources[i].class = XrmPermStringToQuark(resourceids[i].class);
+ wm.resources[i].name = XrmPermStringToQuark(resourceids[i].name);
+ }
+ setresources(XResourceManagerString(dpy));
+}
+
/* set up root window */
static void
initroot(void)
@@ -324,7 +346,7 @@ int
main(int argc, char *argv[])
{
XEvent ev;
- char *filename, *wmname, *xrm;
+ char *filename, *wmname;
if (!setlocale(LC_ALL, "") || !XSupportsLocale())
warnx("warning: no locale support");
@@ -332,9 +354,6 @@ main(int argc, char *argv[])
checkotherwm();
moninit();
xinitvisual();
- XrmInitialize();
- xrm = XResourceManagerString(dpy);
- setresources(xrm);
clientswa.colormap = colormap;
clientswa.border_pixel = BlackPixel(dpy, screen);
clientswa.background_pixel = BlackPixel(dpy, screen);
@@ -364,6 +383,7 @@ main(int argc, char *argv[])
initsignal();
initcursors();
initatoms();
+ initxrm();
initroot();
initdummywindows();
initdock();
diff --git a/shod.h b/shod.h
@@ -27,6 +27,43 @@
} \
}
+#define RESOURCES \
+ /* CLASS NAME */\
+ X(RES_ANY, "?", "?" )\
+ X(RES_TYPE, "Type", "type" )\
+ X(RES_STATE, "State", "state" )\
+ X(RES_DOCK_POS, "Dockpos", "dockpos" )\
+ X(RES_FACE_NAME, "FaceName", "faceName" )\
+ X(RES_FOREGROUND, "Foreground", "foreground" )\
+ X(RES_DOCK_BACKGROUND, "DockBackground", "dockBackground" )\
+ X(RES_DOCK_BORDER, "DockBorder", "dockBorder" )\
+ X(RES_ACTIVE_BG, "ActiveBackground", "activeBackground" )\
+ X(RES_ACTIVE_TOP, "ActiveTopShadowColor", "activeTopShadowColor" )\
+ X(RES_ACTIVE_BOT, "ActiveBottomShadowColor", "activeBottomShadowColor" )\
+ X(RES_INACTIVE_BG, "InactiveBackground", "inactiveBackground" )\
+ X(RES_INACTIVE_TOP, "InactiveTopShadowColor", "inactiveTopShadowColor" )\
+ X(RES_INACTIVE_BOT, "InactiveBottomShadowColor", "inactiveBottomShadowColor" )\
+ X(RES_URGENT_BG, "UrgentBackground", "urgentBackground" )\
+ X(RES_URGENT_TOP, "UrgentTopShadowColor", "urgentTopShadowColor" )\
+ X(RES_URGENT_BOT, "UrgentBottomShadowColor", "urgentBottomShadowColor" )\
+ X(RES_BORDER_WIDTH, "BorderWidth", "borderWidth" )\
+ X(RES_SHADOW_WIDTH, "ShadowThickness", "shadowThickness" )\
+ X(RES_TITLE_WIDTH, "TitleWidth", "titleWidth" )\
+ X(RES_DOCK_WIDTH, "DockWidth", "dockWidth" )\
+ X(RES_DOCK_SPACE, "DockSpace", "dockSpace" )\
+ X(RES_DOCK_GRAVITY, "DockGravity", "dockGravity" )\
+ X(RES_NOTIFY_GAP, "NotifGap", "notifGap" )\
+ X(RES_NOTIFY_GRAVITY, "NotifGravity", "notifGravity" )\
+ X(RES_NDESKTOPS, "NumOfDesktops", "numOfDesktops" )\
+ X(RES_SNAP_PROXIMITY, "SnapProximity", "snapProximity" )
+
+enum Resource {
+#define X(res, class, name) res,
+ RESOURCES
+ NRESOURCES
+#undef X
+};
+
enum {
/* border array indices */
BORDER_N,
@@ -541,6 +578,14 @@ struct WM {
int nclients; /* total number of container windows */
/*
+ * Resources
+ */
+ struct {
+ XrmClass class;
+ XrmName name;
+ } application, resources[NRESOURCES];
+
+ /*
* Xrandr information.
*/
int xrandr; /* whether Xrandr is being used */
diff --git a/xdraw.c b/xdraw.c
@@ -784,73 +784,81 @@ cleantheme(void)
XFreeGC(dpy, gc);
}
+static char *
+queryrdb(int res)
+{
+ XrmClass class[] = { wm.application.class, wm.resources[res].class, NULLQUARK };
+ XrmName name[] = { wm.application.name, wm.resources[res].name, NULLQUARK };
+
+ return getresource(xdb, class, name);
+}
+
void
setresources(char *xrm)
{
long n;
- char *type;
- XrmValue xval;
+ char *value;
if (xrm == NULL || (xdb = XrmGetStringDatabase(xrm)) == NULL)
return;
- if (XrmGetResource(xdb, "shod.faceName", "*", &type, &xval) == True)
- config.font = xval.addr;
- if (XrmGetResource(xdb, "shod.foreground", "*", &type, &xval) == True)
- config.foreground = xval.addr;
-
- if (XrmGetResource(xdb, "shod.dockBackground", "*", &type, &xval) == True)
- config.dockcolors[COLOR_DEF] = xval.addr;
- if (XrmGetResource(xdb, "shod.dockBorder", "*", &type, &xval) == True)
- config.dockcolors[COLOR_ALT] = xval.addr;
-
- if (XrmGetResource(xdb, "shod.activeBackground", "*", &type, &xval) == True)
- config.bordercolors[FOCUSED][COLOR_MID] = xval.addr;
- if (XrmGetResource(xdb, "shod.activeTopShadowColor", "*", &type, &xval) == True)
- config.bordercolors[FOCUSED][COLOR_LIGHT] = xval.addr;
- if (XrmGetResource(xdb, "shod.activeBottomShadowColor", "*", &type, &xval) == True)
- config.bordercolors[FOCUSED][COLOR_DARK] = xval.addr;
-
- if (XrmGetResource(xdb, "shod.inactiveBackground", "*", &type, &xval) == True)
- config.bordercolors[UNFOCUSED][COLOR_MID] = xval.addr;
- if (XrmGetResource(xdb, "shod.inactiveTopShadowColor", "*", &type, &xval) == True)
- config.bordercolors[UNFOCUSED][COLOR_LIGHT] = xval.addr;
- if (XrmGetResource(xdb, "shod.inactiveBottomShadowColor", "*", &type, &xval) == True)
- config.bordercolors[UNFOCUSED][COLOR_DARK] = xval.addr;
-
- if (XrmGetResource(xdb, "shod.urgentBackground", "*", &type, &xval) == True)
- config.bordercolors[URGENT][COLOR_MID] = xval.addr;
- if (XrmGetResource(xdb, "shod.urgentTopShadowColor", "*", &type, &xval) == True)
- config.bordercolors[URGENT][COLOR_LIGHT] = xval.addr;
- if (XrmGetResource(xdb, "shod.urgentBottomShadowColor", "*", &type, &xval) == True)
- config.bordercolors[URGENT][COLOR_DARK] = xval.addr;
-
- if (XrmGetResource(xdb, "shod.borderWidth", "*", &type, &xval) == True)
- if ((n = strtol(xval.addr, NULL, 10)) > 0 && n < 100)
+ if ((value = queryrdb(RES_FACE_NAME)) != NULL)
+ config.font = value;
+ if ((value = queryrdb(RES_FOREGROUND)) != NULL)
+ config.foreground = value;
+
+ if ((value = queryrdb(RES_DOCK_BACKGROUND)) != NULL)
+ config.dockcolors[COLOR_DEF] = value;
+ if ((value = queryrdb(RES_DOCK_BORDER)) != NULL)
+ config.dockcolors[COLOR_ALT] = value;
+
+ if ((value = queryrdb(RES_ACTIVE_BG)) != NULL)
+ config.bordercolors[FOCUSED][COLOR_MID] = value;
+ if ((value = queryrdb(RES_ACTIVE_TOP)) != NULL)
+ config.bordercolors[FOCUSED][COLOR_LIGHT] = value;
+ if ((value = queryrdb(RES_ACTIVE_BOT)) != NULL)
+ config.bordercolors[FOCUSED][COLOR_DARK] = value;
+
+ if ((value = queryrdb(RES_INACTIVE_BG)) != NULL)
+ config.bordercolors[UNFOCUSED][COLOR_MID] = value;
+ if ((value = queryrdb(RES_INACTIVE_TOP)) != NULL)
+ config.bordercolors[UNFOCUSED][COLOR_LIGHT] = value;
+ if ((value = queryrdb(RES_INACTIVE_BOT)) != NULL)
+ config.bordercolors[UNFOCUSED][COLOR_DARK] = value;
+
+ if ((value = queryrdb(RES_URGENT_BG)) != NULL)
+ config.bordercolors[URGENT][COLOR_MID] = value;
+ if ((value = queryrdb(RES_URGENT_TOP)) != NULL)
+ config.bordercolors[URGENT][COLOR_LIGHT] = value;
+ if ((value = queryrdb(RES_URGENT_BOT)) != NULL)
+ config.bordercolors[URGENT][COLOR_DARK] = value;
+
+ if ((value = queryrdb(RES_BORDER_WIDTH)) != NULL)
+ if ((n = strtol(value, NULL, 10)) > 0 && n < 100)
config.borderwidth = n;
- if (XrmGetResource(xdb, "shod.shadowThickness", "*", &type, &xval) == True)
- if ((n = strtol(xval.addr, NULL, 10)) > 0 && n < 100)
+ if ((value = queryrdb(RES_SHADOW_WIDTH)) != NULL)
+ if ((n = strtol(value, NULL, 10)) > 0 && n < 100)
config.shadowthickness = n;
- if (XrmGetResource(xdb, "shod.titleWidth", "*", &type, &xval) == True)
- if ((n = strtol(xval.addr, NULL, 10)) > 0 && n < 100)
+ if ((value = queryrdb(RES_TITLE_WIDTH)) != NULL)
+ if ((n = strtol(value, NULL, 10)) > 0 && n < 100)
config.titlewidth = n;
- if (XrmGetResource(xdb, "shod.dockWidth", "*", &type, &xval) == True)
- if ((n = strtol(xval.addr, NULL, 10)) > 0)
+ if ((value = queryrdb(RES_DOCK_WIDTH)) != NULL)
+ if ((n = strtol(value, NULL, 10)) > 0)
config.dockwidth = n;
- if (XrmGetResource(xdb, "shod.dockSpace", "*", &type, &xval) == True)
- if ((n = strtol(xval.addr, NULL, 10)) > 0)
+ if ((value = queryrdb(RES_DOCK_SPACE)) != NULL)
+ if ((n = strtol(value, NULL, 10)) > 0)
config.dockspace = n;
- if (XrmGetResource(xdb, "shod.dockGravity", "*", &type, &xval) == True)
- config.dockgravity = xval.addr;
- if (XrmGetResource(xdb, "shod.notifGap", "*", &type, &xval) == True)
- if ((n = strtol(xval.addr, NULL, 10)) > 0)
+ if ((value = queryrdb(RES_DOCK_GRAVITY)) != NULL)
+ config.dockgravity = value;
+ if ((value = queryrdb(RES_NOTIFY_GAP)) != NULL)
+ if ((n = strtol(value, NULL, 10)) > 0)
config.notifgap = n;
- if (XrmGetResource(xdb, "shod.notifGravity", "*", &type, &xval) == True)
- config.notifgravity = xval.addr;
- if (XrmGetResource(xdb, "shod.numOfDesktops", "*", &type, &xval) == True)
- if ((n = strtol(xval.addr, NULL, 10)) > 0 && n < 100)
+ if ((value = queryrdb(RES_NOTIFY_GRAVITY)) != NULL)
+ config.notifgravity = value;
+ if ((value = queryrdb(RES_NDESKTOPS)) != NULL)
+ if ((n = strtol(value, NULL, 10)) > 0 && n < 100)
config.ndesktops = n;
- if (XrmGetResource(xdb, "shod.snapProximity", "*", &type, &xval) == True)
- if ((n = strtol(xval.addr, NULL, 10)) >= 0 && n < 100)
+ if ((value = queryrdb(RES_SNAP_PROXIMITY)) != NULL)
+ if ((n = strtol(value, NULL, 10)) >= 0 && n < 100)
config.snap = n;
}
diff --git a/xevents.c b/xevents.c
@@ -324,27 +324,27 @@ getstate(Window w)
return result;
}
-/* get text property from window; return `Success` on success */
-static int
-gettextprop(Window win, Atom atom, char *buf, size_t size)
+static char *
+gettextprop(Window win, Atom atom)
{
- XTextProperty tprop;
+ XTextProperty tprop = { .value = NULL };
int count;
char **list = NULL;
+ char *s = NULL;
- if (buf == NULL || size == 0)
- return BadLength;
- buf[0] = '\0';
- if (!XGetTextProperty(dpy, win, &tprop, atom) || tprop.nitems == 0)
- return BadAlloc;
- if (XmbTextPropertyToTextList(dpy, &tprop, &list, &count) != Success ||
- count < 1 || list == NULL || *list == NULL)
- return BadAlloc;
- strncpy(buf, *list, size - 1);
- buf[size - 1] = '\0';
+ if (!XGetTextProperty(dpy, win, &tprop, atom))
+ goto error;
+ if (tprop.nitems == 0)
+ goto error;
+ if (XmbTextPropertyToTextList(dpy, &tprop, &list, &count) != Success)
+ goto error;
+ if (count < 1 || list == NULL || *list == NULL)
+ goto error;
+ s = strdup(list[0]);
+error:
XFreeStringList(list);
XFree(tprop.value);
- return Success;
+ return s;
}
/* get motif/GNUstep hints from window; return -1 on error */
@@ -376,27 +376,26 @@ getextrahints(Window win, Atom prop, unsigned long nmemb, size_t size, void *hin
return ret;
}
+#define STRCMP(a, b) ((a) != NULL && (b) != NULL && strcmp((a), (b)) == 0)
+
/* get window info based on its type */
static int
getwintype(Window *win_ret, Window *leader, struct Tab **tab, int *state, XRectangle *rect)
{
/* rules for identifying windows */
- enum { CLASS = 0, INSTANCE = 1, ROLE = 2 };
- char *rule[] = { "_", "_", "_" };
-
+ enum { I_APP, I_CLASS, I_INSTANCE, I_ROLE, I_RESOURCE, I_NULL, I_LAST };
+ XrmClass class[I_LAST];
+ XrmName name[I_LAST];
struct MwmHints mwmhints = { 0 };
struct GNUHints gnuhints = { 0 };
- XClassHint classh;
+ XClassHint classh = { .res_class = NULL, .res_name = NULL };
XWMHints *wmhints;
- XrmValue xval;
Window win;
Atom prop;
size_t i;
long n;
int type, isdockapp, pos;
- char *ds;
- char buf[NAMEMAXLEN];
- char role[NAMEMAXLEN];
+ char *role, *value;
pos = 0;
win = *win_ret;
@@ -405,21 +404,16 @@ getwintype(Window *win_ret, Window *leader, struct Tab **tab, int *state, XRecta
type = TYPE_UNKNOWN;
classh.res_class = NULL;
classh.res_name = NULL;
- if (gettextprop(win, atoms[WM_WINDOW_ROLE], role, NAMEMAXLEN) == Success)
- rule[ROLE] = role;
- if (XGetClassHint(dpy, win, &classh)) {
- rule[CLASS] = classh.res_class;
- rule[INSTANCE] = classh.res_name;
- }
- /* get window state requested by application */
*state = getwinstate(win);
/* get window type (and other info) from default (hardcoded) rules */
+ role = gettextprop(win, atoms[WM_WINDOW_ROLE]);
+ XGetClassHint(dpy, win, &classh);
for (i = 0; config.rules[i].class != NULL || config.rules[i].instance != NULL || config.rules[i].role != NULL; i++) {
- if ((config.rules[i].class == NULL || strcmp(config.rules[i].class, rule[CLASS]) == 0)
- && (config.rules[i].instance == NULL || strcmp(config.rules[i].instance, rule[INSTANCE]) == 0)
- && (config.rules[i].role == NULL || strcmp(config.rules[i].role, rule[ROLE]) == 0)) {
+ if ((config.rules[i].class == NULL || STRCMP(config.rules[i].class, classh.res_class))
+ && (config.rules[i].instance == NULL || STRCMP(config.rules[i].instance, classh.res_name))
+ && (config.rules[i].role == NULL || STRCMP(config.rules[i].role, role))) {
if (config.rules[i].type != TYPE_MENU && config.rules[i].type != TYPE_DIALOG) {
type = config.rules[i].type;
}
@@ -429,69 +423,86 @@ getwintype(Window *win_ret, Window *leader, struct Tab **tab, int *state, XRecta
}
}
- /* get window type (and other info) from X resources */
- if (xdb != NULL) {
- /* check for window type */
- (void)snprintf(buf, NAMEMAXLEN, "shod.%s.%s.%s.type", rule[CLASS], rule[INSTANCE], rule[ROLE]);
- if (XrmGetResource(xdb, buf, "*", &ds, &xval) == True && xval.addr != NULL) {
- if (strcasecmp(xval.addr, "DESKTOP") == 0) {
- type = TYPE_DESKTOP;
- } else if (strcasecmp(xval.addr, "DOCKAPP") == 0) {
- type = TYPE_DOCKAPP;
- } else if (strcasecmp(xval.addr, "PROMPT") == 0) {
- type = TYPE_PROMPT;
- } else if (strcasecmp(xval.addr, "NORMAL") == 0) {
- type = TYPE_NORMAL;
- }
- }
+ /* convert strings to quarks for xrm */
+ class[I_NULL] = name[I_NULL] = NULLQUARK;
+ class[I_APP] = wm.application.class;
+ name[I_APP] = wm.application.name;
+ if (classh.res_class != NULL)
+ class[I_CLASS] = name[I_CLASS] = XrmStringToQuark(classh.res_class);
+ else
+ class[I_CLASS] = name[I_CLASS] = wm.resources[RES_ANY].name;
+ if (classh.res_name != NULL)
+ class[I_INSTANCE] = name[I_INSTANCE] = XrmStringToQuark(classh.res_name);
+ else
+ class[I_INSTANCE] = name[I_INSTANCE] = wm.resources[RES_ANY].name;
+ if (role != NULL)
+ class[I_ROLE] = name[I_ROLE] = XrmStringToQuark(role);
+ else
+ class[I_ROLE] = name[I_ROLE] = wm.resources[RES_ANY].name;
+ free(role);
+ XFree(classh.res_class);
+ XFree(classh.res_name);
- /* check for window state */
- (void)snprintf(buf, NAMEMAXLEN, "shod.%s.%s.%s.state", rule[CLASS], rule[INSTANCE], rule[ROLE]);
- if (XrmGetResource(xdb, buf, "*", &ds, &xval) == True && xval.addr != NULL) {
- *state = 0;
- if (strcasestr(xval.addr, "above") != NULL) {
- *state |= ABOVE;
- }
- if (strcasestr(xval.addr, "below") != NULL) {
- *state |= BELOW;
- }
- if (strcasestr(xval.addr, "fullscreen") != NULL) {
- *state |= FULLSCREEN;
- }
- if (strcasestr(xval.addr, "maximized") != NULL) {
- *state |= MAXIMIZED;
- }
- if (strcasestr(xval.addr, "minimized") != NULL) {
- *state |= MINIMIZED;
- }
- if (strcasestr(xval.addr, "shaded") != NULL) {
- *state |= SHADED;
- }
- if (strcasestr(xval.addr, "sticky") != NULL) {
- *state |= STICKY;
- }
- if (strcasestr(xval.addr, "extend") != NULL) {
- *state |= EXTEND;
- }
- if (strcasestr(xval.addr, "shrunk") != NULL) {
- *state |= SHRUNK;
- }
- if (strcasestr(xval.addr, "resized") != NULL) {
- *state |= RESIZED;
- }
+ /* get window type from X resources */
+ class[I_RESOURCE] = wm.resources[RES_TYPE].class;
+ name[I_RESOURCE] = wm.resources[RES_TYPE].name;
+ if ((value = getresource(xdb, class, name)) != NULL) {
+ if (strcasecmp(value, "DESKTOP") == 0) {
+ type = TYPE_DESKTOP;
+ } else if (strcasecmp(value, "DOCKAPP") == 0) {
+ type = TYPE_DOCKAPP;
+ } else if (strcasecmp(value, "PROMPT") == 0) {
+ type = TYPE_PROMPT;
+ } else if (strcasecmp(value, "NORMAL") == 0) {
+ type = TYPE_NORMAL;
}
+ }
- /* check for dockapp position */
- (void)snprintf(buf, NAMEMAXLEN, "shod.%s.%s.%s.dockpos", rule[CLASS], rule[INSTANCE], rule[ROLE]);
- if (XrmGetResource(xdb, buf, "*", &ds, &xval) == True) {
- if ((n = strtol(xval.addr, NULL, 10)) >= 0 && n < INT_MAX) {
- pos = n;
- }
+ /* get window state from X resources */
+ class[I_RESOURCE] = wm.resources[RES_STATE].class;
+ name[I_RESOURCE] = wm.resources[RES_STATE].name;
+ if ((value = getresource(xdb, class, name)) != NULL) {
+ *state = 0;
+ if (strcasestr(value, "above") != NULL) {
+ *state |= ABOVE;
+ }
+ if (strcasestr(value, "below") != NULL) {
+ *state |= BELOW;
+ }
+ if (strcasestr(value, "fullscreen") != NULL) {
+ *state |= FULLSCREEN;
+ }
+ if (strcasestr(value, "maximized") != NULL) {
+ *state |= MAXIMIZED;
+ }
+ if (strcasestr(value, "minimized") != NULL) {
+ *state |= MINIMIZED;
+ }
+ if (strcasestr(value, "shaded") != NULL) {
+ *state |= SHADED;
+ }
+ if (strcasestr(value, "sticky") != NULL) {
+ *state |= STICKY;
+ }
+ if (strcasestr(value, "extend") != NULL) {
+ *state |= EXTEND;
+ }
+ if (strcasestr(value, "shrunk") != NULL) {
+ *state |= SHRUNK;
+ }
+ if (strcasestr(value, "resized") != NULL) {
+ *state |= RESIZED;
}
}
- XFree(classh.res_class);
- XFree(classh.res_name);
+ /* get dockapp position from X resources */
+ class[I_RESOURCE] = wm.resources[RES_DOCK_POS].class;
+ name[I_RESOURCE] = wm.resources[RES_DOCK_POS].name;
+ if ((value = getresource(xdb, class, name)) != NULL) {
+ if ((n = strtol(value, NULL, 10)) >= 0 && n < INT_MAX) {
+ pos = n;
+ }
+ }
/* we already got the type of the window, return */
if (type != TYPE_UNKNOWN)
@@ -1749,19 +1760,19 @@ static void
xeventpropertynotify(XEvent *e)
{
XPropertyEvent *ev;
- XTextProperty prop;
struct Container *c;
struct Object *obj;
struct Tab *tab;
struct Menu *menu;
+ char *str;
ev = &e->xproperty;
if (ev->window == root && ev->atom == XA_RESOURCE_MANAGER) {
- if (!XGetTextProperty(dpy, root, &prop, XA_RESOURCE_MANAGER))
+ if ((str = gettextprop(root, XA_RESOURCE_MANAGER)) == NULL)
return;
XrmDestroyDatabase(xdb);
- setresources(prop.value);
- XFree(prop.value);
+ setresources(str);
+ free(str);
cleantheme();
inittheme();
TAILQ_FOREACH(c, &wm.focusq, entry)
diff --git a/xutil.c b/xutil.c
@@ -112,6 +112,19 @@ estrndup(const char *s, size_t maxlen)
return p;
}
+char *
+getresource(XrmDatabase xdb, XrmClass *class, XrmName *name)
+{
+ XrmRepresentation tmp;
+ XrmValue xval;
+
+ if (xdb == NULL)
+ return NULL;
+ if (XrmQGetResource(xdb, name, class, &tmp, &xval))
+ return xval.addr;
+ return NULL;
+}
+
unsigned long
getwinsprop(Window win, Atom prop, Window **wins)
{
diff --git a/xutil.h b/xutil.h
@@ -102,3 +102,4 @@ void initatoms(void);
void initatom(int atomenum);
void xinit(void);
void xinitvisual(void);
+char *getresource(XrmDatabase xdb, XrmClass *class, XrmName *name);