mirror of
https://github.com/gryf/wmaker.git
synced 2026-02-22 10:05:46 +01:00
Spice up setstyle
- convert to getopt
- tidy xsendevent
- modify hackPathInTexture() so that:
- it properly figures where the style file is
- if it's under the user's home directory, that part of the path
is changed to `~' - this makes your wm configuration usable on
systems with a network home, used on systems where home is /home,
or /u, or /export/home, or whatever.
XXX: there's a note WINGs/findfile.c:wexpandpath() stating that
`too many functions handle a return value of NULL incorrectly'. this is
so true. so if anyone is looking for a small project to sink their
teeth in...
This commit is contained in:
committed by
Carlos R. Mafra
parent
1bc042c172
commit
859338fd83
229
util/setstyle.c
229
util/setstyle.c
@@ -22,12 +22,20 @@
|
|||||||
|
|
||||||
#define PROG_VERSION "setstyle (Window Maker) 0.6"
|
#define PROG_VERSION "setstyle (Window Maker) 0.6"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#ifdef __GLIBC__
|
||||||
#include <stdio.h>
|
#define _GNU_SOURCE /* getopt_long */
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
#include <WINGs/WUtil.h>
|
#include <WINGs/WUtil.h>
|
||||||
|
|
||||||
#include "../src/wconfig.h"
|
#include "../src/wconfig.h"
|
||||||
@@ -97,6 +105,12 @@ static Bool isFontOption(char *option)
|
|||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* finds elements in `texture' that reference external files,
|
||||||
|
* prepends `prefix' to these files. `prefix' is a path component
|
||||||
|
* that qualifies the external references to be absolute, possibly
|
||||||
|
* pending further expansion
|
||||||
|
*/
|
||||||
void hackPathInTexture(WMPropList * texture, char *prefix)
|
void hackPathInTexture(WMPropList * texture, char *prefix)
|
||||||
{
|
{
|
||||||
WMPropList *type;
|
WMPropList *type;
|
||||||
@@ -107,12 +121,14 @@ void hackPathInTexture(WMPropList * texture, char *prefix)
|
|||||||
t = WMGetFromPLString(type);
|
t = WMGetFromPLString(type);
|
||||||
if (t == NULL)
|
if (t == NULL)
|
||||||
return;
|
return;
|
||||||
if (strcasecmp(t, "tpixmap") == 0
|
|
||||||
|| strcasecmp(t, "spixmap") == 0
|
if (strcasecmp(t, "tpixmap") == 0 ||
|
||||||
|| strcasecmp(t, "mpixmap") == 0
|
strcasecmp(t, "spixmap") == 0 ||
|
||||||
|| strcasecmp(t, "cpixmap") == 0
|
strcasecmp(t, "mpixmap") == 0 ||
|
||||||
|| strcasecmp(t, "tvgradient") == 0
|
strcasecmp(t, "cpixmap") == 0 ||
|
||||||
|| strcasecmp(t, "thgradient") == 0 || strcasecmp(t, "tdgradient") == 0) {
|
strcasecmp(t, "tvgradient") == 0 ||
|
||||||
|
strcasecmp(t, "thgradient") == 0 ||
|
||||||
|
strcasecmp(t, "tdgradient") == 0) {
|
||||||
WMPropList *file;
|
WMPropList *file;
|
||||||
char buffer[4018];
|
char buffer[4018];
|
||||||
|
|
||||||
@@ -122,6 +138,7 @@ void hackPathInTexture(WMPropList * texture, char *prefix)
|
|||||||
/* replace path with full path */
|
/* replace path with full path */
|
||||||
WMDeleteFromPLArray(texture, 1);
|
WMDeleteFromPLArray(texture, 1);
|
||||||
WMInsertInPLArray(texture, 1, WMCreatePLString(buffer));
|
WMInsertInPLArray(texture, 1, WMCreatePLString(buffer));
|
||||||
|
|
||||||
} else if (strcasecmp(t, "bitmap") == 0) {
|
} else if (strcasecmp(t, "bitmap") == 0) {
|
||||||
WMPropList *file;
|
WMPropList *file;
|
||||||
char buffer[4018];
|
char buffer[4018];
|
||||||
@@ -334,16 +351,19 @@ void hackStyle(WMPropList * style)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_help()
|
void print_help(int print_usage, int exitval)
|
||||||
{
|
{
|
||||||
printf("Usage: %s [OPTIONS] FILE\n", __progname);
|
printf("Usage: %s [OPTIONS] FILE\n", __progname);
|
||||||
puts("Reads style/theme configuration from FILE and updates Window Maker.");
|
if (print_usage) {
|
||||||
puts("");
|
puts("Reads style/theme configuration from FILE and updates Window Maker.");
|
||||||
puts(" --no-fonts ignore font related options");
|
puts("");
|
||||||
puts(" --no-cursors ignore cursor related options");
|
puts(" --no-fonts ignore font related options");
|
||||||
puts(" --ignore <option> ignore changes in the specified option");
|
puts(" --no-cursors ignore cursor related options");
|
||||||
puts(" -h, --help display this help and exit");
|
puts(" --ignore <option> ignore changes in the specified option");
|
||||||
puts(" -v, --version output version information and exit");
|
puts(" -h, --help display this help and exit");
|
||||||
|
puts(" -v, --version output version information and exit");
|
||||||
|
}
|
||||||
|
exit(exitval);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
@@ -351,47 +371,52 @@ int main(int argc, char **argv)
|
|||||||
WMPropList *prop, *style;
|
WMPropList *prop, *style;
|
||||||
char *path;
|
char *path;
|
||||||
char *file = NULL;
|
char *file = NULL;
|
||||||
struct stat statbuf;
|
struct stat st;
|
||||||
int i;
|
int i, ch, ignflag = 0;
|
||||||
int ignoreCount = 0;
|
int ignoreCount = 0;
|
||||||
char *ignoreList[MAX_OPTIONS];
|
char *ignoreList[MAX_OPTIONS];
|
||||||
|
XEvent ev;
|
||||||
|
|
||||||
dpy = XOpenDisplay("");
|
struct option longopts[] = {
|
||||||
|
{ "version", no_argument, NULL, 'v' },
|
||||||
|
{ "help", no_argument, NULL, 'h' },
|
||||||
|
{ "no-fonts", no_argument, &ignoreFonts, 1 },
|
||||||
|
{ "no-cursors", no_argument, &ignoreCursors, 1 },
|
||||||
|
{ "ignore", required_argument, &ignflag, 1 },
|
||||||
|
{ NULL, 0, NULL, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
if (argc < 2) {
|
while ((ch = getopt_long(argc, argv, "hv", longopts, NULL)) != -1)
|
||||||
printf("%s: missing argument\n", __progname);
|
switch(ch) {
|
||||||
printf("Try '%s --help' for more information\n", __progname);
|
case 'v':
|
||||||
exit(1);
|
puts(PROG_VERSION);
|
||||||
}
|
return 0;
|
||||||
|
/* NOTREACHED */
|
||||||
for (i = 1; i < argc; i++) {
|
case 'h':
|
||||||
if (strcmp("--ignore", argv[i]) == 0) {
|
print_help(1, 0);
|
||||||
i++;
|
/* NOTREACHED */
|
||||||
if (i == argc) {
|
case 0:
|
||||||
printf("%s: missing argument for option --ignore\n", __progname);
|
if (ignflag) {
|
||||||
exit(1);
|
if (ignoreCount >= MAX_OPTIONS) {
|
||||||
}
|
printf("Maximum %d `ignore' arguments\n", MAX_OPTIONS);
|
||||||
ignoreList[ignoreCount++] = argv[i];
|
return 1;
|
||||||
|
}
|
||||||
} else if (strcmp("--no-fonts", argv[i]) == 0) {
|
ignoreList[ignoreCount++] = optarg;
|
||||||
ignoreFonts = 1;
|
ignflag = 0;
|
||||||
} else if (strcmp("--no-cursors", argv[i]) == 0) {
|
};
|
||||||
ignoreCursors = 1;
|
break;
|
||||||
} else if (strcmp("-v", argv[i]) == 0 || strcmp("--version", argv[i]) == 0) {
|
default:
|
||||||
puts(PROG_VERSION);
|
print_help(0, 1);
|
||||||
exit(0);
|
/* NOTREACHED */
|
||||||
} else if (strcmp("-h", argv[i]) == 0 || strcmp("--help", argv[i]) == 0) {
|
|
||||||
print_help();
|
|
||||||
exit(0);
|
|
||||||
} else {
|
|
||||||
if (file) {
|
|
||||||
printf("%s: invalid argument '%s'\n", __progname, argv[i]);
|
|
||||||
printf("Try '%s --help' for more information\n", __progname);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
file = argv[i];
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
|
if (argc != 1)
|
||||||
|
print_help(0, 1);
|
||||||
|
|
||||||
|
file = argv[0];
|
||||||
|
|
||||||
WMPLSetCaseSensitive(False);
|
WMPLSetCaseSensitive(False);
|
||||||
|
|
||||||
@@ -401,65 +426,62 @@ int main(int argc, char **argv)
|
|||||||
if (!prop) {
|
if (!prop) {
|
||||||
perror(path);
|
perror(path);
|
||||||
printf("%s: could not load WindowMaker configuration file.\n", __progname);
|
printf("%s: could not load WindowMaker configuration file.\n", __progname);
|
||||||
exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stat(file, &statbuf) < 0) {
|
if (stat(file, &st) < 0) {
|
||||||
perror(file);
|
perror(file);
|
||||||
exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
if (S_ISDIR(statbuf.st_mode)) {
|
if (S_ISDIR(st.st_mode)) { /* theme pack */
|
||||||
char buffer[4018];
|
char buf[PATH_MAX];
|
||||||
char *prefix;
|
char *homedir;
|
||||||
/* theme pack */
|
|
||||||
|
|
||||||
if (*argv[argc - 1] != '/') {
|
if (realpath(file, buf) == NULL) {
|
||||||
if (!getcwd(buffer, 4000)) {
|
perror(file);
|
||||||
printf("%s: complete path for %s is too long\n", __progname, file);
|
return 1;
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (strlen(buffer) + strlen(file) > 4000) {
|
|
||||||
printf("%s: complete path for %s is too long\n", __progname, file);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
strcat(buffer, "/");
|
|
||||||
} else {
|
|
||||||
buffer[0] = 0;
|
|
||||||
}
|
}
|
||||||
strcat(buffer, file);
|
strncat(buf, "/style", sizeof(buf) - strlen(buf) - 1);
|
||||||
|
|
||||||
prefix = malloc(strlen(buffer) + 10);
|
if (stat(buf, &st) != 0 || !S_ISREG(st.st_mode)) { /* maybe symlink too? */
|
||||||
if (!prefix) {
|
printf("%s: %s: style file not found or not a file\n", __progname, buf);
|
||||||
printf("%s: out of memory\n", __progname);
|
return 1;
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
strcpy(prefix, buffer);
|
|
||||||
|
|
||||||
strcat(buffer, "/style");
|
style = WMReadPropListFromFile(buf);
|
||||||
|
|
||||||
style = WMReadPropListFromFile(buffer);
|
|
||||||
if (!style) {
|
if (!style) {
|
||||||
perror(buffer);
|
perror(buf);
|
||||||
printf("%s: could not load style file.\n", __progname);
|
printf("%s: could not load style file.\n", __progname);
|
||||||
exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
hackPaths(style, prefix);
|
buf[strlen(buf) - 6 /* strlen("/style") */] = '\0';
|
||||||
free(prefix);
|
homedir = wstrdup(wgethomedir());
|
||||||
} else {
|
if (strlen(homedir) > 1 && /* this is insane, wgethomedir() returns `/' on error */
|
||||||
/* normal style file */
|
strncmp(homedir, buf, strlen(homedir)) == 0) {
|
||||||
|
/* theme pack is under ${HOME}; exchange ${HOME} part
|
||||||
|
* for `~' so it gets portable references to the user home dir */
|
||||||
|
*buf = '~';
|
||||||
|
memmove(buf + 1, buf + strlen(homedir), strlen(buf) - strlen(homedir) + 1);
|
||||||
|
}
|
||||||
|
wfree(homedir);
|
||||||
|
|
||||||
|
hackPaths(style, buf); /* this will prefix pixmaps in the style
|
||||||
|
* with absolute(ish) references */
|
||||||
|
|
||||||
|
} else { /* normal style file */
|
||||||
|
|
||||||
style = WMReadPropListFromFile(file);
|
style = WMReadPropListFromFile(file);
|
||||||
if (!style) {
|
if (!style) {
|
||||||
perror(file);
|
perror(file);
|
||||||
printf("%s:could not load style file.\n", __progname);
|
printf("%s:could not load style file.\n", __progname);
|
||||||
exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!WMIsPLDictionary(style)) {
|
if (!WMIsPLDictionary(style)) {
|
||||||
printf("%s: '%s' is not a style file/theme\n", __progname, file);
|
printf("%s: '%s' is not a style file/theme\n", __progname, file);
|
||||||
exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
hackStyle(style);
|
hackStyle(style);
|
||||||
@@ -473,27 +495,20 @@ int main(int argc, char **argv)
|
|||||||
WMMergePLDictionaries(prop, style, True);
|
WMMergePLDictionaries(prop, style, True);
|
||||||
|
|
||||||
WMWritePropListToFile(prop, path);
|
WMWritePropListToFile(prop, path);
|
||||||
{
|
|
||||||
XEvent ev;
|
|
||||||
|
|
||||||
if (dpy) {
|
dpy = XOpenDisplay("");
|
||||||
int i;
|
if (dpy) {
|
||||||
char *msg = "Reconfigure";
|
memset(&ev, 0, sizeof(XEvent));
|
||||||
|
|
||||||
memset(&ev, 0, sizeof(XEvent));
|
ev.xclient.type = ClientMessage;
|
||||||
|
ev.xclient.message_type = XInternAtom(dpy, "_WINDOWMAKER_COMMAND", False);
|
||||||
|
ev.xclient.window = DefaultRootWindow(dpy);
|
||||||
|
ev.xclient.format = 8;
|
||||||
|
strncpy(ev.xclient.data.b, "Reconfigure", sizeof(ev.xclient.data.b));
|
||||||
|
|
||||||
ev.xclient.type = ClientMessage;
|
XSendEvent(dpy, DefaultRootWindow(dpy), False, SubstructureRedirectMask, &ev);
|
||||||
ev.xclient.message_type = XInternAtom(dpy, "_WINDOWMAKER_COMMAND", False);
|
XFlush(dpy);
|
||||||
ev.xclient.window = DefaultRootWindow(dpy);
|
|
||||||
ev.xclient.format = 8;
|
|
||||||
|
|
||||||
for (i = 0; i <= strlen(msg); i++) {
|
|
||||||
ev.xclient.data.b[i] = msg[i];
|
|
||||||
}
|
|
||||||
XSendEvent(dpy, DefaultRootWindow(dpy), False, SubstructureRedirectMask, &ev);
|
|
||||||
XFlush(dpy);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exit(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user