getstyle: fix wcopy_file paths
[wmaker-crm.git] / util / getstyle.c
blobc2c61c3ee0c212e128d31a6e80964803a531e316
1 /* getstyle.c - outputs style related options from WindowMaker to stdout
3 * WindowMaker window manager
5 * Copyright (c) 1997-2003 Alfredo K. Kojima
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #ifdef __GLIBC__
23 #define _GNU_SOURCE /* getopt_long */
24 #endif
26 #include "config.h"
28 #include <sys/types.h>
29 #include <sys/stat.h>
31 #include <errno.h>
32 #include <fcntl.h>
33 #include <getopt.h>
34 #include <libgen.h>
35 #include <limits.h>
36 #include <pwd.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <strings.h>
41 #include <unistd.h>
43 #ifdef HAVE_STDNORETURN
44 #include <stdnoreturn.h>
45 #endif
47 #include <WINGs/WUtil.h>
49 #include "common.h"
51 #ifndef PATH_MAX
52 #define PATH_MAX 1024
53 #endif
55 #include "../src/wconfig.h"
58 /* table of style related options */
59 static char *options[] = {
60 "TitleJustify",
61 "ClipTitleFont",
62 "WindowTitleFont",
63 "MenuTitleFont",
64 "MenuTextFont",
65 "IconTitleFont",
66 "LargeDisplayFont",
67 "HighlightColor",
68 "HighlightTextColor",
69 "ClipTitleColor",
70 "CClipTitleColor",
71 "FTitleColor",
72 "PTitleColor",
73 "UTitleColor",
74 "FTitleBack",
75 "PTitleBack",
76 "UTitleBack",
77 "ResizebarBack",
78 "MenuTitleColor",
79 "MenuTextColor",
80 "MenuDisabledColor",
81 "MenuTitleBack",
82 "MenuTextBack",
83 "IconBack",
84 "IconTitleColor",
85 "IconTitleBack",
86 "FrameBorderWidth",
87 "FrameBorderColor",
88 "FrameFocusedBorderColor",
89 "FrameSelectedBorderColor",
90 "MenuStyle",
91 "WindowTitleExtendSpace",
92 "MenuTitleExtendSpace",
93 "MenuTextExtendSpace",
94 NULL
97 /* table of theme related options */
98 static char *theme_options[] = {
99 "WorkspaceBack",
100 "NormalCursor",
101 "ArrowCursor",
102 "MoveCursor",
103 "ResizeCursor",
104 "TopLeftResizeCursor",
105 "TopRightResizeCursor",
106 "BottomLeftResizeCursor",
107 "BottomRightResizeCursor",
108 "VerticalResizeCursor",
109 "HorizontalResizeCursor",
110 "WaitCursor",
111 "QuestionCursor",
112 "TextCursor",
113 "SelectCursor",
114 NULL
117 /* table of style related fonts */
119 static char *font_options[] = {
120 "ClipTitleFont",
121 "WindowTitleFont",
122 "MenuTitleFont",
123 "MenuTextFont",
124 "IconTitleFont",
125 "LargeDisplayFont",
126 NULL
129 static const char *prog_name;
131 WMPropList *PixmapPath = NULL;
133 char *ThemePath = NULL;
136 static noreturn void print_help(int print_usage, int exitval)
138 printf("Usage: %s [-t] [-p] [-h] [-v] [file]\n", prog_name);
139 if (print_usage) {
140 puts("Retrieves style/theme configuration and outputs to ~/GNUstep/Library/WindowMaker/Themes/file.themed/style or to stdout");
141 puts("");
142 puts(" -h, --help display this help and exit");
143 puts(" -v, --version output version information and exit");
144 puts(" -t, --theme-options output theme related options when producing a style file");
145 puts(" -p, --pack produce output as a theme pack");
147 exit(exitval);
150 static Bool isFontOption(const char *option)
152 int i;
154 for (i = 0; font_options[i] != NULL; i++) {
155 if (strcasecmp(option, font_options[i]) == 0) {
156 return True;
160 return False;
163 static void findCopyFile(const char *dir, const char *file)
165 char *fullPath;
167 fullPath = wfindfileinarray(PixmapPath, file);
168 if (!fullPath) {
169 wwarning("Could not find file %s", file);
170 if (ThemePath)
171 (void)wrmdirhier(ThemePath);
172 return;
174 wcopy_file(dir, fullPath, file);
175 wfree(fullPath);
178 #define THEME_SUBPATH "/Library/WindowMaker/Themes/"
179 #define THEME_EXTDIR ".themed/"
181 static void makeThemePack(WMPropList * style, const char *themeName)
183 WMPropList *keys;
184 WMPropList *key;
185 WMPropList *value;
186 int i;
187 size_t themeNameLen;
188 char *themeDir;
189 const char *user_base;
191 user_base = wusergnusteppath();
192 if (user_base == NULL)
193 return;
194 themeNameLen = strlen(user_base) + sizeof(THEME_SUBPATH) + strlen(themeName) + sizeof(THEME_EXTDIR) + 1;
195 themeDir = wmalloc(themeNameLen);
196 snprintf(themeDir, themeNameLen,
197 "%s" THEME_SUBPATH "%s" THEME_EXTDIR,
198 user_base, themeName);
199 ThemePath = themeDir;
201 if (!wmkdirhier(themeDir)) {
202 wwarning("Could not make theme dir %s\n", themeDir);
203 return;
206 keys = WMGetPLDictionaryKeys(style);
208 for (i = 0; i < WMGetPropListItemCount(keys); i++) {
209 key = WMGetFromPLArray(keys, i);
211 value = WMGetFromPLDictionary(style, key);
212 if (value && WMIsPLArray(value) && WMGetPropListItemCount(value) > 2) {
213 WMPropList *type;
214 char *t;
216 type = WMGetFromPLArray(value, 0);
217 t = WMGetFromPLString(type);
218 if (t == NULL)
219 continue;
221 if (strcasecmp(t, "tpixmap") == 0 ||
222 strcasecmp(t, "spixmap") == 0 ||
223 strcasecmp(t, "cpixmap") == 0 ||
224 strcasecmp(t, "mpixmap") == 0 ||
225 strcasecmp(t, "tdgradient") == 0 ||
226 strcasecmp(t, "tvgradient") == 0 ||
227 strcasecmp(t, "thgradient") == 0) {
229 WMPropList *file;
230 char *p;
231 char *newPath;
233 file = WMGetFromPLArray(value, 1);
235 p = strrchr(WMGetFromPLString(file), '/');
236 if (p) {
237 newPath = wstrdup(p + 1);
239 wcopy_file(themeDir, WMGetFromPLString(file), newPath);
241 WMDeleteFromPLArray(value, 1);
242 WMInsertInPLArray(value, 1, WMCreatePLString(newPath));
243 free(newPath);
244 } else {
245 findCopyFile(themeDir, WMGetFromPLString(file));
247 } else if (strcasecmp(t, "bitmap") == 0) {
249 WMPropList *file;
250 char *p;
251 char *newPath;
253 file = WMGetFromPLArray(value, 1);
255 p = strrchr(WMGetFromPLString(file), '/');
256 if (p) {
257 newPath = wstrdup(p + 1);
259 wcopy_file(themeDir, WMGetFromPLString(file), newPath);
261 WMDeleteFromPLArray(value, 1);
262 WMInsertInPLArray(value, 1, WMCreatePLString(newPath));
263 free(newPath);
264 } else {
265 findCopyFile(themeDir, WMGetFromPLString(file));
268 file = WMGetFromPLArray(value, 2);
270 p = strrchr(WMGetFromPLString(file), '/');
271 if (p) {
272 newPath = wstrdup(p + 1);
274 wcopy_file(themeDir, WMGetFromPLString(file), newPath);
276 WMDeleteFromPLArray(value, 2);
277 WMInsertInPLArray(value, 2, WMCreatePLString(newPath));
278 free(newPath);
279 } else {
280 findCopyFile(themeDir, WMGetFromPLString(file));
285 WMReleasePropList(keys);
288 int main(int argc, char **argv)
290 WMPropList *prop, *style, *key, *val;
291 char *path;
292 int i, ch, theme_too = 0, make_pack = 0;
293 char *style_file = NULL;
295 struct option longopts[] = {
296 { "pack", no_argument, NULL, 'p' },
297 { "theme-options", no_argument, NULL, 't' },
298 { "version", no_argument, NULL, 'v' },
299 { "help", no_argument, NULL, 'h' },
300 { NULL, 0, NULL, 0 }
303 prog_name = argv[0];
304 while ((ch = getopt_long(argc, argv, "ptvh", longopts, NULL)) != -1)
305 switch(ch) {
306 case 'v':
307 printf("%s (Window Maker %s)\n", prog_name, VERSION);
308 return 0;
309 /* NOTREACHED */
310 case 'h':
311 print_help(1, 0);
312 /* NOTREACHED */
313 case 'p':
314 make_pack = 1;
315 theme_too = 1;
316 break;
317 case 't':
318 theme_too = 1;
319 case 0:
320 break;
321 default:
322 print_help(0, 1);
323 /* NOTREACHED */
326 /* At most one non-option ARGV-element is accepted (the theme name) */
327 if (argc - optind > 1)
328 print_help(0, 1);
330 if (argc - optind == 1)
331 style_file = argv[argc - 1];
333 if (make_pack && !style_file) {
334 printf("%s: you must supply a name for the theme pack\n", prog_name);
335 return 1;
338 WMPLSetCaseSensitive(False);
340 path = wdefaultspathfordomain("WindowMaker");
342 prop = WMReadPropListFromFile(path);
343 if (!prop) {
344 printf("%s: could not load WindowMaker configuration file \"%s\".\n", prog_name, path);
345 return 1;
348 /* get global value */
349 path = wglobaldefaultspathfordomain("WindowMaker");
351 val = WMReadPropListFromFile(path);
352 if (val) {
353 WMMergePLDictionaries(val, prop, True);
354 WMReleasePropList(prop);
355 prop = val;
358 style = WMCreatePLDictionary(NULL, NULL);
360 for (i = 0; options[i] != NULL; i++) {
361 key = WMCreatePLString(options[i]);
363 val = WMGetFromPLDictionary(prop, key);
364 if (val) {
365 WMRetainPropList(val);
366 if (isFontOption(options[i])) {
367 char *newfont, *oldfont;
369 oldfont = WMGetFromPLString(val);
370 newfont = convertFont(oldfont, False);
371 /* newfont is a reference to old if conversion is not needed */
372 if (newfont != oldfont) {
373 WMReleasePropList(val);
374 val = WMCreatePLString(newfont);
375 wfree(newfont);
378 WMPutInPLDictionary(style, key, val);
379 WMReleasePropList(val);
381 WMReleasePropList(key);
384 val = WMGetFromPLDictionary(prop, WMCreatePLString("PixmapPath"));
385 if (val)
386 PixmapPath = val;
388 if (theme_too) {
389 for (i = 0; theme_options[i] != NULL; i++) {
390 key = WMCreatePLString(theme_options[i]);
392 val = WMGetFromPLDictionary(prop, key);
393 if (val)
394 WMPutInPLDictionary(style, key, val);
398 if (make_pack) {
399 char *path;
401 makeThemePack(style, style_file);
403 path = wmalloc(strlen(ThemePath) + 32);
404 strcpy(path, ThemePath);
405 strcat(path, "/style");
406 WMWritePropListToFile(style, path);
407 wfree(path);
408 } else {
409 if (style_file) {
410 WMWritePropListToFile(style, style_file);
411 } else {
412 puts(WMGetPropListDescription(style, True));
415 return 0;