wmaker-check: rewrote parsing of structure fields for callback checker
[wmaker-crm.git] / util / getstyle.c
blobf0de4c49dfa57f27c4ef6e6def65447be2183a3d
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, fullPath);
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 wcopy_file(themeDir, WMGetFromPLString(file), WMGetFromPLString(file));
239 newPath = wstrdup(p + 1);
240 WMDeleteFromPLArray(value, 1);
241 WMInsertInPLArray(value, 1, WMCreatePLString(newPath));
242 free(newPath);
243 } else {
244 findCopyFile(themeDir, WMGetFromPLString(file));
246 } else if (strcasecmp(t, "bitmap") == 0) {
248 WMPropList *file;
249 char *p;
250 char *newPath;
252 file = WMGetFromPLArray(value, 1);
254 p = strrchr(WMGetFromPLString(file), '/');
255 if (p) {
256 wcopy_file(themeDir, WMGetFromPLString(file), WMGetFromPLString(file));
258 newPath = wstrdup(p + 1);
259 WMDeleteFromPLArray(value, 1);
260 WMInsertInPLArray(value, 1, WMCreatePLString(newPath));
261 free(newPath);
262 } else {
263 findCopyFile(themeDir, WMGetFromPLString(file));
266 file = WMGetFromPLArray(value, 2);
268 p = strrchr(WMGetFromPLString(file), '/');
269 if (p) {
270 wcopy_file(themeDir, WMGetFromPLString(file), WMGetFromPLString(file));
272 newPath = wstrdup(p + 1);
273 WMDeleteFromPLArray(value, 2);
274 WMInsertInPLArray(value, 2, WMCreatePLString(newPath));
275 free(newPath);
276 } else {
277 findCopyFile(themeDir, WMGetFromPLString(file));
282 WMReleasePropList(keys);
285 int main(int argc, char **argv)
287 WMPropList *prop, *style, *key, *val;
288 char *path;
289 int i, ch, theme_too = 0, make_pack = 0;
290 char *style_file = NULL;
292 struct option longopts[] = {
293 { "pack", no_argument, NULL, 'p' },
294 { "theme-options", no_argument, NULL, 't' },
295 { "version", no_argument, NULL, 'v' },
296 { "help", no_argument, NULL, 'h' },
297 { NULL, 0, NULL, 0 }
300 prog_name = argv[0];
301 while ((ch = getopt_long(argc, argv, "ptvh", longopts, NULL)) != -1)
302 switch(ch) {
303 case 'v':
304 printf("%s (Window Maker %s)\n", prog_name, VERSION);
305 return 0;
306 /* NOTREACHED */
307 case 'h':
308 print_help(1, 0);
309 /* NOTREACHED */
310 case 'p':
311 make_pack = 1;
312 theme_too = 1;
313 break;
314 case 't':
315 theme_too = 1;
316 case 0:
317 break;
318 default:
319 print_help(0, 1);
320 /* NOTREACHED */
323 /* At most one non-option ARGV-element is accepted (the theme name) */
324 if (argc - optind > 1)
325 print_help(0, 1);
327 if (argc - optind == 1)
328 style_file = argv[argc - 1];
330 if (make_pack && !style_file) {
331 printf("%s: you must supply a name for the theme pack\n", prog_name);
332 return 1;
335 WMPLSetCaseSensitive(False);
337 path = wdefaultspathfordomain("WindowMaker");
339 prop = WMReadPropListFromFile(path);
340 if (!prop) {
341 printf("%s: could not load WindowMaker configuration file \"%s\".\n", prog_name, path);
342 return 1;
345 /* get global value */
346 path = wglobaldefaultspathfordomain("WindowMaker");
348 val = WMReadPropListFromFile(path);
349 if (val) {
350 WMMergePLDictionaries(val, prop, True);
351 WMReleasePropList(prop);
352 prop = val;
355 style = WMCreatePLDictionary(NULL, NULL);
357 for (i = 0; options[i] != NULL; i++) {
358 key = WMCreatePLString(options[i]);
360 val = WMGetFromPLDictionary(prop, key);
361 if (val) {
362 WMRetainPropList(val);
363 if (isFontOption(options[i])) {
364 char *newfont, *oldfont;
366 oldfont = WMGetFromPLString(val);
367 newfont = convertFont(oldfont, False);
368 /* newfont is a reference to old if conversion is not needed */
369 if (newfont != oldfont) {
370 WMReleasePropList(val);
371 val = WMCreatePLString(newfont);
372 wfree(newfont);
375 WMPutInPLDictionary(style, key, val);
376 WMReleasePropList(val);
378 WMReleasePropList(key);
381 val = WMGetFromPLDictionary(prop, WMCreatePLString("PixmapPath"));
382 if (val)
383 PixmapPath = val;
385 if (theme_too) {
386 for (i = 0; theme_options[i] != NULL; i++) {
387 key = WMCreatePLString(theme_options[i]);
389 val = WMGetFromPLDictionary(prop, key);
390 if (val)
391 WMPutInPLDictionary(style, key, val);
395 if (make_pack) {
396 char *path;
398 makeThemePack(style, style_file);
400 path = wmalloc(strlen(ThemePath) + 32);
401 strcpy(path, ThemePath);
402 strcat(path, "/style");
403 WMWritePropListToFile(style, path);
404 wfree(path);
405 } else {
406 if (style_file) {
407 WMWritePropListToFile(style, style_file);
408 } else {
409 puts(WMGetPropListDescription(style, True));
412 return 0;