Change to the linux kernel coding style
[wmaker-crm.git] / util / getstyle.c
Commit [+]AuthorDateLineData
9d2e6ef9 scottc1998-09-29 22:36:29 +00001/* getstyle.c - outputs style related options from WindowMaker to stdout
2 *
3 * WindowMaker window manager
6d02fe98 dan2004-04-13 03:49:38 +00004 *
4153e2fd dan2003-01-16 23:30:45 +00005 * Copyright (c) 1997-2003 Alfredo K. Kojima
6d02fe98 dan2004-04-13 03:49:38 +00006 *
9d2e6ef9 scottc1998-09-29 22:36:29 +00007 * 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.
11 *
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.
16 *
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
6d02fe98 dan2004-04-13 03:49:38 +000019 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
9d2e6ef9 scottc1998-09-29 22:36:29 +000020 * USA.
21 */
22
b3dee733 kojima2000-07-15 08:12:33 +000023#define PROG_VERSION "getstyle (Window Maker) 0.6"
931a37b1 dan1999-01-29 08:11:17 +000024
9d2e6ef9 scottc1998-09-29 22:36:29 +000025#include <stdlib.h>
26#include <stdio.h>
9d2e6ef9 scottc1998-09-29 22:36:29 +000027#include <string.h>
0261c326 dan1999-01-06 15:22:33 +000028#include <unistd.h>
29#include <string.h>
30#include <pwd.h>
31#include <limits.h>
e7495baf dan1999-02-17 11:06:40 +000032#include <assert.h>
33cc542e dan2001-10-04 03:07:34 +000033#include <WINGs/WUtil.h>
0261c326 dan1999-01-06 15:22:33 +000034
35#ifndef PATH_MAX
36#define PATH_MAX 1024
37#endif
9d2e6ef9 scottc1998-09-29 22:36:29 +000038
39#include "../src/wconfig.h"
40
41/* table of style related options */
42static char *options[] = {
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020043 "TitleJustify",
44 "ClipTitleFont",
45 "WindowTitleFont",
46 "MenuTitleFont",
47 "MenuTextFont",
48 "IconTitleFont",
49 "DisplayFont",
50 "LargeDisplayFont",
51 "WindowTitleExtendSpace",
52 "MenuTitleExtendSpace",
53 "MenuTextExtendSpace",
54 "HighlightColor",
55 "HighlightTextColor",
56 "ClipTitleColor",
57 "CClipTitleColor",
58 "FTitleColor",
59 "PTitleColor",
60 "UTitleColor",
61 "FTitleBack",
62 "PTitleBack",
63 "UTitleBack",
64 "ResizebarBack",
65 "MenuTitleColor",
66 "MenuTextColor",
67 "MenuDisabledColor",
68 "MenuTitleBack",
69 "MenuTextBack",
70 "IconBack",
71 "IconTitleColor",
72 "IconTitleBack",
73 "MenuStyle",
74 "WindowTitleExtendSpace",
75 "MenuTitleExtendSpace",
76 "MenuTextExtendSpace",
77 NULL
9d2e6ef9 scottc1998-09-29 22:36:29 +000078};
79
9d2e6ef9 scottc1998-09-29 22:36:29 +000080/* table of theme related options */
81static char *theme_options[] = {
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020082 "WorkspaceBack",
83 "NormalCursor",
84 "ArrowCursor",
85 "MoveCursor",
86 "ResizeCursor",
87 "TopLeftResizeCursor",
88 "TopRightResizeCursor",
89 "BottomLeftResizeCursor",
90 "BottomRightResizeCursor",
91 "VerticalResizeCursor",
92 "HorizontalResizeCursor",
93 "WaitCursor",
94 "QuestionCursor",
95 "TextCursor",
96 "SelectCursor",
97 NULL
9d2e6ef9 scottc1998-09-29 22:36:29 +000098};
99
f54b0de7 vlaad2004-04-10 14:55:55 +0000100/* table of style related fonts */
9d2e6ef9 scottc1998-09-29 22:36:29 +0000101
6d02fe98 dan2004-04-13 03:49:38 +0000102static char *font_options[] = {
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200103 "ClipTitleFont",
104 "WindowTitleFont",
105 "MenuTitleFont",
106 "MenuTextFont",
107 "IconTitleFont",
108 "DisplayFont",
109 "LargeDisplayFont",
110 NULL
f54b0de7 vlaad2004-04-10 14:55:55 +0000111};
112
9d2e6ef9 scottc1998-09-29 22:36:29 +0000113char *ProgName;
114
33cc542e dan2001-10-04 03:07:34 +0000115WMPropList *PixmapPath = NULL;
0261c326 dan1999-01-06 15:22:33 +0000116
117char *ThemePath = NULL;
118
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200119extern char *convertFont(char *font, Bool keepXLFD);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000120
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200121void print_help()
9d2e6ef9 scottc1998-09-29 22:36:29 +0000122{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200123 printf("Usage: %s [OPTIONS] [FILE]\n", ProgName);
124 puts("Retrieves style/theme configuration and output to FILE or to stdout");
125 puts("");
126 puts(" -t, --theme-options output theme related options when producing a style file");
127 puts(" -p, --pack produce output as a theme pack");
128 puts(" --help display this help and exit");
129 puts(" --version output version information and exit");
9d2e6ef9 scottc1998-09-29 22:36:29 +0000130}
131
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200132char *globalDefaultsPathForDomain(char *domain)
416e3a82 dan1999-01-25 19:06:50 +0000133{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200134 static char path[1024];
416e3a82 dan1999-01-25 19:06:50 +0000135
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200136 sprintf(path, "%s/WindowMaker/%s", SYSCONFDIR, domain);
416e3a82 dan1999-01-25 19:06:50 +0000137
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200138 return path;
416e3a82 dan1999-01-25 19:06:50 +0000139}
140
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200141char *defaultsPathForDomain(char *domain)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000142{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200143 static char path[1024];
144 char *gspath;
145
146 gspath = getenv("GNUSTEP_USER_ROOT");
147 if (gspath) {
148 strcpy(path, gspath);
149 strcat(path, "/");
150 } else {
151 char *home;
152
153 home = getenv("HOME");
154 if (!home) {
155 printf("%s:could not get HOME environment variable!\n", ProgName);
156 exit(0);
157 }
158 strcpy(path, home);
159 strcat(path, "/GNUstep/");
160 }
161 strcat(path, DEFAULTS_DIR);
162 strcat(path, "/");
163 strcat(path, domain);
164
165 return path;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000166}
167
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200168void abortar(char *reason)
0261c326 dan1999-01-06 15:22:33 +0000169{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200170 char buffer[4000];
0261c326 dan1999-01-06 15:22:33 +0000171
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200172 printf("%s: %s\n", ProgName, reason);
0261c326 dan1999-01-06 15:22:33 +0000173
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200174 if (ThemePath) {
175 printf("Removing unfinished theme pack\n");
176 sprintf(buffer, "/bin/rm -fr \"%s\"", ThemePath);
6d02fe98 dan2004-04-13 03:49:38 +0000177
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200178 if (system(buffer) != 0) {
179 printf("%s: could not execute command %s\n", ProgName, buffer);
180 }
181 }
182 exit(1);
0261c326 dan1999-01-06 15:22:33 +0000183}
184
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200185char *wgethomedir()
0261c326 dan1999-01-06 15:22:33 +0000186{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200187 char *home = getenv("HOME");
188 struct passwd *user;
189
190 if (home)
191 return home;
192
193 user = getpwuid(getuid());
194 if (!user) {
195 char buffer[80];
196
197 sprintf(buffer, "could not get password entry for UID %i", getuid());
198 perror(buffer);
199 return "/";
200 }
201 if (!user->pw_dir) {
202 return "/";
203 } else {
204 return user->pw_dir;
205 }
0261c326 dan1999-01-06 15:22:33 +0000206}
207
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200208static char *getuserhomedir(char *username)
0261c326 dan1999-01-06 15:22:33 +0000209{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200210 struct passwd *user;
211
212 user = getpwnam(username);
213 if (!user) {
214 char buffer[100];
215
216 sprintf(buffer, "could not get password entry for user %s", username);
217 perror(buffer);
218 return NULL;
219 }
220 if (!user->pw_dir) {
221 return "/";
222 } else {
223 return user->pw_dir;
224 }
0261c326 dan1999-01-06 15:22:33 +0000225}
226
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200227char *wexpandpath(char *path)
0261c326 dan1999-01-06 15:22:33 +0000228{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200229 char buffer2[PATH_MAX + 2];
230 char buffer[PATH_MAX + 2];
231 int i;
232
233 memset(buffer, 0, PATH_MAX + 2);
234
235 if (*path == '~') {
236 char *home;
237
238 path++;
239 if (*path == '/' || *path == 0) {
240 home = wgethomedir();
241 strcat(buffer, home);
242 } else {
243 int j;
244 j = 0;
245 while (*path != 0 && *path != '/') {
246 buffer2[j++] = *path;
247 buffer2[j] = 0;
248 path++;
249 }
250 home = getuserhomedir(buffer2);
251 if (!home)
252 return NULL;
253 strcat(buffer, home);
254 }
255 }
256
257 i = strlen(buffer);
258
259 while (*path != 0) {
260 char *tmp;
261
262 if (*path == '$') {
263 int j = 0;
264 path++;
265 /* expand $(HOME) or $HOME style environment variables */
266 if (*path == '(') {
267 path++;
268 while (*path != 0 && *path != ')') {
269 buffer2[j++] = *(path++);
270 buffer2[j] = 0;
271 }
272 if (*path == ')')
273 path++;
274 tmp = getenv(buffer2);
275 if (!tmp) {
276 buffer[i] = 0;
277 strcat(buffer, "$(");
278 strcat(buffer, buffer2);
279 strcat(buffer, ")");
280 i += strlen(buffer2) + 3;
281 } else {
282 strcat(buffer, tmp);
283 i += strlen(tmp);
284 }
285 } else {
286 while (*path != 0 && *path != '/') {
287 buffer2[j++] = *(path++);
288 buffer2[j] = 0;
289 }
290 tmp = getenv(buffer2);
291 if (!tmp) {
292 strcat(buffer, "$");
293 strcat(buffer, buffer2);
294 i += strlen(buffer2) + 1;
295 } else {
296 strcat(buffer, tmp);
297 i += strlen(tmp);
298 }
299 }
300 } else {
301 buffer[i++] = *path;
302 path++;
303 }
304 }
305
306 return wstrdup(buffer);
0261c326 dan1999-01-06 15:22:33 +0000307}
308
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200309char *wfindfileinarray(WMPropList * paths, char *file)
0261c326 dan1999-01-06 15:22:33 +0000310{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200311 int i;
312 char *path;
313 int len, flen;
314 char *fullpath;
315
316 if (!file)
317 return NULL;
318
319 if (*file == '/' || *file == '~' || !paths || !WMIsPLArray(paths)
320 || WMGetPropListItemCount(paths) == 0) {
321 if (access(file, R_OK) < 0) {
322 fullpath = wexpandpath(file);
323 if (!fullpath)
324 return NULL;
325
326 if (access(fullpath, R_OK) < 0) {
327 free(fullpath);
328 return NULL;
329 } else {
330 return fullpath;
331 }
332 } else {
333 return wstrdup(file);
334 }
335 }
336
337 flen = strlen(file);
338 for (i = 0; i < WMGetPropListItemCount(paths); i++) {
339 WMPropList *tmp;
340 char *dir;
341
342 tmp = WMGetFromPLArray(paths, i);
343 if (!WMIsPLString(tmp) || !(dir = WMGetFromPLString(tmp)))
344 continue;
345
346 len = strlen(dir);
347 path = wmalloc(len + flen + 2);
348 path = memcpy(path, dir, len);
349 path[len] = 0;
350 strcat(path, "/");
351 strcat(path, file);
352 /* expand tilde */
353 fullpath = wexpandpath(path);
354 free(path);
355 if (fullpath) {
356 /* check if file is readable */
357 if (access(fullpath, R_OK) == 0) {
358 return fullpath;
359 }
360 free(fullpath);
361 }
362 }
363 return NULL;
0261c326 dan1999-01-06 15:22:33 +0000364}
365
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200366static Bool isFontOption(char *option)
f54b0de7 vlaad2004-04-10 14:55:55 +0000367{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200368 int i;
6d02fe98 dan2004-04-13 03:49:38 +0000369
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200370 for (i = 0; font_options[i] != NULL; i++) {
371 if (strcasecmp(option, font_options[i]) == 0) {
372 return True;
373 }
374 }
6d02fe98 dan2004-04-13 03:49:38 +0000375
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200376 return False;
f54b0de7 vlaad2004-04-10 14:55:55 +0000377}
378
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200379void copyFile(char *dir, char *file)
0261c326 dan1999-01-06 15:22:33 +0000380{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200381 char buffer[4000];
6d02fe98 dan2004-04-13 03:49:38 +0000382
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200383 sprintf(buffer, "/bin/cp \"%s\" \"%s\"", file, dir);
384 if (system(buffer) != 0) {
385 printf("%s: could not copy file %s\n", ProgName, file);
386 }
0261c326 dan1999-01-06 15:22:33 +0000387}
388
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200389void findCopyFile(char *dir, char *file)
0261c326 dan1999-01-06 15:22:33 +0000390{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200391 char *fullPath;
0261c326 dan1999-01-06 15:22:33 +0000392
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200393 fullPath = wfindfileinarray(PixmapPath, file);
394 if (!fullPath) {
395 char buffer[4000];
416e3a82 dan1999-01-25 19:06:50 +0000396
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200397 sprintf(buffer, "could not find file %s", file);
398 abortar(buffer);
399 }
400 copyFile(dir, fullPath);
401 free(fullPath);
0261c326 dan1999-01-06 15:22:33 +0000402}
403
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200404char *makeThemePack(WMPropList * style, char *themeName)
0261c326 dan1999-01-06 15:22:33 +0000405{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200406 WMPropList *keys;
407 WMPropList *key;
408 WMPropList *value;
409 int i;
410 char *themeDir;
411
412 themeDir = wmalloc(strlen(themeName) + 50);
413 sprintf(themeDir, "%s.themed", themeName);
414 ThemePath = themeDir;
415 {
416 char *tmp;
417
418 tmp = wmalloc(strlen(themeDir) + 20);
419 sprintf(tmp, "/bin/mkdir \"%s\"", themeDir);
420 if (system(tmp) != 0) {
421 printf
422 ("%s: could not create directory %s. Probably there's already a theme with that name in this directory.\n",
423 ProgName, themeDir);
424 exit(1);
425 }
426 free(tmp);
427 }
428 keys = WMGetPLDictionaryKeys(style);
429
430 for (i = 0; i < WMGetPropListItemCount(keys); i++) {
431 key = WMGetFromPLArray(keys, i);
432
433 value = WMGetFromPLDictionary(style, key);
434 if (value && WMIsPLArray(value) && WMGetPropListItemCount(value) > 2) {
435 WMPropList *type;
436 char *t;
437
438 type = WMGetFromPLArray(value, 0);
439 t = WMGetFromPLString(type);
440 if (t == NULL)
441 continue;
442
443 if (strcasecmp(t, "tpixmap") == 0
444 || strcasecmp(t, "spixmap") == 0
445 || strcasecmp(t, "cpixmap") == 0
446 || strcasecmp(t, "mpixmap") == 0
447 || strcasecmp(t, "tdgradient") == 0
448 || strcasecmp(t, "tvgradient") == 0 || strcasecmp(t, "thgradient") == 0) {
449 WMPropList *file;
450 char *p;
451 char *newPath;
452
453 file = WMGetFromPLArray(value, 1);
454
455 p = strrchr(WMGetFromPLString(file), '/');
456 if (p) {
457 copyFile(themeDir, WMGetFromPLString(file));
458
459 newPath = wstrdup(p + 1);
460 WMDeleteFromPLArray(value, 1);
461 WMInsertInPLArray(value, 1, WMCreatePLString(newPath));
462 free(newPath);
463 } else {
464 findCopyFile(themeDir, WMGetFromPLString(file));
465 }
466 } else if (strcasecmp(t, "bitmap") == 0) {
467 WMPropList *file;
468 char *p;
469 char *newPath;
470
471 file = WMGetFromPLArray(value, 1);
472
473 p = strrchr(WMGetFromPLString(file), '/');
474 if (p) {
475 copyFile(themeDir, WMGetFromPLString(file));
476
477 newPath = wstrdup(p + 1);
478 WMDeleteFromPLArray(value, 1);
479 WMInsertInPLArray(value, 1, WMCreatePLString(newPath));
480 free(newPath);
481 } else {
482 findCopyFile(themeDir, WMGetFromPLString(file));
483 }
484
485 file = WMGetFromPLArray(value, 2);
486
487 p = strrchr(WMGetFromPLString(file), '/');
488 if (p) {
489 copyFile(themeDir, WMGetFromPLString(file));
490
491 newPath = wstrdup(p + 1);
492 WMDeleteFromPLArray(value, 2);
493 WMInsertInPLArray(value, 2, WMCreatePLString(newPath));
494 free(newPath);
495 } else {
496 findCopyFile(themeDir, WMGetFromPLString(file));
497 }
498 }
499 }
500 }
501
502 return themeDir;
0261c326 dan1999-01-06 15:22:33 +0000503}
504
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200505int main(int argc, char **argv)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000506{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200507 WMPropList *prop, *style, *key, *val;
508 char *path;
509 int i, theme_too = 0, make_pack = 0;
510 char *style_file = NULL;
511
512 ProgName = argv[0];
513
514 if (argc > 1) {
515 for (i = 1; i < argc; i++) {
516 if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "--pack") == 0) {
517 make_pack = 1;
518 theme_too = 1;
519 } else if (strcmp(argv[i], "-t") == 0 || strcmp(argv[i], "--theme-options") == 0) {
520 theme_too++;
521 } else if (strcmp(argv[i], "--help") == 0) {
522 print_help();
523 exit(0);
524 } else if (strcmp(argv[i], "--version") == 0) {
525 puts(PROG_VERSION);
526 exit(0);
527 } else {
528 if (style_file != NULL) {
529 printf("%s: invalid argument '%s'\n", argv[0],
530 style_file[0] == '-' ? style_file : argv[i]);
531 printf("Try '%s --help' for more information\n", argv[0]);
532 exit(1);
533 }
534 style_file = argv[i];
535 }
536 }
537 }
538
539 if (make_pack && !style_file) {
540 printf("%s: you must supply a name for the theme pack\n", ProgName);
541 exit(1);
542 }
543
544 WMPLSetCaseSensitive(False);
545
546 path = defaultsPathForDomain("WindowMaker");
547
548 prop = WMReadPropListFromFile(path);
549 if (!prop) {
550 printf("%s:could not load WindowMaker configuration file \"%s\".\n", ProgName, path);
551 exit(1);
552 }
553
554 /* get global value */
555 path = globalDefaultsPathForDomain("WindowMaker");
556 val = WMReadPropListFromFile(path);
557 if (val) {
558 WMMergePLDictionaries(val, prop, True);
559 WMReleasePropList(prop);
560 prop = val;
561 }
562
563 style = WMCreatePLDictionary(NULL, NULL);
564
565 for (i = 0; options[i] != NULL; i++) {
566 key = WMCreatePLString(options[i]);
567
568 val = WMGetFromPLDictionary(prop, key);
569 if (val) {
570 WMRetainPropList(val);
571 if (isFontOption(options[i])) {
572 char *newfont, *oldfont;
573
574 oldfont = WMGetFromPLString(val);
575 newfont = convertFont(oldfont, False);
576 /* newfont is a reference to old if conversion is not needed */
577 if (newfont != oldfont) {
578 WMReleasePropList(val);
579 val = WMCreatePLString(newfont);
580 wfree(newfont);
581 }
582 }
583 WMPutInPLDictionary(style, key, val);
584 WMReleasePropList(val);
585 }
586 WMReleasePropList(key);
587 }
588
589 val = WMGetFromPLDictionary(prop, WMCreatePLString("PixmapPath"));
590 if (val)
591 PixmapPath = val;
592
593 if (theme_too) {
594 for (i = 0; theme_options[i] != NULL; i++) {
595 key = WMCreatePLString(theme_options[i]);
596
597 val = WMGetFromPLDictionary(prop, key);
598 if (val)
599 WMPutInPLDictionary(style, key, val);
600 }
601 }
602
603 if (make_pack) {
604 char *path;
605
606 makeThemePack(style, style_file);
607
608 path = wmalloc(strlen(ThemePath) + 32);
609 strcpy(path, ThemePath);
610 strcat(path, "/style");
611 WMWritePropListToFile(style, path, False);
612 wfree(path);
613 } else {
614 if (style_file) {
615 WMWritePropListToFile(style, style_file, False);
616 } else {
617 puts(WMGetPropListDescription(style, True));
618 }
619 }
620 exit(0);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000621}