wrlib: add merged code for xpm support in 2 distinct functions
[wmaker-crm.git] / util / getstyle.c
blobbf321c3049e064ef9b850961d684e871c39060ae
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"
57 #ifndef GLOBAL_DEFAULTS_SUBDIR
58 #define GLOBAL_DEFAULTS_SUBDIR "WindowMaker"
59 #endif
61 /* table of style related options */
62 static char *options[] = {
63 "TitleJustify",
64 "ClipTitleFont",
65 "WindowTitleFont",
66 "MenuTitleFont",
67 "MenuTextFont",
68 "IconTitleFont",
69 "LargeDisplayFont",
70 "HighlightColor",
71 "HighlightTextColor",
72 "ClipTitleColor",
73 "CClipTitleColor",
74 "FTitleColor",
75 "PTitleColor",
76 "UTitleColor",
77 "FTitleBack",
78 "PTitleBack",
79 "UTitleBack",
80 "ResizebarBack",
81 "MenuTitleColor",
82 "MenuTextColor",
83 "MenuDisabledColor",
84 "MenuTitleBack",
85 "MenuTextBack",
86 "IconBack",
87 "IconTitleColor",
88 "IconTitleBack",
89 "FrameBorderWidth",
90 "FrameBorderColor",
91 "FrameFocusedBorderColor",
92 "FrameSelectedBorderColor",
93 "MenuStyle",
94 "WindowTitleExtendSpace",
95 "MenuTitleExtendSpace",
96 "MenuTextExtendSpace",
97 NULL
100 /* table of theme related options */
101 static char *theme_options[] = {
102 "WorkspaceBack",
103 "NormalCursor",
104 "ArrowCursor",
105 "MoveCursor",
106 "ResizeCursor",
107 "TopLeftResizeCursor",
108 "TopRightResizeCursor",
109 "BottomLeftResizeCursor",
110 "BottomRightResizeCursor",
111 "VerticalResizeCursor",
112 "HorizontalResizeCursor",
113 "WaitCursor",
114 "QuestionCursor",
115 "TextCursor",
116 "SelectCursor",
117 NULL
120 /* table of style related fonts */
122 static char *font_options[] = {
123 "ClipTitleFont",
124 "WindowTitleFont",
125 "MenuTitleFont",
126 "MenuTextFont",
127 "IconTitleFont",
128 "LargeDisplayFont",
129 NULL
132 extern char *__progname;
134 WMPropList *PixmapPath = NULL;
136 char *ThemePath = NULL;
139 static noreturn void print_help(int print_usage, int exitval)
141 printf("Usage: %s [-t] [-p] [-h] [-v] [file]\n", __progname);
142 if (print_usage) {
143 puts("Retrieves style/theme configuration and outputs to ~/GNUstep/Library/WindowMaker/Themes/file.themed/style or to stdout");
144 puts("");
145 puts(" -h, --help display this help and exit");
146 puts(" -v, --version output version information and exit");
147 puts(" -t, --theme-options output theme related options when producing a style file");
148 puts(" -p, --pack produce output as a theme pack");
150 exit(exitval);
153 static Bool isFontOption(const char *option)
155 int i;
157 for (i = 0; font_options[i] != NULL; i++) {
158 if (strcasecmp(option, font_options[i]) == 0) {
159 return True;
163 return False;
166 static void findCopyFile(const char *dir, const char *file)
168 char *fullPath;
170 fullPath = wfindfileinarray(PixmapPath, file);
171 if (!fullPath) {
172 wwarning("Could not find file %s", file);
173 if (ThemePath)
174 (void)wrmdirhier(ThemePath);
176 wcopy_file(dir, fullPath, fullPath);
177 free(fullPath);
180 #define THEME_SUBPATH "/Library/WindowMaker/Themes/"
181 #define THEME_EXTDIR ".themed/"
183 static void makeThemePack(WMPropList * style, const char *themeName)
185 WMPropList *keys;
186 WMPropList *key;
187 WMPropList *value;
188 int i;
189 size_t themeNameLen;
190 char *themeDir;
191 const char *user_base;
193 user_base = wusergnusteppath();
194 if (user_base == NULL)
195 return;
196 themeNameLen = strlen(user_base) + sizeof(THEME_SUBPATH) + strlen(themeName) + sizeof(THEME_EXTDIR) + 1;
197 themeDir = wmalloc(themeNameLen);
198 snprintf(themeDir, themeNameLen,
199 "%s" THEME_SUBPATH "%s" THEME_EXTDIR,
200 user_base, themeName);
201 ThemePath = themeDir;
203 if (!wmkdirhier(themeDir)) {
204 wwarning("Could not make theme dir %s\n", themeDir);
205 return;
208 keys = WMGetPLDictionaryKeys(style);
210 for (i = 0; i < WMGetPropListItemCount(keys); i++) {
211 key = WMGetFromPLArray(keys, i);
213 value = WMGetFromPLDictionary(style, key);
214 if (value && WMIsPLArray(value) && WMGetPropListItemCount(value) > 2) {
215 WMPropList *type;
216 char *t;
218 type = WMGetFromPLArray(value, 0);
219 t = WMGetFromPLString(type);
220 if (t == NULL)
221 continue;
223 if (strcasecmp(t, "tpixmap") == 0 ||
224 strcasecmp(t, "spixmap") == 0 ||
225 strcasecmp(t, "cpixmap") == 0 ||
226 strcasecmp(t, "mpixmap") == 0 ||
227 strcasecmp(t, "tdgradient") == 0 ||
228 strcasecmp(t, "tvgradient") == 0 ||
229 strcasecmp(t, "thgradient") == 0) {
231 WMPropList *file;
232 char *p;
233 char *newPath;
235 file = WMGetFromPLArray(value, 1);
237 p = strrchr(WMGetFromPLString(file), '/');
238 if (p) {
239 wcopy_file(themeDir, WMGetFromPLString(file), WMGetFromPLString(file));
241 newPath = wstrdup(p + 1);
242 WMDeleteFromPLArray(value, 1);
243 WMInsertInPLArray(value, 1, WMCreatePLString(newPath));
244 free(newPath);
245 } else {
246 findCopyFile(themeDir, WMGetFromPLString(file));
248 } else if (strcasecmp(t, "bitmap") == 0) {
250 WMPropList *file;
251 char *p;
252 char *newPath;
254 file = WMGetFromPLArray(value, 1);
256 p = strrchr(WMGetFromPLString(file), '/');
257 if (p) {
258 wcopy_file(themeDir, WMGetFromPLString(file), WMGetFromPLString(file));
260 newPath = wstrdup(p + 1);
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 wcopy_file(themeDir, WMGetFromPLString(file), WMGetFromPLString(file));
274 newPath = wstrdup(p + 1);
275 WMDeleteFromPLArray(value, 2);
276 WMInsertInPLArray(value, 2, WMCreatePLString(newPath));
277 free(newPath);
278 } else {
279 findCopyFile(themeDir, WMGetFromPLString(file));
284 WMReleasePropList(keys);
287 int main(int argc, char **argv)
289 WMPropList *prop, *style, *key, *val;
290 char *path;
291 int i, ch, theme_too = 0, make_pack = 0;
292 char *style_file = NULL;
294 struct option longopts[] = {
295 { "pack", no_argument, NULL, 'p' },
296 { "theme-options", no_argument, NULL, 't' },
297 { "version", no_argument, NULL, 'v' },
298 { "help", no_argument, NULL, 'h' },
299 { NULL, 0, NULL, 0 }
302 while ((ch = getopt_long(argc, argv, "ptvh", longopts, NULL)) != -1)
303 switch(ch) {
304 case 'v':
305 printf("%s (Window Maker %s)\n", __progname, VERSION);
306 return 0;
307 /* NOTREACHED */
308 case 'h':
309 print_help(1, 0);
310 /* NOTREACHED */
311 case 'p':
312 make_pack = 1;
313 theme_too = 1;
314 break;
315 case 't':
316 theme_too = 1;
317 case 0:
318 break;
319 default:
320 print_help(0, 1);
321 /* NOTREACHED */
324 /* At most one non-option ARGV-element is accepted (the theme name) */
325 if (argc - optind > 1)
326 print_help(0, 1);
328 if (argc - optind == 1)
329 style_file = argv[argc - 1];
331 if (make_pack && !style_file) {
332 printf("%s: you must supply a name for the theme pack\n", __progname);
333 return 1;
336 WMPLSetCaseSensitive(False);
338 path = wdefaultspathfordomain("WindowMaker");
340 prop = WMReadPropListFromFile(path);
341 if (!prop) {
342 printf("%s: could not load WindowMaker configuration file \"%s\".\n", __progname, path);
343 return 1;
346 /* get global value */
347 path = wglobaldefaultspathfordomain("WindowMaker");
349 val = WMReadPropListFromFile(path);
350 if (val) {
351 WMMergePLDictionaries(val, prop, True);
352 WMReleasePropList(prop);
353 prop = val;
356 style = WMCreatePLDictionary(NULL, NULL);
358 for (i = 0; options[i] != NULL; i++) {
359 key = WMCreatePLString(options[i]);
361 val = WMGetFromPLDictionary(prop, key);
362 if (val) {
363 WMRetainPropList(val);
364 if (isFontOption(options[i])) {
365 char *newfont, *oldfont;
367 oldfont = WMGetFromPLString(val);
368 newfont = convertFont(oldfont, False);
369 /* newfont is a reference to old if conversion is not needed */
370 if (newfont != oldfont) {
371 WMReleasePropList(val);
372 val = WMCreatePLString(newfont);
373 wfree(newfont);
376 WMPutInPLDictionary(style, key, val);
377 WMReleasePropList(val);
379 WMReleasePropList(key);
382 val = WMGetFromPLDictionary(prop, WMCreatePLString("PixmapPath"));
383 if (val)
384 PixmapPath = val;
386 if (theme_too) {
387 for (i = 0; theme_options[i] != NULL; i++) {
388 key = WMCreatePLString(theme_options[i]);
390 val = WMGetFromPLDictionary(prop, key);
391 if (val)
392 WMPutInPLDictionary(style, key, val);
396 if (make_pack) {
397 char *path;
399 makeThemePack(style, style_file);
401 path = wmalloc(strlen(ThemePath) + 32);
402 strcpy(path, ThemePath);
403 strcat(path, "/style");
404 WMWritePropListToFile(style, path);
405 wfree(path);
406 } else {
407 if (style_file) {
408 WMWritePropListToFile(style, style_file);
409 } else {
410 puts(WMGetPropListDescription(style, True));
413 return 0;