Files
wmaker/util/getstyle.c
T

484 lines
10 KiB
C
Raw Normal View History

1998-09-29 22:36:29 +00:00
/* getstyle.c - outputs style related options from WindowMaker to stdout
*
* WindowMaker window manager
*
2003-01-16 23:30:45 +00:00
* Copyright (c) 1997-2003 Alfredo K. Kojima
*
1998-09-29 22:36:29 +00:00
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1998-09-29 22:36:29 +00:00
*/
2010-03-31 04:24:17 +02:00
#ifdef __GLIBC__
#define _GNU_SOURCE /* getopt_long */
#endif
2010-03-17 22:46:19 +01:00
#include <sys/types.h>
#include <sys/stat.h>
2010-03-26 20:25:27 +01:00
#include <errno.h>
2010-03-17 22:46:19 +01:00
#include <fcntl.h>
2010-03-31 04:24:17 +02:00
#include <getopt.h>
#include <libgen.h>
#include <limits.h>
#include <pwd.h>
1998-09-29 22:36:29 +00:00
#include <stdio.h>
2010-03-31 04:24:17 +02:00
#include <stdlib.h>
1998-09-29 22:36:29 +00:00
#include <string.h>
1999-01-06 15:22:33 +00:00
#include <unistd.h>
2010-03-31 04:24:17 +02:00
#include <WINGs/WUtil.h>
1999-01-06 15:22:33 +00:00
2010-03-26 20:25:27 +01:00
#define RETRY( x ) do { \
x; \
} while (errno == EINTR);
1999-01-06 15:22:33 +00:00
#ifndef PATH_MAX
#define PATH_MAX 1024
#endif
1998-09-29 22:36:29 +00:00
#include "../src/wconfig.h"
#ifndef GLOBAL_DEFAULTS_SUBDIR
#define GLOBAL_DEFAULTS_SUBDIR "WindowMaker"
#endif
1998-09-29 22:36:29 +00:00
/* table of style related options */
static char *options[] = {
2009-08-20 00:59:40 +02:00
"TitleJustify",
"ClipTitleFont",
"WindowTitleFont",
"MenuTitleFont",
"MenuTextFont",
"IconTitleFont",
"DisplayFont",
"LargeDisplayFont",
"WindowTitleExtendSpace",
"MenuTitleExtendSpace",
"MenuTextExtendSpace",
"HighlightColor",
"HighlightTextColor",
"ClipTitleColor",
"CClipTitleColor",
"FTitleColor",
"PTitleColor",
"UTitleColor",
"FTitleBack",
"PTitleBack",
"UTitleBack",
"ResizebarBack",
"MenuTitleColor",
"MenuTextColor",
"MenuDisabledColor",
"MenuTitleBack",
"MenuTextBack",
"IconBack",
"IconTitleColor",
"IconTitleBack",
"MenuStyle",
"WindowTitleExtendSpace",
"MenuTitleExtendSpace",
"MenuTextExtendSpace",
NULL
1998-09-29 22:36:29 +00:00
};
/* table of theme related options */
static char *theme_options[] = {
2009-08-20 00:59:40 +02:00
"WorkspaceBack",
"NormalCursor",
"ArrowCursor",
"MoveCursor",
"ResizeCursor",
"TopLeftResizeCursor",
"TopRightResizeCursor",
"BottomLeftResizeCursor",
"BottomRightResizeCursor",
"VerticalResizeCursor",
"HorizontalResizeCursor",
"WaitCursor",
"QuestionCursor",
"TextCursor",
"SelectCursor",
NULL
1998-09-29 22:36:29 +00:00
};
/* table of style related fonts */
1998-09-29 22:36:29 +00:00
static char *font_options[] = {
2009-08-20 00:59:40 +02:00
"ClipTitleFont",
"WindowTitleFont",
"MenuTitleFont",
"MenuTextFont",
"IconTitleFont",
"DisplayFont",
"LargeDisplayFont",
NULL
};
2010-03-18 23:14:23 +01:00
extern char *__progname;
1998-09-29 22:36:29 +00:00
WMPropList *PixmapPath = NULL;
1999-01-06 15:22:33 +00:00
char *ThemePath = NULL;
2009-08-20 00:59:40 +02:00
extern char *convertFont(char *font, Bool keepXLFD);
1998-09-29 22:36:29 +00:00
2010-03-31 04:24:17 +02:00
void print_help(int print_usage, int exitval)
1998-09-29 22:36:29 +00:00
{
2010-03-31 04:24:17 +02:00
printf("Usage: %s [-t] [-p] [-h] [-v] [file]\n", __progname);
if (print_usage) {
puts("Retrieves style/theme configuration and output to FILE or to stdout");
puts("");
puts(" -h, --help display this help and exit");
puts(" -v, --version output version information and exit");
puts(" -t, --theme-options output theme related options when producing a style file");
puts(" -p, --pack produce output as a theme pack");
}
exit(exitval);
1998-09-29 22:36:29 +00:00
}
2009-08-20 00:59:40 +02:00
void abortar(char *reason)
1999-01-06 15:22:33 +00:00
{
2010-03-18 23:14:23 +01:00
printf("%s: %s\n", __progname, reason);
2009-08-20 00:59:40 +02:00
if (ThemePath) {
printf("Removing unfinished theme pack\n");
2010-03-17 22:46:19 +01:00
(void)wrmdirhier(ThemePath);
2009-08-20 00:59:40 +02:00
}
exit(1);
1999-01-06 15:22:33 +00:00
}
2009-08-20 00:59:40 +02:00
static Bool isFontOption(char *option)
{
2009-08-20 00:59:40 +02:00
int i;
2009-08-20 00:59:40 +02:00
for (i = 0; font_options[i] != NULL; i++) {
if (strcasecmp(option, font_options[i]) == 0) {
return True;
}
}
2009-08-20 00:59:40 +02:00
return False;
}
2010-03-26 20:25:27 +01:00
/*
* copy a file specified by `file' into `directory'. name stays.
*/
2010-03-17 22:46:19 +01:00
/*
* it is more or less assumed that this function will only
* copy reasonably-sized files
*/
2010-03-26 20:25:27 +01:00
/* XXX: is almost like WINGs/wcolodpanel.c:fetchFile() */
2009-08-20 00:59:40 +02:00
void copyFile(char *dir, char *file)
1999-01-06 15:22:33 +00:00
{
2010-04-08 14:43:52 -04:00
FILE *src = NULL, *dst = NULL;
2010-03-26 20:25:27 +01:00
size_t nread, nwritten, len;
2010-03-17 22:46:19 +01:00
char buf[4096];
struct stat st;
2010-03-26 20:25:27 +01:00
char *dstpath;
2010-03-17 22:46:19 +01:00
/* only to a directory */
if (stat(dir, &st) != 0 || !S_ISDIR(st.st_mode))
return;
/* only copy files */
if (stat(file, &st) != 0 || !S_ISREG(st.st_mode))
return;
len = strlen(dir) + 1 /* / */ + strlen(file) + 1 /* '\0' */;
2010-03-26 20:25:27 +01:00
dstpath = wmalloc(len);
snprintf(dstpath, len, "%s/%s", dir, basename(file));
2010-03-17 22:46:19 +01:00
buf[len] = '\0';
2010-03-26 20:25:27 +01:00
RETRY( dst = fopen(dstpath, "wb") )
if (dst == NULL) {
werror(_("Could not create %s"), dstpath);
2010-03-26 20:25:27 +01:00
goto err;
2010-03-17 22:46:19 +01:00
}
2010-03-26 20:25:27 +01:00
RETRY( src = fopen(file, "rb") )
if (src == NULL) {
werror(_("Could not open %s"), file);
2010-03-26 20:25:27 +01:00
goto err;
2009-08-20 00:59:40 +02:00
}
2010-03-17 22:46:19 +01:00
2010-03-26 20:25:27 +01:00
do {
RETRY( nread = fread(buf, 1, sizeof(buf), src) )
if (ferror(src))
break;
RETRY( nwritten = fwrite(buf, 1, nread, dst) )
if (ferror(dst) || feof(src))
break;
} while (1);
if (ferror(src) || ferror(dst))
unlink(dstpath);
fchmod(fileno(dst), st.st_mode);
fsync(fileno(dst));
RETRY( fclose(dst) )
2010-03-17 22:46:19 +01:00
2010-03-26 20:25:27 +01:00
err:
2010-04-08 14:43:52 -04:00
if (src) {
RETRY( fclose(src) )
}
2010-03-26 20:25:27 +01:00
wfree(dstpath);
return;
1999-01-06 15:22:33 +00:00
}
2009-08-20 00:59:40 +02:00
void findCopyFile(char *dir, char *file)
1999-01-06 15:22:33 +00:00
{
2009-08-20 00:59:40 +02:00
char *fullPath;
1999-01-06 15:22:33 +00:00
2009-08-20 00:59:40 +02:00
fullPath = wfindfileinarray(PixmapPath, file);
if (!fullPath) {
char buffer[4000];
1999-01-25 19:06:50 +00:00
2009-08-20 00:59:40 +02:00
sprintf(buffer, "could not find file %s", file);
abortar(buffer);
}
copyFile(dir, fullPath);
free(fullPath);
1999-01-06 15:22:33 +00:00
}
2010-03-17 22:46:19 +01:00
void makeThemePack(WMPropList * style, char *themeName)
1999-01-06 15:22:33 +00:00
{
2009-08-20 00:59:40 +02:00
WMPropList *keys;
WMPropList *key;
WMPropList *value;
int i;
2010-03-17 22:46:19 +01:00
size_t themeNameLen;
char *themeDir, *t;
if ((t = wusergnusteppath()) == NULL)
return;
themeNameLen = strlen(t) + 1 /* / */ + strlen(themeName) + 8 /* ".themed/" */ + 1 /* '\0' */;
themeDir = wmalloc(themeNameLen);
snprintf(themeDir, themeNameLen, "%s/%s.themed/", t, themeName);
2009-08-20 00:59:40 +02:00
ThemePath = themeDir;
2010-03-17 22:46:19 +01:00
if (!wmkdirhier(themeDir))
return;
2009-08-20 00:59:40 +02:00
keys = WMGetPLDictionaryKeys(style);
for (i = 0; i < WMGetPropListItemCount(keys); i++) {
key = WMGetFromPLArray(keys, i);
value = WMGetFromPLDictionary(style, key);
if (value && WMIsPLArray(value) && WMGetPropListItemCount(value) > 2) {
WMPropList *type;
char *t;
type = WMGetFromPLArray(value, 0);
t = WMGetFromPLString(type);
if (t == NULL)
continue;
2010-04-01 03:30:05 +02:00
if (strcasecmp(t, "tpixmap") == 0 ||
strcasecmp(t, "spixmap") == 0 ||
strcasecmp(t, "cpixmap") == 0 ||
strcasecmp(t, "mpixmap") == 0 ||
strcasecmp(t, "tdgradient") == 0 ||
strcasecmp(t, "tvgradient") == 0 ||
strcasecmp(t, "thgradient") == 0) {
2009-08-20 00:59:40 +02:00
WMPropList *file;
char *p;
char *newPath;
file = WMGetFromPLArray(value, 1);
p = strrchr(WMGetFromPLString(file), '/');
if (p) {
copyFile(themeDir, WMGetFromPLString(file));
newPath = wstrdup(p + 1);
WMDeleteFromPLArray(value, 1);
WMInsertInPLArray(value, 1, WMCreatePLString(newPath));
free(newPath);
} else {
findCopyFile(themeDir, WMGetFromPLString(file));
}
} else if (strcasecmp(t, "bitmap") == 0) {
2010-04-01 03:30:05 +02:00
2009-08-20 00:59:40 +02:00
WMPropList *file;
char *p;
char *newPath;
file = WMGetFromPLArray(value, 1);
p = strrchr(WMGetFromPLString(file), '/');
if (p) {
copyFile(themeDir, WMGetFromPLString(file));
newPath = wstrdup(p + 1);
WMDeleteFromPLArray(value, 1);
WMInsertInPLArray(value, 1, WMCreatePLString(newPath));
free(newPath);
} else {
findCopyFile(themeDir, WMGetFromPLString(file));
}
file = WMGetFromPLArray(value, 2);
p = strrchr(WMGetFromPLString(file), '/');
if (p) {
copyFile(themeDir, WMGetFromPLString(file));
newPath = wstrdup(p + 1);
WMDeleteFromPLArray(value, 2);
WMInsertInPLArray(value, 2, WMCreatePLString(newPath));
free(newPath);
} else {
findCopyFile(themeDir, WMGetFromPLString(file));
}
}
}
}
1999-01-06 15:22:33 +00:00
}
2009-08-20 00:59:40 +02:00
int main(int argc, char **argv)
1998-09-29 22:36:29 +00:00
{
2009-08-20 00:59:40 +02:00
WMPropList *prop, *style, *key, *val;
2010-03-18 00:51:33 +01:00
char *path, *p;
2010-03-31 04:24:17 +02:00
int i, ch, theme_too = 0, make_pack = 0;
2009-08-20 00:59:40 +02:00
char *style_file = NULL;
2010-03-31 04:24:17 +02:00
struct option longopts[] = {
{ "pack", no_argument, NULL, 'p' },
{ "theme-options", no_argument, NULL, 't' },
{ "version", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 'h' },
{ NULL, 0, NULL, 0 }
};
while ((ch = getopt_long(argc, argv, "ptvh", longopts, NULL)) != -1)
switch(ch) {
case 'v':
2010-04-01 19:05:25 +02:00
printf("%s (Window Maker %s)\n", __progname, VERSION);
2010-03-31 04:24:17 +02:00
return 0;
/* NOTREACHED */
case 'h':
print_help(1, 0);
/* NOTREACHED */
case 'p':
2009-08-20 00:59:40 +02:00
make_pack = 1;
theme_too = 1;
2010-03-31 04:24:17 +02:00
break;
case 't':
2010-03-18 23:14:23 +01:00
theme_too = 1;
2010-03-31 04:24:17 +02:00
case 0:
break;
default:
print_help(0, 1);
/* NOTREACHED */
2009-08-20 00:59:40 +02:00
}
2010-03-31 04:24:17 +02:00
argc -= optind;
argv += optind;
if (argc != 1)
print_help(0, 1);
style_file = argv[0];
while ((p = strchr(style_file, '/')) != NULL)
*p = '_';
if (style_file && !make_pack) /* what's this? */
print_help(0, 1);
2010-03-18 23:14:23 +01:00
2009-08-20 00:59:40 +02:00
if (make_pack && !style_file) {
2010-03-18 23:14:23 +01:00
printf("%s: you must supply a name for the theme pack\n", __progname);
2010-03-31 04:24:17 +02:00
return 1;
2009-08-20 00:59:40 +02:00
}
WMPLSetCaseSensitive(False);
2010-03-18 23:14:23 +01:00
path = wdefaultspathfordomain("WindowMaker");
2009-08-20 00:59:40 +02:00
prop = WMReadPropListFromFile(path);
if (!prop) {
2010-03-18 23:14:23 +01:00
printf("%s: could not load WindowMaker configuration file \"%s\".\n", __progname, path);
2010-03-31 04:24:17 +02:00
return 1;
2009-08-20 00:59:40 +02:00
}
/* get global value */
2010-03-18 23:14:23 +01:00
path = wglobaldefaultspathfordomain("WindowMaker");
2009-08-20 00:59:40 +02:00
val = WMReadPropListFromFile(path);
if (val) {
WMMergePLDictionaries(val, prop, True);
WMReleasePropList(prop);
prop = val;
}
style = WMCreatePLDictionary(NULL, NULL);
for (i = 0; options[i] != NULL; i++) {
key = WMCreatePLString(options[i]);
val = WMGetFromPLDictionary(prop, key);
if (val) {
WMRetainPropList(val);
if (isFontOption(options[i])) {
char *newfont, *oldfont;
oldfont = WMGetFromPLString(val);
newfont = convertFont(oldfont, False);
/* newfont is a reference to old if conversion is not needed */
if (newfont != oldfont) {
WMReleasePropList(val);
val = WMCreatePLString(newfont);
wfree(newfont);
}
}
WMPutInPLDictionary(style, key, val);
WMReleasePropList(val);
}
WMReleasePropList(key);
}
val = WMGetFromPLDictionary(prop, WMCreatePLString("PixmapPath"));
if (val)
PixmapPath = val;
if (theme_too) {
for (i = 0; theme_options[i] != NULL; i++) {
key = WMCreatePLString(theme_options[i]);
val = WMGetFromPLDictionary(prop, key);
if (val)
WMPutInPLDictionary(style, key, val);
}
}
if (make_pack) {
char *path;
makeThemePack(style, style_file);
path = wmalloc(strlen(ThemePath) + 32);
strcpy(path, ThemePath);
strcat(path, "/style");
2010-03-15 23:12:24 +01:00
WMWritePropListToFile(style, path);
2009-08-20 00:59:40 +02:00
wfree(path);
} else {
if (style_file) {
2010-03-15 23:12:24 +01:00
WMWritePropListToFile(style, style_file);
2009-08-20 00:59:40 +02:00
} else {
puts(WMGetPropListDescription(style, True));
}
}
2010-03-31 04:24:17 +02:00
return 0;
1998-09-29 22:36:29 +00:00
}