/* setstyle.c - loads style related options to wmaker * * WindowMaker window manager * * Copyright (c) 1997-2003 Alfredo K. Kojima * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef __GLIBC__ #define _GNU_SOURCE /* getopt_long */ #endif #include "config.h" #include #include #include #include #include #include #include #include #include #ifdef HAVE_STDNORETURN #include #endif #include #include "../src/wconfig.h" #include "common.h" #define MAX_OPTIONS 128 char *FontOptions[] = { "IconTitleFont", "ClipTitleFont", "LargeDisplayFont", "MenuTextFont", "MenuTitleFont", "WindowTitleFont", NULL }; char *CursorOptions[] = { "NormalCursor", "ArrowCursor", "MoveCursor", "ResizeCursor", "TopLeftResizeCursor", "TopRightResizeCursor", "BottomLeftResizeCursor", "BottomRightResizeCursor", "VerticalResizeCursor", "HorizontalResizeCursor", "WaitCursor", "QuestionCursor", "TextCursor", "SelectCursor", NULL }; static const char *prog_name; int ignoreFonts = 0; int ignoreCursors = 0; Display *dpy; static Bool isCursorOption(const char *option) { int i; for (i = 0; CursorOptions[i] != NULL; i++) { if (strcasecmp(option, CursorOptions[i]) == 0) { return True; } } return False; } static Bool isFontOption(const char *option) { int i; for (i = 0; FontOptions[i] != NULL; i++) { if (strcasecmp(option, FontOptions[i]) == 0) { return True; } } return False; } /* * finds elements in `texture' that reference external files, * prepends `prefix' to these files. `prefix' is a path component * that qualifies the external references to be absolute, possibly * pending further expansion */ static void hackPathInTexture(WMPropList * texture, const char *prefix) { WMPropList *type; char *t; /* get texture type */ type = WMGetFromPLArray(texture, 0); t = WMGetFromPLString(type); if (t == NULL) return; if (strcasecmp(t, "tpixmap") == 0 || strcasecmp(t, "spixmap") == 0 || strcasecmp(t, "mpixmap") == 0 || strcasecmp(t, "cpixmap") == 0 || strcasecmp(t, "fpixmap") == 0 || strcasecmp(t, "tvgradient") == 0 || strcasecmp(t, "thgradient") == 0 || strcasecmp(t, "tdgradient") == 0) { WMPropList *file; char buffer[4018]; /* get pixmap file path */ file = WMGetFromPLArray(texture, 1); sprintf(buffer, "%s/%s", prefix, WMGetFromPLString(file)); /* replace path with full path */ WMDeleteFromPLArray(texture, 1); WMInsertInPLArray(texture, 1, WMCreatePLString(buffer)); } else if (strcasecmp(t, "bitmap") == 0) { WMPropList *file; char buffer[4018]; /* get bitmap file path */ file = WMGetFromPLArray(texture, 1); sprintf(buffer, "%s/%s", prefix, WMGetFromPLString(file)); /* replace path with full path */ WMDeleteFromPLArray(texture, 1); WMInsertInPLArray(texture, 1, WMCreatePLString(buffer)); /* get mask file path */ file = WMGetFromPLArray(texture, 2); sprintf(buffer, "%s/%s", prefix, WMGetFromPLString(file)); /* replace path with full path */ WMDeleteFromPLArray(texture, 2); WMInsertInPLArray(texture, 2, WMCreatePLString(buffer)); } } static void hackPaths(WMPropList * style, const char *prefix) { WMPropList *keys; WMPropList *key; WMPropList *value; int i; keys = WMGetPLDictionaryKeys(style); for (i = 0; i < WMGetPropListItemCount(keys); i++) { key = WMGetFromPLArray(keys, i); value = WMGetFromPLDictionary(style, key); if (!value) continue; if (strcasecmp(WMGetFromPLString(key), "WorkspaceSpecificBack") == 0) { if (WMIsPLArray(value)) { int j; WMPropList *texture; for (j = 0; j < WMGetPropListItemCount(value); j++) { texture = WMGetFromPLArray(value, j); if (texture && WMIsPLArray(texture) && WMGetPropListItemCount(texture) > 2) { hackPathInTexture(texture, prefix); } } } } else { if (WMIsPLArray(value) && WMGetPropListItemCount(value) > 2) { hackPathInTexture(value, prefix); } } } WMReleasePropList(keys); } static WMPropList *getColor(WMPropList * texture) { WMPropList *value, *type; char *str; type = WMGetFromPLArray(texture, 0); if (!type) return NULL; value = NULL; str = WMGetFromPLString(type); if (strcasecmp(str, "solid") == 0) { value = WMGetFromPLArray(texture, 1); } else if (strcasecmp(str, "dgradient") == 0 || strcasecmp(str, "hgradient") == 0 || strcasecmp(str, "vgradient") == 0) { WMPropList *c1, *c2; int r1, g1, b1, r2, g2, b2; char buffer[32]; c1 = WMGetFromPLArray(texture, 1); c2 = WMGetFromPLArray(texture, 2); if (!dpy) { if (sscanf(WMGetFromPLString(c1), "#%2x%2x%2x", &r1, &g1, &b1) == 3 && sscanf(WMGetFromPLString(c2), "#%2x%2x%2x", &r2, &g2, &b2) == 3) { sprintf(buffer, "#%02x%02x%02x", (r1 + r2) / 2, (g1 + g2) / 2, (b1 + b2) / 2); value = WMCreatePLString(buffer); } else { value = c1; } } else { XColor color1; XColor color2; XParseColor(dpy, DefaultColormap(dpy, DefaultScreen(dpy)), WMGetFromPLString(c1), &color1); XParseColor(dpy, DefaultColormap(dpy, DefaultScreen(dpy)), WMGetFromPLString(c2), &color2); sprintf(buffer, "#%02x%02x%02x", (color1.red + color2.red) >> 9, (color1.green + color2.green) >> 9, (color1.blue + color2.blue) >> 9); value = WMCreatePLString(buffer); } } else if (strcasecmp(str, "mdgradient") == 0 || strcasecmp(str, "mhgradient") == 0 || strcasecmp(str, "mvgradient") == 0) { value = WMGetFromPLArray(texture, 1); } else if (strcasecmp(str, "tpixmap") == 0 || strcasecmp(str, "cpixmap") == 0 || strcasecmp(str, "spixmap") == 0) { value = WMGetFromPLArray(texture, 2); } return value; } /* * since some of the options introduce incompatibilities, we will need * to do a kluge here or the themes ppl will get real annoying. * So, treat for the absence of the following options: * IconTitleColor * IconTitleBack */ static void hackStyle(WMPropList * style) { WMPropList *keys, *tmp; int foundIconTitle = 0, foundResizebarBack = 0; int i; keys = WMGetPLDictionaryKeys(style); for (i = 0; i < WMGetPropListItemCount(keys); i++) { char *str; tmp = WMGetFromPLArray(keys, i); str = WMGetFromPLString(tmp); if (str) { if (ignoreFonts && isFontOption(str)) { WMRemoveFromPLDictionary(style, tmp); continue; } if (ignoreCursors && isCursorOption(str)) { WMRemoveFromPLDictionary(style, tmp); continue; } if (isFontOption(str)) { WMPropList *value; char *newfont, *oldfont; value = WMGetFromPLDictionary(style, tmp); if (value) { oldfont = WMGetFromPLString(value); newfont = convertFont(oldfont, False); if (newfont != oldfont) { value = WMCreatePLString(newfont); WMPutInPLDictionary(style, tmp, value); WMReleasePropList(value); wfree(newfont); } } } if (strcasecmp(str, "IconTitleColor") == 0 || strcasecmp(str, "IconTitleBack") == 0) { foundIconTitle = 1; } else if (strcasecmp(str, "ResizebarBack") == 0) { foundResizebarBack = 1; } } } WMReleasePropList(keys); if (!foundIconTitle) { /* set the default values */ tmp = WMGetFromPLDictionary(style, WMCreatePLString("FTitleColor")); if (tmp) { WMPutInPLDictionary(style, WMCreatePLString("IconTitleColor"), tmp); } tmp = WMGetFromPLDictionary(style, WMCreatePLString("FTitleBack")); if (tmp) { WMPropList *value; value = getColor(tmp); if (value) { WMPutInPLDictionary(style, WMCreatePLString("IconTitleBack"), value); } } } if (!foundResizebarBack) { /* set the default values */ tmp = WMGetFromPLDictionary(style, WMCreatePLString("UTitleBack")); if (tmp) { WMPropList *value; value = getColor(tmp); if (value) { WMPropList *t; t = WMCreatePLArray(WMCreatePLString("solid"), value, NULL); WMPutInPLDictionary(style, WMCreatePLString("ResizebarBack"), t); } } } if (!WMGetFromPLDictionary(style, WMCreatePLString("MenuStyle"))) { WMPutInPLDictionary(style, WMCreatePLString("MenuStyle"), WMCreatePLString("normal")); } } static noreturn void print_help(int print_usage, int exitval) { printf("Usage: %s [OPTIONS] FILE\n", prog_name); if (print_usage) { puts("Reads style/theme configuration from FILE and updates Window Maker."); puts(""); puts(" --no-fonts ignore font related options"); puts(" --no-cursors ignore cursor related options"); puts(" --ignore