Fix some bugs, DisableMiniwindows, _KWM_WIN_ICON_GEOMETRY..
[wmaker-crm.git] / util / getstyle.c
blob1ea1e74a4bfbe3e4d19db8f979147397eba1ed10
1 /* getstyle.c - outputs style related options from WindowMaker to stdout
3 * WindowMaker window manager
4 *
5 * Copyright (c) 1997, 1998 Alfredo K. Kojima
6 *
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
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20 * USA.
24 #define PROG_VERSION "getstyle (Window Maker) 0.2"
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <proplist.h>
31 #include <string.h>
32 #include <unistd.h>
33 #include <string.h>
34 #include <pwd.h>
35 #include <limits.h>
36 #include <assert.h>
38 #ifndef PATH_MAX
39 #define PATH_MAX 1024
40 #endif
42 #include "../src/wconfig.h"
44 /* table of style related options */
45 static char *options[] = {
46 "TitleJustify",
47 "ClipTitleFont",
48 "WindowTitleFont",
49 "MenuTitleFont",
50 "MenuTextFont",
51 "IconTitleFont",
52 "DisplayFont",
53 "HighlightColor",
54 "HighlightTextColor",
55 "ClipTitleColor",
56 "CClipTitleColor",
57 "FTitleColor",
58 "PTitleColor",
59 "UTitleColor",
60 "FTitleBack",
61 "PTitleBack",
62 "UTitleBack",
63 "MenuTitleColor",
64 "MenuTextColor",
65 "MenuDisabledColor",
66 "MenuTitleBack",
67 "MenuTextBack",
68 "IconBack",
69 "IconTitleColor",
70 "IconTitleBack",
71 #ifdef TITLE_TEXT_SHADOW
72 "Shadow",
73 "FShadowColor",
74 "PShadowColor",
75 "UShadowColor",
76 "MShadowColor",
77 #endif
78 NULL
82 /* table of theme related options */
83 static char *theme_options[] = {
84 "WorkspaceBack",
85 NULL
91 char *ProgName;
93 proplist_t PixmapPath = NULL;
95 char *ThemePath = NULL;
98 void
99 print_help()
101 printf("Usage: %s [OPTIONS] [FILE]\n", ProgName);
102 puts("Retrieves style/theme configuration and output to FILE or to stdout");
103 puts("");
104 puts(" -t, --theme-options output theme related options when producing a style file");
105 puts(" -p, --pack produce output as a theme pack");
106 puts(" --help display this help and exit");
107 puts(" --version output version information and exit");
111 char*
112 globalDefaultsPathForDomain(char *domain)
114 char path[1024];
115 char *tmp;
117 sprintf(path, "%s/%s", SYSCONFDIR, domain);
119 tmp = malloc(strlen(path)+2);
120 assert(tmp!=NULL);
121 strcpy(tmp, path);
123 return tmp;
127 char*
128 defaultsPathForDomain(char *domain)
130 char path[1024];
131 char *gspath, *tmp;
133 gspath = getenv("GNUSTEP_USER_ROOT");
134 if (gspath) {
135 strcpy(path, gspath);
136 strcat(path, "/");
137 } else {
138 char *home;
140 home = getenv("HOME");
141 if (!home) {
142 printf("%s:could not get HOME environment variable!\n", ProgName);
143 exit(0);
145 strcpy(path, home);
146 strcat(path, "/GNUstep/");
148 strcat(path, DEFAULTS_DIR);
149 strcat(path, "/");
150 strcat(path, domain);
152 tmp = malloc(strlen(path)+2);
153 strcpy(tmp, path);
155 return tmp;
159 BOOL
160 StringCompareHook(proplist_t pl1, proplist_t pl2)
162 char *str1, *str2;
164 str1 = PLGetString(pl1);
165 str2 = PLGetString(pl2);
167 if (strcasecmp(str1, str2)==0)
168 return YES;
169 else
170 return NO;
174 void
175 abortar(char *reason)
177 char buffer[4000];
179 printf("%s: %s\n", ProgName, reason);
181 if (ThemePath) {
182 printf("Removing unfinished theme pack\n");
183 sprintf(buffer, "/bin/rm -fr %s", ThemePath);
185 if (system(buffer)!=0) {
186 printf("%s: could not execute command %s\n", ProgName, buffer);
189 exit(1);
195 char*
196 wgethomedir()
198 char *home = getenv("HOME");
199 struct passwd *user;
201 if (home)
202 return home;
204 user = getpwuid(getuid());
205 if (!user) {
206 char buffer[80];
208 sprintf(buffer, "could not get password entry for UID %i", getuid());
209 perror(buffer);
210 return "/";
212 if (!user->pw_dir) {
213 return "/";
214 } else {
215 return user->pw_dir;
220 void*
221 wmalloc(int size)
223 void *tmp;
225 tmp = malloc(size);
226 if (!tmp) {
227 abortar("out of memory");
230 return tmp;
234 char*
235 wstrdup(char *str)
237 char *tmp;
239 tmp = wmalloc(strlen(str)+1);
241 strcpy(tmp, str);
243 return tmp;
247 static char*
248 getuserhomedir(char *username)
250 struct passwd *user;
252 user = getpwnam(username);
253 if (!user) {
254 char buffer[100];
256 sprintf(buffer,"could not get password entry for user %s", username);
257 perror(buffer);
258 return NULL;
260 if (!user->pw_dir) {
261 return "/";
262 } else {
263 return user->pw_dir;
270 char*
271 wexpandpath(char *path)
273 char buffer2[PATH_MAX+2];
274 char buffer[PATH_MAX+2];
275 int i;
277 memset(buffer, 0, PATH_MAX+2);
279 if (*path=='~') {
280 char *home;
282 path++;
283 if (*path=='/' || *path==0) {
284 home = wgethomedir();
285 strcat(buffer, home);
286 } else {
287 int j;
288 j = 0;
289 while (*path!=0 && *path!='/') {
290 buffer2[j++] = *path;
291 buffer2[j] = 0;
292 path++;
294 home = getuserhomedir(buffer2);
295 if (!home)
296 return NULL;
297 strcat(buffer, home);
301 i = strlen(buffer);
303 while (*path!=0) {
304 char *tmp;
306 if (*path=='$') {
307 int j = 0;
308 path++;
309 /* expand $(HOME) or $HOME style environment variables */
310 if (*path=='(') {
311 path++;
312 while (*path!=0 && *path!=')') {
313 buffer2[j++] = *(path++);
314 buffer2[j] = 0;
316 if (*path==')')
317 path++;
318 tmp = getenv(buffer2);
319 if (!tmp) {
320 buffer[i] = 0;
321 strcat(buffer, "$(");
322 strcat(buffer, buffer2);
323 strcat(buffer, ")");
324 i += strlen(buffer2)+3;
325 } else {
326 strcat(buffer, tmp);
327 i += strlen(tmp);
329 } else {
330 while (*path!=0 && *path!='/') {
331 buffer2[j++] = *(path++);
332 buffer2[j] = 0;
334 tmp = getenv(buffer2);
335 if (!tmp) {
336 strcat(buffer, "$");
337 strcat(buffer, buffer2);
338 i += strlen(buffer2)+1;
339 } else {
340 strcat(buffer, tmp);
341 i += strlen(tmp);
344 } else {
345 buffer[i++] = *path;
346 path++;
350 return wstrdup(buffer);
355 char*
356 wfindfileinarray(proplist_t paths, char *file)
358 int i;
359 char *path;
360 int len, flen;
361 char *fullpath;
363 if (!file)
364 return NULL;
366 if (*file=='/' || *file=='~' || !paths || !PLIsArray(paths)
367 || PLGetNumberOfElements(paths)==0) {
368 if (access(file, R_OK)<0) {
369 fullpath = wexpandpath(file);
370 if (!fullpath)
371 return NULL;
373 if (access(fullpath, R_OK)<0) {
374 free(fullpath);
375 return NULL;
376 } else {
377 return fullpath;
379 } else {
380 return wstrdup(file);
384 flen = strlen(file);
385 for (i=0; i < PLGetNumberOfElements(paths); i++) {
386 proplist_t tmp;
387 char *dir;
389 tmp = PLGetArrayElement(paths, i);
390 if (!PLIsString(tmp) || !(dir = PLGetString(tmp)))
391 continue;
393 len = strlen(dir);
394 path = wmalloc(len+flen+2);
395 path = memcpy(path, dir, len);
396 path[len]=0;
397 strcat(path, "/");
398 strcat(path, file);
399 /* expand tilde */
400 fullpath = wexpandpath(path);
401 free(path);
402 if (fullpath) {
403 /* check if file is readable */
404 if (access(fullpath, R_OK)==0) {
405 return fullpath;
407 free(fullpath);
410 return NULL;
416 void
417 copyFile(char *dir, char *file)
419 char buffer[4000];
421 sprintf(buffer, "/bin/cp %s %s", file, dir);
422 if (system(buffer)!=0) {
423 printf("%s: could not copy file %s\n", ProgName, file);
428 void
429 findCopyFile(char *dir, char *file)
431 char *fullPath;
433 fullPath = wfindfileinarray(PixmapPath, file);
434 if (!fullPath) {
435 char buffer[4000];
437 sprintf(buffer, "coould not find file %s", file);
438 abortar(buffer);
440 copyFile(dir, fullPath);
441 free(fullPath);
445 char*
446 makeThemePack(proplist_t style, char *themeName)
448 proplist_t keys;
449 proplist_t key;
450 proplist_t value;
451 int i;
452 char *themeDir;
454 themeDir = wmalloc(strlen(themeName)+50);
455 sprintf(themeDir, "%s.themed", themeName);
456 ThemePath = themeDir;
458 char *tmp;
460 tmp = wmalloc(strlen(themeDir)+20);
461 sprintf(tmp, "/bin/mkdir %s", themeDir);
462 if (system(tmp)!=0) {
463 printf("%s: could not create directory %s\n", ProgName, themeDir);
464 exit(1);
466 free(tmp);
468 keys = PLGetAllDictionaryKeys(style);
470 for (i = 0; i < PLGetNumberOfElements(keys); i++) {
471 key = PLGetArrayElement(keys, i);
473 value = PLGetDictionaryEntry(style, key);
474 if (value && PLIsArray(value) && PLGetNumberOfElements(value) > 2) {
475 proplist_t type;
476 char *t;
478 type = PLGetArrayElement(value, 0);
479 t = PLGetString(type);
480 if (t && (strcasecmp(t, "tpixmap")==0
481 || strcasecmp(t, "spixmap")==0
482 || strcasecmp(t, "cpixmap")==0
483 || strcasecmp(t, "mpixmap")==0
484 || strcasecmp(t, "tdgradient")==0
485 || strcasecmp(t, "tvgradient")==0
486 || strcasecmp(t, "thgradient")==0)) {
487 proplist_t file;
488 char *p;
489 char *newPath;
491 file = PLGetArrayElement(value, 1);
493 p = strrchr(PLGetString(file), '/');
494 if (p) {
495 copyFile(themeDir, PLGetString(file));
497 newPath = wstrdup(p+1);
498 PLRemoveArrayElement(value, 1);
499 PLInsertArrayElement(value, PLMakeString(newPath), 1);
500 free(newPath);
501 } else {
502 findCopyFile(themeDir, PLGetString(file));
508 return themeDir;
512 int
513 main(int argc, char **argv)
515 proplist_t prop, style, key, val;
516 char *path;
517 int i, theme_too=0;
518 int make_pack = 0;
519 char *style_file = NULL;
522 ProgName = argv[0];
524 if (argc>1) {
525 for (i=1; i<argc; i++) {
526 if (strcmp(argv[i], "-p")==0
527 || strcmp(argv[i], "--pack")==0) {
528 make_pack = 1;
529 theme_too = 1;
530 } else if (strcmp(argv[i], "-t")==0
531 || strcmp(argv[i], "--theme-options")==0) {
532 theme_too++;
533 } else if (strcmp(argv[i], "--help")==0) {
534 print_help();
535 exit(0);
536 } else if (strcmp(argv[i], "--version")==0) {
537 puts(PROG_VERSION);
538 exit(0);
539 } else {
540 if (style_file!=NULL) {
541 printf("%s: invalid argument '%s'\n", argv[0],
542 style_file[0]=='-' ? style_file : argv[i]);
543 printf("Try '%s --help' for more information\n", argv[0]);
544 exit(1);
546 style_file = argv[i];
551 if (make_pack && !style_file) {
552 printf("%s: you must supply a name for the theme pack\n", ProgName);
553 exit(1);
556 PLSetStringCmpHook(StringCompareHook);
558 path = defaultsPathForDomain("WindowMaker");
560 prop = PLGetProplistWithPath(path);
561 if (!prop) {
562 printf("%s:could not load WindowMaker configuration file \"%s\".\n",
563 ProgName, path);
564 exit(1);
566 free(path);
568 /* get global value */
569 path = globalDefaultsPathForDomain("WindowMaker");
570 val = PLGetProplistWithPath(path);
571 if (val) {
572 PLMergeDictionaries(val, prop);
573 PLRelease(prop);
574 prop = val;
577 style = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
580 for (i=0; options[i]!=NULL; i++) {
581 key = PLMakeString(options[i]);
583 val = PLGetDictionaryEntry(prop, key);
584 if (val)
585 PLInsertDictionaryEntry(style, key, val);
588 val = PLGetDictionaryEntry(prop, PLMakeString("PixmapPath"));
589 if (val)
590 PixmapPath = val;
592 if (theme_too) {
593 for (i=0; theme_options[i]!=NULL; i++) {
594 key = PLMakeString(theme_options[i]);
596 val = PLGetDictionaryEntry(prop, key);
597 if (val)
598 PLInsertDictionaryEntry(style, key, val);
602 if (make_pack) {
603 char *path;
605 makeThemePack(style, style_file);
607 path = wmalloc(strlen(ThemePath)+32);
608 strcpy(path, ThemePath);
609 strcat(path, "/style");
610 PLSetFilename(style, PLMakeString(path));
611 PLSave(style, NO);
612 } else {
613 if (style_file) {
614 val = PLMakeString(style_file);
615 PLSetFilename(style, val);
616 PLSave(style, NO);
617 } else {
618 puts(PLGetDescriptionIndent(style, 0));
621 exit(0);