Allow setting separate border color for focused windows
[wmaker-crm.git] / util / getstyle.c
blob079b7d4013c49c09a9259e2740ddccb2becb8870
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 #define RETRY( x ) do { \
52 x; \
53 } while (errno == EINTR);
55 #ifndef PATH_MAX
56 #define PATH_MAX 1024
57 #endif
59 #include "../src/wconfig.h"
61 #ifndef GLOBAL_DEFAULTS_SUBDIR
62 #define GLOBAL_DEFAULTS_SUBDIR "WindowMaker"
63 #endif
65 /* table of style related options */
66 static char *options[] = {
67 "TitleJustify",
68 "ClipTitleFont",
69 "WindowTitleFont",
70 "MenuTitleFont",
71 "MenuTextFont",
72 "IconTitleFont",
73 "LargeDisplayFont",
74 "HighlightColor",
75 "HighlightTextColor",
76 "ClipTitleColor",
77 "CClipTitleColor",
78 "FTitleColor",
79 "PTitleColor",
80 "UTitleColor",
81 "FTitleBack",
82 "PTitleBack",
83 "UTitleBack",
84 "ResizebarBack",
85 "MenuTitleColor",
86 "MenuTextColor",
87 "MenuDisabledColor",
88 "MenuTitleBack",
89 "MenuTextBack",
90 "IconBack",
91 "IconTitleColor",
92 "IconTitleBack",
93 "FrameBorderWidth",
94 "FrameBorderColor",
95 "FrameFocusedBorderColor",
96 "FrameSelectedBorderColor",
97 "MenuStyle",
98 "WindowTitleExtendSpace",
99 "MenuTitleExtendSpace",
100 "MenuTextExtendSpace",
101 NULL
104 /* table of theme related options */
105 static char *theme_options[] = {
106 "WorkspaceBack",
107 "NormalCursor",
108 "ArrowCursor",
109 "MoveCursor",
110 "ResizeCursor",
111 "TopLeftResizeCursor",
112 "TopRightResizeCursor",
113 "BottomLeftResizeCursor",
114 "BottomRightResizeCursor",
115 "VerticalResizeCursor",
116 "HorizontalResizeCursor",
117 "WaitCursor",
118 "QuestionCursor",
119 "TextCursor",
120 "SelectCursor",
121 NULL
124 /* table of style related fonts */
126 static char *font_options[] = {
127 "ClipTitleFont",
128 "WindowTitleFont",
129 "MenuTitleFont",
130 "MenuTextFont",
131 "IconTitleFont",
132 "LargeDisplayFont",
133 NULL
136 extern char *__progname;
138 WMPropList *PixmapPath = NULL;
140 char *ThemePath = NULL;
143 static noreturn void print_help(int print_usage, int exitval)
145 printf("Usage: %s [-t] [-p] [-h] [-v] [file]\n", __progname);
146 if (print_usage) {
147 puts("Retrieves style/theme configuration and outputs to ~/GNUstep/Library/WindowMaker/Themes/file.themed/style or to stdout");
148 puts("");
149 puts(" -h, --help display this help and exit");
150 puts(" -v, --version output version information and exit");
151 puts(" -t, --theme-options output theme related options when producing a style file");
152 puts(" -p, --pack produce output as a theme pack");
154 exit(exitval);
157 static Bool isFontOption(const char *option)
159 int i;
161 for (i = 0; font_options[i] != NULL; i++) {
162 if (strcasecmp(option, font_options[i]) == 0) {
163 return True;
167 return False;
170 static void findCopyFile(const char *dir, const char *file)
172 char *fullPath;
174 fullPath = wfindfileinarray(PixmapPath, file);
175 if (!fullPath) {
176 wwarning("Could not find file %s", file);
177 if (ThemePath)
178 (void)wrmdirhier(ThemePath);
180 wcopy_file(dir, fullPath, fullPath);
181 free(fullPath);
184 static void makeThemePack(WMPropList * style, const char *themeName)
186 WMPropList *keys;
187 WMPropList *key;
188 WMPropList *value;
189 int i;
190 size_t themeNameLen;
191 char *themeDir;
192 const char *t;
194 if ((t = wusergnusteppath()) == NULL)
195 return;
196 themeNameLen = strlen(t) + strlen(themeName) + 50;
197 themeDir = wmalloc(themeNameLen);
198 snprintf(themeDir, themeNameLen, "%s/Library/WindowMaker/Themes/%s.themed/", t, 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));
284 int main(int argc, char **argv)
286 WMPropList *prop, *style, *key, *val;
287 char *path;
288 int i, ch, theme_too = 0, make_pack = 0;
289 char *style_file = NULL;
291 struct option longopts[] = {
292 { "pack", no_argument, NULL, 'p' },
293 { "theme-options", no_argument, NULL, 't' },
294 { "version", no_argument, NULL, 'v' },
295 { "help", no_argument, NULL, 'h' },
296 { NULL, 0, NULL, 0 }
299 while ((ch = getopt_long(argc, argv, "ptvh", longopts, NULL)) != -1)
300 switch(ch) {
301 case 'v':
302 printf("%s (Window Maker %s)\n", __progname, VERSION);
303 return 0;
304 /* NOTREACHED */
305 case 'h':
306 print_help(1, 0);
307 /* NOTREACHED */
308 case 'p':
309 make_pack = 1;
310 theme_too = 1;
311 break;
312 case 't':
313 theme_too = 1;
314 case 0:
315 break;
316 default:
317 print_help(0, 1);
318 /* NOTREACHED */
321 /* At most one non-option ARGV-element is accepted (the theme name) */
322 if (argc - optind > 1)
323 print_help(0, 1);
325 if (argc - optind == 1)
326 style_file = argv[argc - 1];
328 if (make_pack && !style_file) {
329 printf("%s: you must supply a name for the theme pack\n", __progname);
330 return 1;
333 WMPLSetCaseSensitive(False);
335 path = wdefaultspathfordomain("WindowMaker");
337 prop = WMReadPropListFromFile(path);
338 if (!prop) {
339 printf("%s: could not load WindowMaker configuration file \"%s\".\n", __progname, path);
340 return 1;
343 /* get global value */
344 path = wglobaldefaultspathfordomain("WindowMaker");
346 val = WMReadPropListFromFile(path);
347 if (val) {
348 WMMergePLDictionaries(val, prop, True);
349 WMReleasePropList(prop);
350 prop = val;
353 style = WMCreatePLDictionary(NULL, NULL);
355 for (i = 0; options[i] != NULL; i++) {
356 key = WMCreatePLString(options[i]);
358 val = WMGetFromPLDictionary(prop, key);
359 if (val) {
360 WMRetainPropList(val);
361 if (isFontOption(options[i])) {
362 char *newfont, *oldfont;
364 oldfont = WMGetFromPLString(val);
365 newfont = convertFont(oldfont, False);
366 /* newfont is a reference to old if conversion is not needed */
367 if (newfont != oldfont) {
368 WMReleasePropList(val);
369 val = WMCreatePLString(newfont);
370 wfree(newfont);
373 WMPutInPLDictionary(style, key, val);
374 WMReleasePropList(val);
376 WMReleasePropList(key);
379 val = WMGetFromPLDictionary(prop, WMCreatePLString("PixmapPath"));
380 if (val)
381 PixmapPath = val;
383 if (theme_too) {
384 for (i = 0; theme_options[i] != NULL; i++) {
385 key = WMCreatePLString(theme_options[i]);
387 val = WMGetFromPLDictionary(prop, key);
388 if (val)
389 WMPutInPLDictionary(style, key, val);
393 if (make_pack) {
394 char *path;
396 makeThemePack(style, style_file);
398 path = wmalloc(strlen(ThemePath) + 32);
399 strcpy(path, ThemePath);
400 strcat(path, "/style");
401 WMWritePropListToFile(style, path);
402 wfree(path);
403 } else {
404 if (style_file) {
405 WMWritePropListToFile(style, style_file);
406 } else {
407 puts(WMGetPropListDescription(style, True));
410 return 0;