1 /*****************************************************************************
2  *   Copyright 2003 - 2010 Craig Drummond <craig.p.drummond@gmail.com>       *
3  *   Copyright 2013 - 2015 Yichao Yu <yyc1992@gmail.com>                     *
4  *                                                                           *
5  *   This program is free software; you can redistribute it and/or modify    *
6  *   it under the terms of the GNU Lesser General Public License as          *
7  *   published by the Free Software Foundation; either version 2.1 of the    *
8  *   License, or (at your option) version 3, or any later version accepted   *
9  *   by the membership of KDE e.V. (or its successor approved by the         *
10  *   membership of KDE e.V.), which shall act as a proxy defined in          *
11  *   Section 6 of version 3 of the license.                                  *
12  *                                                                           *
13  *   This program is distributed in the hope that it will be useful,         *
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       *
16  *   Lesser General Public License for more details.                         *
17  *                                                                           *
18  *   You should have received a copy of the GNU Lesser General Public        *
19  *   License along with this library. If not,                                *
20  *   see <http://www.gnu.org/licenses/>.                                     *
21  *****************************************************************************/
22 
23 #include "config.h"
24 
25 #include "qt_settings.h"
26 
27 #include <qtcurve-utils/color.h>
28 #include <qtcurve-utils/log.h>
29 #include <qtcurve-utils/dirs.h>
30 #include <qtcurve-utils/strs.h>
31 #include <qtcurve-utils/process.h>
32 
33 #include <common/config_file.h>
34 #include "helpers.h"
35 #include <dirent.h>
36 #include <locale.h>
37 #include <gmodule.h>
38 
39 namespace QtCurve {
40 
41 QtCPalette qtcPalette;
42 Options opts;
43 
44 #define MAX_APP_NAME_LEN 32
45 
46 #define KDE_CFG_DIR "/share/config/"
47 #define KDE4_SYS_CFG_DIR "/share/kde4/config/"
48 #define KDEGLOBALS_FILE "kdeglobals"
49 #define KDEGLOBALS_SYS_FILE "system.kdeglobals"
50 
51 #define qtc_gtkrc_printf(str_buff, args...)     \
52     gtk_rc_parse_string(str_buff.printf(args))
53 
54 static char*
getKdeHome()55 getKdeHome()
56 {
57     static uniqueStr dir = [] {
58         size_t len = 0;
59         const char *const args[] = {"kde4-config", "--localprefix", nullptr};
60         char *res = qtcPopenStdout("kde4-config", args, 300, &len);
61         if (res && res[strspn(res, " \t\b\n\f\v")]) {
62             if (res[len - 1] == '\n') {
63                 res[len - 1] = '\0';
64             }
65             return res;
66         }
67         if ((res = getenv(getuid() ? "KDEHOME" : "KDEROOTHOME"))) {
68             return strdup(res);
69         }
70         // according to kdecore/kernel/kstandarddirs.h, ~/.kde is the default for KDEHOME
71         // distributions using the default should not have to patch this code.
72         return Str::cat(getHome(), ".kde");
73     };
74     return dir.get();
75 }
76 
77 static const char*
kdeFile(const char * f)78 kdeFile(const char *f)
79 {
80     static Str::Buff<1024> buff;
81     return buff.cat(getKdeHome(), KDE_CFG_DIR, f);
82 }
83 
84 static const char*
kde4Globals()85 kde4Globals()
86 {
87     return kdeFile(KDEGLOBALS_FILE);
88 }
89 
90 static const char*
kde5Globals()91 kde5Globals()
92 {
93     static Str::Buff<1024> buff;
94     return buff.cat(getHome(), ".config/", KDEGLOBALS_FILE);;
95 }
96 
97 static const char*
kwinrc()98 kwinrc()
99 {
100     return kdeFile("kwinrc");
101 }
102 
103 #define HICOLOR_ICONS "hicolor"
104 #define HICOLOR_LEN 7
105 #define ICON_FOLDER "/share/icons/"
106 #define ICON_FOLDER_SLEN 13
107 #define DEFAULT_ICON_PREFIX "/usr/share/icons"
108 #define DEFAULT_ICON_PREFIX_LEN 16
109 
110 static GdkColor
setGdkColor(int r,int g,int b)111 setGdkColor(int r, int g, int b)
112 {
113     GdkColor col;
114 
115     col.red = toGtkColor(r);
116     col.green = toGtkColor(g);
117     col.blue = toGtkColor(b);
118     return col;
119 }
120 
121 #define DEFAULT_KDE_ACT_PAL                                           \
122     "active=#000000^e#dddfe4^e#ffffff^e#ffffff^e#555555^e#c7c7c7^e"   \
123     "#000000^e#ffffff^e#000000^e#ffffff^e#efefef^e#000000^e#678db2^e" \
124     "#ffffff^e#0000ee^e#52188b^e"
125 
126 #define DEFAULT_KDE_DIS_PAL                                           \
127     "disabled=#000000^e#dddfe4^e#ffffff^e#ffffff^e#555555^e#c7c7c7^e" \
128     "#c7c7c7^e#ffffff^e#000000^e#ffffff^e#efefef^e#000000^e#678db2^e" \
129     "#ffffff^e#0000ee^e#52188b^e"
130 
131 #ifdef READ_INACTIVE_PAL
132 #define DEFAULT_KDE_INACT_PAL                                         \
133     "inactive=#000000^e#dddfe4^e#ffffff^e#ffffff^e#555555^e#c7c7c7^e" \
134     "#000000^e#ffffff^e#000000^e#ffffff^e#efefef^e#000000^e#678db2^e" \
135     "#ffffff^e#0000ee^e#52188b^e"
136 #endif
137 
138 #define DEFAULT_KDE_FONT "Sans Serif"
139 #define DEFAULT_KDE_FONT_SIZE 10.0
140 #define MAX_LINE_LEN 1024
141 
142 QtData qtSettings;
143 
144 #define defaultIcons() ("oxygen")
145 
146 enum {
147     SECT_NONE = 0x000001,
148     SECT_PALETTE = 0x000002,
149     SECT_GENERAL = 0x000004,
150     SECT_KDE = 0x000008,
151     SECT_ICONS = 0x000010,
152     SECT_TOOLBAR_STYLE = 0x000020,
153     SECT_MAIN_TOOLBAR_ICONS = 0x000040,
154     SECT_SMALL_ICONS = 0x000080,
155 
156     SECT_KDE4_COL_BUTTON = 0x000100,
157     SECT_KDE4_COL_SEL = 0x000200,
158     SECT_KDE4_COL_TOOLTIP = 0x000400,
159     SECT_KDE4_COL_VIEW = 0x000800,
160     SECT_KDE4_COL_WINDOW = 0x001000,
161 
162     SECT_KDE4_EFFECT_DISABLED = 0x002000,
163     SECT_KDE4_EFFECT_INACTIVE = 0x004000,
164 
165     SECT_KDE4_COL_WM = 0x008000,
166 
167     SECT_KWIN_COMPOS = 0x010000
168 };
169 
170 #define ALL_KDE4_PAL_SETTINGS                                           \
171     (SECT_KDE4_COL_BUTTON | SECT_KDE4_COL_SEL | SECT_KDE4_COL_TOOLTIP | \
172      SECT_KDE4_COL_VIEW | SECT_KDE4_COL_WINDOW |                        \
173      SECT_KDE4_EFFECT_DISABLED | SECT_KDE4_EFFECT_INACTIVE | SECT_KDE4_COL_WM)
174 /*
175   Qt uses the following predefined weights:
176     Light    = 25,
177     Normal   = 50,
178     DemiBold = 63,
179     Bold     = 75,
180     Black    = 87
181 
182   ...need to categorize mid way, i.e. 0->37 = light, 38->56 = normal, etc...
183 */
184 
185 enum {
186     WEIGHT_NORMAL = 38, /* Less than this = light */
187     WEIGHT_DEMIBOLD = 57,
188     WEIGHT_BOLD = 69,
189     WEIGHT_BLACK = 81
190 };
191 
192 static const char*
weightStr(int w)193 weightStr(int w)
194 {
195     if (w < WEIGHT_NORMAL) {
196         return "light";
197     } else if (w < WEIGHT_DEMIBOLD) {
198         return "";
199     } else if (w < WEIGHT_BOLD) {
200         return "demibold";
201     } else if (w < WEIGHT_BLACK) {
202         return "bold";
203     } else {
204         return "black";
205     }
206 }
207 
208 static const char*
italicStr(int i)209 italicStr(int i)
210 {
211     return i ? "Italic" : "";
212 }
213 
214 enum {
215     RD_ACT_PALETTE = 0x000001,
216     RD_DIS_PALETTE = 0x000002,
217     RD_INACT_PALETTE = 0x000004,
218     RD_FONT = 0x000008,
219     RD_CONTRAST = 0x000010,
220     RD_ICONS = 0x000020,
221     RD_TOOLBAR_STYLE = 0x000040,
222     RD_TOOLBAR_ICON_SIZE = 0x000080,
223     RD_BUTTON_ICONS = 0x000100,
224     RD_SMALL_ICON_SIZE = 0x000200,
225     RD_LIST_COLOR = 0x000400,
226 #ifdef QTC_GTK2_STYLE_SUPPORT
227     RD_STYLE = 0x000800,
228 #else
229     RD_STYLE = 0x000000,
230 #endif
231     RD_LIST_SHADE = 0x001000,
232     RD_KDE4_PAL = 0x002000,
233 
234     RD_MENU_FONT = 0x004000,
235     RD_TB_FONT = 0x008000,
236 
237     RD_DRAG_DIST = 0x010000,
238     RD_DRAG_TIME = 0x020000
239 };
240 
241 #ifdef QTC_GTK2_STYLE_SUPPORT
242 static char*
themeFileSub(const char * prefix,const char * name,Str::Buff & str_buff,const char * sub)243 themeFileSub(const char *prefix, const char *name, Str::Buff &str_buff,
244              const char *sub)
245 {
246     if (isRegFile(str_buff.cat(prefix, "/", sub, "/", name, THEME_SUFFIX))) {
247         return str_buff.get();
248     }
249     return nullptr;
250 }
251 
252 static char*
themeFile(const char * prefix,const char * name,Str::Buff & str_buff)253 themeFile(const char *prefix, const char *name, Str::Buff &str_buff)
254 {
255     char *f = themeFileSub(prefix, name, str_buff, THEME_DIR);
256     if (!f) {
257         f = themeFileSub(prefix, name, str_buff, THEME_DIR4);
258     }
259     return f;
260 }
261 #endif
262 
263 typedef enum {
264     BackgroundAlternate,
265     BackgroundNormal,
266     DecorationFocus,
267     DecorationHover,
268     ForegroundNormal,
269 
270     UnknownColor
271 } ColorType;
272 
273 typedef enum  // Taken from "kcolorscheme.cpp"
274 {
275     // Effects
276     Intensity = 0,
277     Color = 1,
278     Contrast = 2,
279     // Intensity
280     IntensityNoEffect = 0,
281     IntensityShade = 1,
282     IntensityDarken = 2,
283     IntensityLighten = 3,
284     // Color
285     ColorNoEffect = 0,
286     ColorDesaturate = 1,
287     ColorFade = 2,
288     ColorTint = 3,
289     // Contrast
290     ContrastNoEffect = 0,
291     ContrastFade = 1,
292     ContrastTint = 2
293 } ColAdjustEffects;
294 
295 typedef struct
296 {
297     double           amount;
298     ColAdjustEffects effect;
299 } ColAdjust;
300 
301 typedef struct {
302     GdkColor  col;
303     ColAdjust intensity,
304               color,
305               contrast;
306     bool enabled;
307 } ColorEffect;
308 
309 typedef enum
310 {
311     EFF_DISABLED,
312     EFF_INACTIVE
313 } Effect;
314 
getColorType(const char * line)315 static ColorType getColorType(const char *line)
316 {
317     if(0==strncasecmp(line, "BackgroundAlternate=", 20))
318         return BackgroundAlternate;
319     if(0==strncasecmp(line, "BackgroundNormal=", 17))
320         return BackgroundNormal;
321     if(0==strncasecmp(line, "ForegroundNormal=", 17))
322         return ForegroundNormal;
323     if(0==strncasecmp(line, "DecorationFocus=", 16))
324         return DecorationFocus;
325     if(0==strncasecmp(line, "DecorationHover=", 16))
326         return DecorationHover;
327     return UnknownColor;
328 }
329 
readColor(const char * line)330 static GdkColor readColor(const char *line)
331 {
332     const char *eq = strchr(line, '=');
333     GdkColor col;
334     int red;
335     int green;
336     int blue;
337 
338     if (eq && ++eq && *eq != '\0' &&
339         sscanf(eq, "%d,%d,%d", &red, &green, &blue) == 3) {
340         col.red = toGtkColor(red);
341         col.green = toGtkColor(green);
342         col.blue = toGtkColor(blue);
343     } else {
344         col.red = col.blue = col.green = 0;
345     }
346     return col;
347 }
348 
readInt(const char * line,int offset)349 static int readInt(const char *line, int offset)
350 {
351     return line[offset]!='\0' ? atoi(&line[offset]) : 0;
352 }
353 
readDouble(const char * line,int offset)354 static double readDouble(const char *line, int offset)
355 {
356     return line[offset]!='\0' ? g_ascii_strtod(&line[offset], nullptr) : 0;
357 }
358 
359 static bool
readBool(const char * line,int offset)360 readBool(const char *line, int offset)
361 {
362     return line[offset]!='\0' ? 0==strncasecmp(&line[offset], "true", 4) : false;
363 }
364 
365 typedef struct
366 {
367     int   weight,
368           italic,
369           fixedW;
370     float size;
371     char  family[MAX_CONFIG_INPUT_LINE_LEN+1];
372 } QtFontDetails;
373 
initFont(QtFontDetails * f,bool setFamily)374 static void initFont(QtFontDetails *f, bool setFamily)
375 {
376     f->weight = WEIGHT_NORMAL,
377     f->italic = 0;
378     f->fixedW = 0;
379     f->size = DEFAULT_KDE_FONT_SIZE;
380     if (setFamily) {
381         strcpy(f->family, DEFAULT_KDE_FONT);
382     } else {
383         f->family[0] = '\0';
384     }
385 }
386 
387 static void
parseFontLine(const char * line,QtFontDetails * font)388 parseFontLine(const char *line, QtFontDetails *font)
389 {
390     int n = -1;
391     char *l;
392     char fontLine[MAX_CONFIG_INPUT_LINE_LEN+1];
393     QtFontDetails rc;
394 
395     initFont(&rc, false);
396     memcpy(fontLine, line, MAX_CONFIG_INPUT_LINE_LEN + 1);
397     l = strtok(fontLine, "=");
398 
399     while (l) {
400         switch (n) {
401         case 0: {
402             /* Family - and foundry(maybe!) (ignore X11 and XFT) */
403             if (char *dash = strchr(l, '-')) {
404                 *dash = '\0';
405                 l = ++dash;
406             }
407             strcpy(rc.family, l);
408             break;
409         }
410         case 1:  /* Point size */
411             sscanf(l, "%f", &rc.size);
412             break;
413         case 4:  /* Weight */
414             sscanf(l, "%d", &rc.weight);
415             break;
416         case 5:  /* Slant */
417             sscanf(l, "%d", &rc.italic);
418             break;
419         case 8:  /* Spacing */
420             sscanf(l, "%d", &rc.fixedW);
421             break;
422         default:
423             break;
424         }
425 
426         n++;
427         if (n>8 && font->family[0]) {
428             font->weight = rc.weight;
429             font->italic = rc.italic;
430             font->fixedW = rc.fixedW;
431             font->size = rc.size;
432             strcpy(font->family, rc.family);
433             break;
434         }
435         l = strtok(nullptr, ",");
436     }
437 }
438 
439 static void
setFont(QtFontDetails * font,int f)440 setFont(QtFontDetails *font, int f)
441 {
442     if (qtSettings.fonts[f]) {
443         free(qtSettings.fonts[f]);
444         qtSettings.fonts[f] = nullptr;
445     }
446     if (f == FONT_GENERAL && qtSettings.fonts[FONT_BOLD]) {
447         free(qtSettings.fonts[FONT_BOLD]);
448         qtSettings.fonts[FONT_BOLD] = nullptr;
449     }
450 
451     qtSettings.fonts[f] = (char*)malloc(strlen(font->family) + 1 +
452                                         strlen(weightStr(font->weight)) + 1 +
453                                         strlen(italicStr(font->italic)) + 1 +
454                                         20 /* point size */ + 1);
455 
456     sprintf(qtSettings.fonts[f], "%s %s %s %f", font->family,
457             weightStr(font->weight), italicStr(font->italic), font->size);
458 
459     /* Qt uses a bold font for progressbars, try to mimic this... */
460     if (f == FONT_GENERAL && font->weight >= WEIGHT_NORMAL &&
461         font->weight < WEIGHT_DEMIBOLD) {
462         qtSettings.fonts[FONT_BOLD] =
463             (char*)malloc(strlen(font->family) + 1 +
464                           strlen(weightStr(WEIGHT_BOLD)) + 1 +
465                           strlen(italicStr(font->italic)) + 1 +
466                           20 /* point size */ + 1);
467 
468         sprintf(qtSettings.fonts[FONT_BOLD], "%s %s %s %f", font->family,
469                 weightStr(WEIGHT_BOLD), italicStr(font->italic), font->size);
470     }
471     if (qtSettings.debug) {
472         fprintf(stderr, DEBUG_PREFIX"Font[%d] - %s\n", f, qtSettings.fonts[f]);
473     }
474 }
475 
476 #define MIX(a, b, bias) (a + ((b - a) * bias))
mixColors(const GdkColor * c1,const GdkColor * c2,double bias)477 GdkColor mixColors(const GdkColor *c1, const GdkColor *c2, double bias)
478 {
479     if (bias <= 0.0 || std::isnan(bias))
480         return *c1;
481     if (bias >= 1.0)
482         return *c2;
483 
484     double r1 = c1->red / 65535.0;
485     double g1 = c1->green / 65535.0;
486     double b1 = c1->blue / 65535.0;
487     double r2 = c2->red / 65535.0;
488     double g2 = c2->green / 65535.0;
489     double b2 = c2->blue / 65535.0;
490     GdkColor col;
491     col.red = int(65535.0 * MIX(r1, r2, bias));
492     col.green = int(65535.0 * MIX(g1, g2, bias));
493     col.blue = int(65535.0 * MIX(b1, b2, bias));
494     return col;
495 }
496 
readKwinrc()497 static void readKwinrc()
498 {
499     if (FILE *f = fopen(kwinrc(), "r")) {
500         int  section = SECT_NONE;
501         char line[MAX_CONFIG_INPUT_LINE_LEN + 1];
502 
503         if (qtSettings.debug)
504             fprintf(stderr, DEBUG_PREFIX "Reading kwinrc\n");
505 
506         while(nullptr!=fgets(line, MAX_CONFIG_INPUT_LINE_LEN, f))
507             if(line[0]=='[')
508             {
509                 if(0==strncasecmp(line, "[Compositing]", 13))
510                     section=SECT_KWIN_COMPOS;
511                 else
512                     section=SECT_NONE;
513             }
514             else if (SECT_KWIN_COMPOS==section && 0==strncasecmp(line, "Backend=", 8))
515             {
516                 if (strstr(line, "=XRender"))
517                     opts.square|=SQUARE_POPUP_MENUS|SQUARE_TOOLTIPS;
518                 break;
519             }
520         fclose(f);
521     }
522 }
523 
readKdeGlobals(const char * rc,int rd,bool first)524 static void readKdeGlobals(const char *rc, int rd, bool first)
525 {
526     ColorEffect   effects[2];
527     int found = 0;
528     int colorsFound = 0;
529     char          line[MAX_CONFIG_INPUT_LINE_LEN+1];
530     FILE          *f=fopen(rc, "r");
531     QtFontDetails fonts[FONT_NUM_STD];
532 
533     for (int i = 0;i < FONT_NUM_STD;++i) {
534         initFont(&fonts[i], true);
535     }
536 
537     if(first)
538     {
539         // Set defaults!
540         effects[EFF_DISABLED].col.red=112;
541         effects[EFF_DISABLED].col.green=111;
542         effects[EFF_DISABLED].col.blue=110;
543         effects[EFF_DISABLED].color.amount=0.0;
544         effects[EFF_DISABLED].color.effect=ColorNoEffect;
545         effects[EFF_DISABLED].contrast.amount=0.65;
546         effects[EFF_DISABLED].contrast.effect=ContrastFade;
547         effects[EFF_DISABLED].intensity.amount=0.1;
548         effects[EFF_DISABLED].intensity.effect=IntensityDarken;
549         effects[EFF_DISABLED].enabled=true;
550         effects[EFF_INACTIVE].col.red=112;
551         effects[EFF_INACTIVE].col.green=111;
552         effects[EFF_INACTIVE].col.blue=110;
553         effects[EFF_INACTIVE].color.amount=0.0;
554         effects[EFF_INACTIVE].color.effect=ColorNoEffect;
555         effects[EFF_INACTIVE].contrast.amount=0.0;
556         effects[EFF_INACTIVE].contrast.effect=ContrastNoEffect;
557         effects[EFF_INACTIVE].intensity.amount=0.0;
558         effects[EFF_INACTIVE].intensity.effect=IntensityNoEffect;
559         effects[EFF_INACTIVE].enabled=false;
560 
561         qtSettings.colors[PAL_ACTIVE][COLOR_BUTTON]=setGdkColor(232, 231, 230);
562         qtSettings.colors[PAL_ACTIVE][COLOR_BUTTON_TEXT]=setGdkColor(20, 19, 18);
563         qtSettings.colors[PAL_ACTIVE][COLOR_SELECTED]=setGdkColor(65, 139, 212);
564         qtSettings.colors[PAL_ACTIVE][COLOR_TEXT_SELECTED]=setGdkColor(255, 255, 255);
565         qtSettings.colors[PAL_ACTIVE][COLOR_TOOLTIP]=setGdkColor(192, 218, 255);
566         qtSettings.colors[PAL_ACTIVE][COLOR_TOOLTIP_TEXT]=setGdkColor(20, 19, 18);
567         qtSettings.colors[PAL_ACTIVE][COLOR_BACKGROUND]=setGdkColor(255, 255, 255);
568         qtSettings.colors[PAL_ACTIVE][COLOR_TEXT]=setGdkColor(20, 19, 18);
569         qtSettings.colors[PAL_ACTIVE][COLOR_LV]=setGdkColor(248, 247, 246);
570         qtSettings.colors[PAL_ACTIVE][COLOR_WINDOW]=setGdkColor(233, 232, 232);
571         qtSettings.colors[PAL_ACTIVE][COLOR_WINDOW_TEXT]=setGdkColor(20, 19, 18);
572         qtSettings.colors[PAL_ACTIVE][COLOR_WINDOW_BORDER]=qtSettings.colors[PAL_ACTIVE][COLOR_WINDOW];
573         qtSettings.colors[PAL_INACTIVE][COLOR_WINDOW_BORDER]=qtSettings.colors[PAL_ACTIVE][COLOR_WINDOW];
574         qtSettings.colors[PAL_ACTIVE][COLOR_WINDOW_BORDER_TEXT]=qtSettings.colors[PAL_ACTIVE][COLOR_WINDOW_TEXT];
575         qtSettings.colors[PAL_INACTIVE][COLOR_WINDOW_BORDER_TEXT]=qtSettings.colors[PAL_ACTIVE][COLOR_WINDOW_TEXT];
576 
577         qtSettings.colors[PAL_ACTIVE][COLOR_FOCUS]=setGdkColor( 43, 116, 199);
578         qtSettings.colors[PAL_ACTIVE][COLOR_HOVER]=setGdkColor(119, 183, 255);
579     }
580 
581     if(f)
582     {
583         int section=SECT_NONE;
584 
585         if(qtSettings.debug)
586             fprintf(stderr, DEBUG_PREFIX"Reading kdeglobals - %s\n", rc);
587 
588         while(found!=rd && nullptr!=fgets(line, MAX_CONFIG_INPUT_LINE_LEN, f))
589             if(line[0]=='[')
590             {
591                 if(0==strncasecmp(line, "[Icons]", 7))
592                     section=SECT_ICONS;
593                 else if(0==strncasecmp(line, "[Toolbar style]", 15))
594                     section=SECT_TOOLBAR_STYLE;
595                 else if(0==strncasecmp(line, "[MainToolbarIcons]", 18))
596                     section=SECT_MAIN_TOOLBAR_ICONS;
597                 else if(0==strncasecmp(line, "[SmallIcons]", 12))
598                     section=SECT_SMALL_ICONS;
599                 else if(0==strncasecmp(line, "[Colors:View]", 13))
600                     section=SECT_KDE4_COL_VIEW;
601                 else if(0==strncasecmp(line, "[Colors:Button]", 15))
602                     section=SECT_KDE4_COL_BUTTON;
603                 else if(0==strncasecmp(line, "[Colors:Selection]", 18))
604                     section=SECT_KDE4_COL_SEL;
605                 else if(0==strncasecmp(line, "[Colors:Tooltip]", 16))
606                     section=SECT_KDE4_COL_TOOLTIP;
607                 else if(0==strncasecmp(line, "[Colors:Window]", 15))
608                     section=SECT_KDE4_COL_WINDOW;
609                 else if(0==strncasecmp(line, "[ColorEffects:Disabled]", 23))
610                     section=SECT_KDE4_EFFECT_DISABLED;
611                 else if(0==strncasecmp(line, "[ColorEffects:Inactive]", 23))
612                     section=SECT_KDE4_EFFECT_INACTIVE;
613                 else if(0==strncasecmp(line, "[General]", 9))
614                     section=SECT_GENERAL;
615                 else if(0==strncasecmp(line, "[KDE]", 5))
616                     section=SECT_KDE;
617                 else if(0==strncasecmp(line, "[WM]", 4))
618                     section=SECT_KDE4_COL_WM;
619                 else
620                 {
621                     section=SECT_NONE;
622                     if(colorsFound==ALL_KDE4_PAL_SETTINGS)
623                         found|=RD_KDE4_PAL;
624                     if(found==rd)
625                         break;
626                 }
627             }
628             else if (SECT_ICONS==section && rd&RD_ICONS && !(found&RD_ICONS) &&
629                      0==strncasecmp(line, "Theme=", 6)) {
630                 char *eq = strstr(line, "=");
631 
632                 if(eq && ++eq) {
633                     unsigned int len = strlen(eq);
634 
635                     qtSettings.icons = (char*)realloc(qtSettings.icons,
636                                                       len + 1);
637                     strcpy(qtSettings.icons, eq);
638                     if('\n'==qtSettings.icons[len-1])
639                         qtSettings.icons[len-1]='\0';
640                 }
641                 found|=RD_ICONS;
642             }
643             else if (SECT_SMALL_ICONS==section && rd&RD_SMALL_ICON_SIZE && !(found&RD_SMALL_ICON_SIZE) &&
644                      0==strncasecmp(line, "Size=", 5))
645             {
646                 int size=readInt(line, 5);
647 
648                 if(0!=size)
649                 {
650                     qtSettings.iconSizes.smlTbSize=size;
651                     qtSettings.iconSizes.btnSize=size;
652                     qtSettings.iconSizes.mnuSize=size;
653                     found|=RD_SMALL_ICON_SIZE;
654                 }
655             }
656             else if (SECT_TOOLBAR_STYLE==section && rd&RD_TOOLBAR_STYLE &&
657                      !(found&RD_TOOLBAR_STYLE) &&
658                      0==strncasecmp(line, "ToolButtonStyle=", 16)) {
659                 char *eq = strstr(line, "=");
660 
661                 if(eq && ++eq)
662                 {
663                     if(0==strncasecmp(eq, "IconOnly", 8))
664                         qtSettings.toolbarStyle=GTK_TOOLBAR_ICONS;
665                     else if(0==strncasecmp(eq, "TextOnly", 8))
666                         qtSettings.toolbarStyle=GTK_TOOLBAR_TEXT;
667                     else if (0==strncasecmp(eq, "TextBesideIcon", 14))
668                         qtSettings.toolbarStyle=GTK_TOOLBAR_BOTH_HORIZ;
669                     else if (0==strncasecmp(eq, "TextUnderIcon", 13))
670                         qtSettings.toolbarStyle=GTK_TOOLBAR_BOTH;
671                     found|=RD_TOOLBAR_STYLE;
672                 }
673             }
674             else if (SECT_MAIN_TOOLBAR_ICONS==section && rd&RD_TOOLBAR_ICON_SIZE &&
675                         !(found&RD_TOOLBAR_ICON_SIZE) && 0==strncasecmp(line, "Size=", 5))
676             {
677                 qtSettings.iconSizes.tbSize = readInt(line, 5);
678                 found|=RD_TOOLBAR_ICON_SIZE;
679             }
680             else if (SECT_KDE==section && rd&RD_BUTTON_ICONS && !(found&RD_BUTTON_ICONS) &&
681                         0==strncasecmp(line, "ShowIconsOnPushButtons=", 23))
682             {
683                 qtSettings.buttonIcons=readBool(line, 23);
684                 found|=RD_BUTTON_ICONS;
685             }
686 //             else if (SECT_KDE==section && rd&RD_DRAG_DIST && !(found&RD_DRAG_DIST) &&
687 //                         0==strncasecmp(line, "StartDragDist=", 14))
688 //             {
689 //                 qtSettings.startDragDist=readInt(line, 14);
690 //                 found|=RD_DRAG_DIST;
691 //             }
692             else if (SECT_KDE==section && rd&RD_DRAG_TIME && !(found&RD_DRAG_TIME) &&
693                         0==strncasecmp(line, "StartDragTime=", 14))
694             {
695                 qtSettings.startDragTime=readInt(line, 14);
696                 found|=RD_DRAG_TIME;
697             }
698             else if (SECT_KDE4_COL_WM==section && rd&RD_KDE4_PAL &&
699                      !(found&RD_KDE4_PAL)) {
700                 colorsFound|=section;
701                 if(0==strncasecmp(line, "activeBackground=", 17))
702                     qtSettings.colors[PAL_ACTIVE][COLOR_WINDOW_BORDER]=readColor(line);
703                 else if(0==strncasecmp(line, "activeForeground=", 17))
704                     qtSettings.colors[PAL_ACTIVE][COLOR_WINDOW_BORDER_TEXT]=readColor(line);
705                 else if(0==strncasecmp(line, "inactiveBackground=", 19))
706                     qtSettings.colors[PAL_INACTIVE][COLOR_WINDOW_BORDER]=readColor(line);
707                 else if(0==strncasecmp(line, "inactiveForeground=", 19))
708                     qtSettings.colors[PAL_INACTIVE][COLOR_WINDOW_BORDER_TEXT]=readColor(line);
709             } else if (section>=SECT_KDE4_COL_BUTTON &&
710                        section<=SECT_KDE4_COL_WINDOW &&
711                        rd&RD_KDE4_PAL && !(found&RD_KDE4_PAL)) {
712                 ColorType colorType=getColorType(line);
713 
714                 colorsFound|=section;
715                 if(UnknownColor!=colorType)
716                 {
717                     GdkColor color=readColor(line);
718 
719                     switch(section)
720                     {
721                         case SECT_KDE4_COL_BUTTON:
722                             switch(colorType) {
723                             case BackgroundNormal:
724                                 qtSettings.colors[PAL_ACTIVE][COLOR_BUTTON]=color;
725                                 break;
726                             case ForegroundNormal:
727                                 qtSettings.colors[PAL_ACTIVE][COLOR_BUTTON_TEXT]=color;
728                                 break;
729                             case DecorationFocus:
730                                 qtSettings.colors[PAL_ACTIVE][COLOR_FOCUS]=color;
731                                 break;
732                             case DecorationHover:
733                                 qtSettings.colors[PAL_ACTIVE][COLOR_HOVER]=color;
734                                 break;
735                             default:
736                                 break;
737                             }
738                             break;
739                         case SECT_KDE4_COL_SEL:
740                             if(BackgroundNormal==colorType)
741                                 qtSettings.colors[PAL_ACTIVE][COLOR_SELECTED]=color;
742                             else if(ForegroundNormal==colorType)
743                                 qtSettings.colors[PAL_ACTIVE][COLOR_TEXT_SELECTED]=color;
744                             break;
745                         case SECT_KDE4_COL_TOOLTIP:
746                             if(BackgroundNormal==colorType)
747                                 qtSettings.colors[PAL_ACTIVE][COLOR_TOOLTIP]=color;
748                             else if(ForegroundNormal==colorType)
749                                 qtSettings.colors[PAL_ACTIVE][COLOR_TOOLTIP_TEXT]=color;
750                             break;
751                         case SECT_KDE4_COL_VIEW:
752                             if(BackgroundNormal==colorType)
753                                 qtSettings.colors[PAL_ACTIVE][COLOR_BACKGROUND]=color;
754                             else if(ForegroundNormal==colorType)
755                                 qtSettings.colors[PAL_ACTIVE][COLOR_TEXT]=color;
756                             else if(BackgroundAlternate==colorType)
757                                 qtSettings.colors[PAL_ACTIVE][COLOR_LV]=color;
758                             break;
759                         case SECT_KDE4_COL_WINDOW:
760                             if(BackgroundNormal==colorType)
761                                 qtSettings.colors[PAL_ACTIVE][COLOR_WINDOW]=color;
762                             else if(ForegroundNormal==colorType)
763                                 qtSettings.colors[PAL_ACTIVE][COLOR_WINDOW_TEXT]=color;
764                             break;
765                         default:
766                             break;
767                     }
768                 }
769             } else if (SECT_GENERAL==section && rd&RD_FONT && !(found&RD_FONT) &&
770                        0==strncasecmp(line, "font=", 5)) {
771                 parseFontLine(line, &fonts[FONT_GENERAL]);
772                 found|=RD_FONT;
773             }
774             else if (SECT_GENERAL==section && rd&RD_MENU_FONT && !(found&RD_MENU_FONT) &&
775                      0==strncasecmp(line, "menuFont=", 9))
776             {
777                 parseFontLine(line, &fonts[FONT_MENU]);
778                 found|=RD_MENU_FONT;
779             }
780             else if (SECT_GENERAL==section && rd&RD_TB_FONT && !(found&RD_TB_FONT) &&
781                      0==strncasecmp(line, "toolBarFont=", 12))
782             {
783                 parseFontLine(line, &fonts[FONT_TOOLBAR]);
784                 found|=RD_TB_FONT;
785             } else if (rd&RD_CONTRAST && !(found&RD_CONTRAST) &&
786                        SECT_KDE==section && 0==strncasecmp(line, "contrast=", 9)) {
787                 opts.contrast=readInt(line, 9);
788                 if(opts.contrast>10 || opts.contrast<0)
789                     opts.contrast=DEFAULT_CONTRAST;
790                 found|=RD_CONTRAST;
791             }
792 #ifdef QTC_GTK2_STYLE_SUPPORT
793             else if(SECT_GENERAL==section && rd&RD_STYLE && !(found&RD_STYLE) &&
794                     0==strncasecmp(line, "widgetStyle=", 12)) {
795                 int len=strlen(line);
796                 qtSettings.styleName=realloc(qtSettings.styleName, strlen(&line[12])+1);
797                 if('\n'==line[len-1])
798                     line[len-1]='\0';
799                 strcpy(qtSettings.styleName, &line[12]);
800                 found|=RD_STYLE;
801             }
802 #endif
803             else if((SECT_KDE4_EFFECT_DISABLED==section ||
804                      SECT_KDE4_EFFECT_INACTIVE==section) &&
805                     rd&RD_KDE4_PAL && !(found&RD_KDE4_PAL)) {
806                 colorsFound|=section;
807                 Effect eff=SECT_KDE4_EFFECT_DISABLED==section ? EFF_DISABLED : EFF_INACTIVE;
808                 if(0==strncasecmp(line, "Color=", 6))
809                     effects[eff].col=readColor(line);
810                 else if(0==strncasecmp(line, "ColorAmount=", 12))
811                     effects[eff].color.amount=readDouble(line, 12);
812                 else if(0==strncasecmp(line, "ColorEffect=", 12))
813                     effects[eff].color.effect =
814                         (ColAdjustEffects)readInt(line, 12);
815                 else if(0==strncasecmp(line, "ContrastAmount=", 15))
816                     effects[eff].contrast.amount=readDouble(line, 15);
817                 else if(0==strncasecmp(line, "ContrastEffect=", 15))
818                     effects[eff].contrast.effect =
819                         (ColAdjustEffects)readInt(line, 15);
820                 else if(0==strncasecmp(line, "IntensityAmount=", 16))
821                     effects[eff].intensity.amount=readDouble(line, 16);
822                 else if(0==strncasecmp(line, "IntensityEffect=", 16))
823                     effects[eff].intensity.effect =
824                         (ColAdjustEffects)readInt(line, 16);
825                 else if(0==strncasecmp(line, "Enable=", 7))
826                     effects[eff].enabled=readBool(line, 7);
827                 else if(0==strncasecmp(line, "ChangeSelectionColor=", 21))
828                     qtSettings.inactiveChangeSelectionColor=readBool(line, 21);
829             }
830             else if(SECT_GENERAL==section && rd&RD_LIST_SHADE && !(found&RD_LIST_SHADE) &&
831                     0==strncasecmp(line, "shadeSortColumn=", 16))
832             {
833                 qtSettings.shadeSortedList=readBool(line, 16);
834                 found|=RD_LIST_SHADE;
835             }
836             else if(found==rd)
837                 break;
838 
839         fclose(f);
840     }
841     else if (!first)
842     {
843         // don't repeat the settings below, as that would probably override settings read from file.
844         return;
845     }
846 
847     int eff = 0;
848     double contrast = 0.1 * opts.contrast;
849     double y;
850 
851     contrast = (1.0 > contrast ? (-1.0 < contrast ? contrast : -1.0) : 1.0);
852     y = qtcColorLuma(&qtSettings.colors[PAL_ACTIVE][COLOR_WINDOW]);
853 
854     if(y<0.006)
855         qtSettings.colors[PAL_ACTIVE][COLOR_MID]=qtcColorShade(&qtSettings.colors[PAL_ACTIVE][COLOR_WINDOW], 0.01 + 0.20 * contrast, 0.0);
856     else if(y>0.93)
857         qtSettings.colors[PAL_ACTIVE][COLOR_MID]=qtcColorShade(&qtSettings.colors[PAL_ACTIVE][COLOR_WINDOW], -0.02 - 0.20 * contrast, 0.0);
858     else {
859         double darkAmount =  (-y) * (0.55 + contrast * 0.35);
860 
861         qtSettings.colors[PAL_ACTIVE][COLOR_MID]=qtcColorShade(&qtSettings.colors[PAL_ACTIVE][COLOR_WINDOW], (0.35 + 0.15 * y) * darkAmount, 0.0);
862     }
863 
864     for (eff=0; eff<2; ++eff) {
865         int p=0==eff ? PAL_DISABLED : PAL_INACTIVE;
866         memcpy(qtSettings.colors[p], qtSettings.colors[PAL_ACTIVE], sizeof(GdkColor) * COLOR_NUMCOLORS_STD);
867         if(effects[eff].enabled) {
868             int col;
869             for(col=0; col<COLOR_NUMCOLORS_STD; ++col) {
870                 switch(effects[eff].intensity.effect) {
871                 case IntensityShade:
872                     qtSettings.colors[p][col] = qtcColorShade(&qtSettings.colors[p][col], effects[eff].intensity.amount, 0.0);
873                     break;
874                 case IntensityDarken:
875                     qtSettings.colors[p][col] = qtcColorDarken(&qtSettings.colors[p][col], effects[eff].intensity.amount, 1.0);
876                     break;
877                 case IntensityLighten:
878                     qtSettings.colors[p][col] =
879                         qtcColorLighten(
880                             &qtSettings.colors[p][col],
881                             effects[eff].intensity.amount, 1.0);
882                 default:
883                     break;
884                 }
885                 switch (effects[eff].color.effect) {
886                 case ColorDesaturate:
887                     qtSettings.colors[p][col] = qtcColorDarken(&qtSettings.colors[p][col], 0.0, 1.0 - effects[eff].color.amount);
888                     break;
889                 case ColorFade:
890                     qtSettings.colors[p][col] = qtcColorMix(&qtSettings.colors[p][col], &effects[eff].col, effects[eff].color.amount);
891                     break;
892                 case ColorTint:
893                     qtSettings.colors[p][col] = qtcColorTint(&qtSettings.colors[p][col], &effects[eff].col, effects[eff].color.amount);
894                 default:
895                     break;
896                 }
897 
898                 if (COLOR_BUTTON_TEXT==col || COLOR_TEXT==col ||
899                     COLOR_WINDOW_TEXT==col || COLOR_TOOLTIP_TEXT==col) {
900                     int other = (COLOR_BUTTON_TEXT==col ? COLOR_BUTTON :
901                                  COLOR_WINDOW_TEXT==col ? COLOR_WINDOW :
902                                  COLOR_TEXT==col ? COLOR_BACKGROUND :
903                                  COLOR_TOOLTIP);
904 
905                     switch (effects[eff].contrast.effect) {
906                     case ContrastFade:
907                         qtSettings.colors[p][col]=qtcColorMix(&qtSettings.colors[p][col],
908                                                               &qtSettings.colors[PAL_DISABLED][other],
909                                                               effects[eff].contrast.amount);
910                         break;
911                     case ContrastTint:
912                         qtSettings.colors[p][col]=qtcColorTint(&qtSettings.colors[p][col],
913                                                                &qtSettings.colors[PAL_DISABLED][other],
914                                                                effects[eff].contrast.amount);
915                     default:
916                         break;
917                     }
918                 }
919             }
920         }
921     }
922 
923     qtSettings.colors[PAL_INACTIVE][COLOR_SELECTED]=qtSettings.colors[PAL_ACTIVE][COLOR_SELECTED];
924 #if 0 // Use alpha values instead...
925     if(qtSettings.inactiveChangeSelectionColor)
926         if(effects[PAL_INACTIVE].enabled)
927             qtSettings.colors[PAL_INACTIVE][COLOR_SELECTED]=qtcColorTint(&qtSettings.colors[PAL_INACTIVE][COLOR_WINDOW],
928                                                                          &qtSettings.colors[PAL_ACTIVE][COLOR_SELECTED],
929                                                                          0.4);
930         else
931             qtSettings.inactiveChangeSelectionColor=false;
932 #endif
933 
934     if(rd&RD_ICONS && !qtSettings.icons)
935     {
936         qtSettings.icons=(char *)realloc(qtSettings.icons, strlen(defaultIcons())+1);
937         strcpy(qtSettings.icons, defaultIcons());
938     }
939     if(rd&RD_TOOLBAR_STYLE && !(found&RD_TOOLBAR_STYLE))
940         qtSettings.toolbarStyle=GTK_TOOLBAR_ICONS;
941     if(rd&RD_BUTTON_ICONS && !(found&RD_BUTTON_ICONS))
942         qtSettings.buttonIcons=true;
943     if(rd&RD_LIST_SHADE && !(found&RD_LIST_SHADE))
944         qtSettings.shadeSortedList=true;
945     //if(rd&RD_FONT && (found&RD_FONT || (!qtSettings.fonts[FONT_GENERAL] && kde4)))  /* No need to check if read in */
946     if(rd&RD_FONT && found&RD_FONT)
947         setFont(&fonts[FONT_GENERAL], FONT_GENERAL);
948     if(rd&RD_MENU_FONT && found&RD_MENU_FONT)
949         setFont(&fonts[FONT_MENU], FONT_MENU);
950     if(rd&RD_TB_FONT && found&RD_TB_FONT)
951         setFont(&fonts[FONT_TOOLBAR], FONT_TOOLBAR);
952 }
953 
954 static int qt_refs = 0;
955 
956 static const char*
kdeIconsPrefix()957 kdeIconsPrefix()
958 {
959     static uniqueStr dir = [] {
960         size_t len = 0;
961         const char *const args[] = {"kde4-config", "--install", "icon",
962                                     nullptr};
963         char *res = qtcPopenStdout("kde4-config", args, 300, &len);
964         if (res && res[strspn(res, " \t\b\n\f\v")]) {
965             if (res[len - 1]=='\n') {
966                 res[len - 1]='\0';
967             }
968             return res;
969         }
970         return strdup(QTC_KDE4_ICONS_PREFIX &&
971                       strlen(QTC_KDE4_ICONS_PREFIX) > 2 ?
972                       QTC_KDE4_ICONS_PREFIX : DEFAULT_ICON_PREFIX);
973     };
974     return dir.get();
975 }
976 
977 static char*
getIconPath()978 getIconPath()
979 {
980     static Str::Buff<1024> buff;
981 
982     const char *kdeHome = getKdeHome();
983     const char *kdePrefix = kdeIconsPrefix();
984     const char *defIcons = defaultIcons();
985     bool nonDefIcons = qtSettings.icons && strcmp(qtSettings.icons, defIcons);
986     bool addDefaultPrefix = strcmp(kdePrefix, DEFAULT_ICON_PREFIX);
987 
988     buff.cat("pixmap_path \"");
989     if (nonDefIcons) {
990         buff.append(kdeHome, ICON_FOLDER, qtSettings.icons, ":",
991                     kdePrefix, "/", qtSettings.icons, ":");
992         if (addDefaultPrefix) {
993             buff.append(DEFAULT_ICON_PREFIX, "/", qtSettings.icons, ":");
994         }
995     }
996     buff.append(kdeHome, ICON_FOLDER, defIcons, ":",
997                 kdePrefix, "/", defIcons, ":");
998     if (addDefaultPrefix) {
999         buff.append(DEFAULT_ICON_PREFIX, "/", defIcons, ":");
1000     }
1001     buff.append(kdeHome, ICON_FOLDER, HICOLOR_ICONS, ":",
1002                 kdePrefix, "/", HICOLOR_ICONS, ":");
1003     if (addDefaultPrefix) {
1004         buff.append(DEFAULT_ICON_PREFIX, "/", HICOLOR_ICONS);
1005     } else {
1006         auto len = strlen(buff.get());
1007         if (buff[len] == ':') {
1008             buff[len] = 0;
1009         }
1010     }
1011     buff.append("\"");
1012     if (qtSettings.debug) {
1013         fprintf(stderr, DEBUG_PREFIX "%s\n", buff.get());
1014     }
1015     return buff.get();
1016 }
1017 
1018 static bool
checkFileVersion(const char * fname,const char * versionStr,int versionStrLen)1019 checkFileVersion(const char *fname, const char *versionStr, int versionStrLen)
1020 {
1021     FILE *f = fopen(fname, "r");
1022     bool diff = true;
1023 
1024     if (f) {
1025         if (access(fname, W_OK) != 0) {
1026             /* If file is not writeable, then just pretend no difference */
1027             diff = false;
1028         } else {
1029             static const int constVLen = 32;
1030             char line[constVLen + 1];
1031             int numChars = qtcMin(constVLen, versionStrLen - 1);
1032             diff = (fgets(line, numChars + 1, f) == nullptr ||
1033                     memcmp(versionStr, line, numChars));
1034         }
1035         fclose(f);
1036     }
1037     return !diff;
1038 }
1039 
1040 static bool
isMozApp(const char * app,const char * check)1041 isMozApp(const char *app, const char *check)
1042 {
1043     if (strcmp(app, check) == 0) {
1044         return true;
1045     } else if (Str::startsWith(app, check)) {
1046         int app_len=strlen(app),
1047             check_len=strlen(check);
1048 
1049         if(check_len+4 == app_len && 0==strcmp(&app[check_len], "-bin"))
1050             return true;
1051 
1052         /* OK check for xulrunner-1.9 */
1053         {
1054         float dummy;
1055         if(app_len>(check_len+1) && 1==sscanf(&app[check_len+1], "%f", &dummy))
1056             return true;
1057         }
1058     }
1059 
1060     return false;
1061 }
1062 
1063 static bool
excludedApp(Strings config)1064 excludedApp(Strings config)
1065 {
1066     if (qtSettings.appName && config) {
1067         for (int i = 0;config[i];++i) {
1068             if (strcmp("gtk", config[i]) == 0 ||
1069                 strcmp(qtSettings.appName, config[i]) == 0) {
1070                 return true;
1071             }
1072         }
1073     }
1074     return false;
1075 }
1076 
1077 static QtcDebug
debugLevel()1078 debugLevel()
1079 {
1080     if (const char *dbg = getenv("QTCURVE_DEBUG")) {
1081         switch (atoi(dbg)) {
1082         case 1:
1083             return DEBUG_SETTINGS;
1084         case 2:
1085             return DEBUG_ALL;
1086         default:
1087             return DEBUG_NONE;
1088         }
1089     }
1090     return DEBUG_NONE;
1091 }
1092 
1093 bool
qtSettingsInit()1094 qtSettingsInit()
1095 {
1096     if (0 == qt_refs++) {
1097         static int lastRead = 0;
1098         int now = time(nullptr);
1099         qtSettings.app = GTK_APP_UNKNOWN;
1100         if (abs(now - lastRead) > 1) {
1101             char *locale = setlocale(LC_NUMERIC, nullptr);
1102             char *path = nullptr;
1103             Str::Buff<4096> str_buff;
1104             char *tmpStr = nullptr;
1105             GtkSettings *settings=nullptr;
1106 
1107             setlocale(LC_NUMERIC, "C");
1108             qtSettings.icons=nullptr;
1109             memset(qtSettings.fonts, 0, sizeof(char *)*FONT_NUM_TOTAL);
1110             qtSettings.iconSizes.smlTbSize=16;
1111             qtSettings.iconSizes.tbSize=22;
1112             qtSettings.iconSizes.dndSize=32;
1113             qtSettings.iconSizes.btnSize=16;
1114             qtSettings.iconSizes.mnuSize=16;
1115             qtSettings.iconSizes.dlgSize=32;
1116             qtSettings.colors[PAL_ACTIVE][COLOR_LV]=setGdkColor(0, 0, 0);
1117             qtSettings.colors[PAL_ACTIVE][COLOR_TOOLTIP_TEXT]=setGdkColor(0, 0, 0);
1118             qtSettings.colors[PAL_ACTIVE][COLOR_TOOLTIP]=setGdkColor(0xFF, 0xFF, 192);
1119 #ifdef QTC_GTK2_STYLE_SUPPORT
1120             qtSettings.styleName=nullptr;
1121 #endif
1122             qtSettings.inactiveChangeSelectionColor=false;
1123             qtSettings.appName=nullptr;
1124             /* qtSettings.startDragDist=4; */
1125             qtSettings.startDragTime=500;
1126             qtSettings.debug=debugLevel();
1127             opts.contrast=DEFAULT_CONTRAST;
1128             for (int i = 0;i < FONT_NUM_TOTAL;++i) {
1129                 qtSettings.fonts[i] = nullptr;
1130             }
1131 
1132             qtSettings.qt4 = false;
1133             // TODO: blacklist logic
1134             qtSettings.useAlpha =
1135                 (opts.bgndOpacity < 100 || opts.dlgOpacity < 100 ||
1136                  opts.menuBgndOpacity < 100 ||
1137                  !(opts.square & SQUARE_POPUP_MENUS) ||
1138                  !(opts.square & SQUARE_TOOLTIPS));
1139 
1140             lastRead=now;
1141 
1142             {
1143             int        f=0;
1144             const char *files[]={QTC_GTK2_THEME_DIR"/kdeglobals", /* QtCurve supplied kdeglobals file */
1145                                  "/etc/kderc",
1146                                  "/etc/kde4/kdeglobals",
1147                                  "/etc/kde4rc",
1148                                  QTC_KDE4_PREFIX KDE4_SYS_CFG_DIR KDEGLOBALS_FILE,
1149                                  QTC_KDE4_PREFIX KDE4_SYS_CFG_DIR
1150                                  KDEGLOBALS_SYS_FILE,
1151                                  kde4Globals(),
1152                                  kde5Globals(),
1153                                  nullptr};
1154 
1155             for(f=0; 0!=files[f]; ++f)
1156                 readKdeGlobals(files[f], RD_ICONS|RD_SMALL_ICON_SIZE|RD_TOOLBAR_STYLE|RD_MENU_FONT|RD_TB_FONT|
1157                                RD_TOOLBAR_ICON_SIZE|RD_BUTTON_ICONS|RD_LIST_SHADE|
1158                                (RD_KDE4_PAL|RD_FONT|RD_CONTRAST|RD_STYLE|RD_DRAG_DIST|RD_DRAG_TIME),
1159                                0==f);
1160             }
1161 
1162 #ifdef QTC_GTK2_STYLE_SUPPORT
1163             /* Only for testing - allows me to simulate Qt's -style parameter.
1164                e.g start Gtk2 app as follows:
1165 
1166                QTC_STYLE=qtc_klearlooks gtk-demo
1167             */
1168             if (const char *env = getenv("QTC_STYLE")) {
1169                 if (*env) {
1170                     qtSettings.styleName = Str::fill(qtSettings.styleName, env);
1171                 }
1172             }
1173 
1174             char *rcFile = nullptr;
1175             /* Is the user using a non-default QtCurve style? */
1176             if (qtSettings.styleName &&
1177                 Str::startsWith(qtSettings.styleName, THEME_PREFIX)) {
1178                 rcFile = themeFile(getKdeHome(), qtSettings.styleName,
1179                                    str_buff);
1180 
1181                 if (!rcFile) {
1182                     rcFile = themeFile(QTC_KDE4_PREFIX, qtSettings.styleName,
1183                                        str_buff);
1184                 }
1185             }
1186 
1187             qtcReadConfig(rcFile, &opts, nullptr);
1188 #else
1189             qtcReadConfig(nullptr, &opts, nullptr);
1190 #endif
1191             /* Focus is messed up if not using glow focus*/
1192             if (!opts.gtkComboMenus && opts.focus != FOCUS_GLOW)
1193                 opts.gtkComboMenus = true;
1194 #if 0
1195             if (opts.inactiveHighlight) {
1196                 generateMidColor(&qtSettings.colors[PAL_ACTIVE][COLOR_WINDOW],
1197                                  &qtSettings.colors[PAL_ACTIVE][COLOR_SELECTED],
1198                                  &qtSettings.inactiveSelectCol,
1199                                  INACTIVE_HIGHLIGHT_FACTOR);
1200             } else {
1201                 qtSettings.inactiveSelectCol =
1202                     qtSettings.colors[PAL_INACTIVE][COLOR_SELECTED];
1203             }
1204 #endif
1205             /* Check if we're firefox... */
1206             if ((qtSettings.appName = getProgName())) {
1207                 bool firefox = (isMozApp(qtSettings.appName, "firefox") ||
1208                                 isMozApp(qtSettings.appName, "iceweasel") ||
1209                                 isMozApp(qtSettings.appName, "swiftfox") ||
1210                                 isMozApp(qtSettings.appName, "xulrunner") ||
1211                                 isMozApp(qtSettings.appName, "abrowser"));
1212                 bool thunderbird =
1213                     (!firefox && (isMozApp(qtSettings.appName, "thunderbird") ||
1214                                   isMozApp(qtSettings.appName, "icedove")));
1215                 bool mozThunderbird =
1216                     (!thunderbird && !firefox &&
1217                      isMozApp(qtSettings.appName, "mozilla-thunderbird"));
1218                 bool seamonkey = (!thunderbird && !firefox && !mozThunderbird &&
1219                                   isMozApp(qtSettings.appName, "seamonkey"));
1220 
1221                 if (firefox || thunderbird || mozThunderbird || seamonkey) {
1222                     qtSettings.app = (firefox ? GTK_APP_NEW_MOZILLA :
1223                                       GTK_APP_MOZILLA);
1224                     if (qtSettings.app == GTK_APP_MOZILLA)
1225                         qtSettings.app = GTK_APP_NEW_MOZILLA;
1226                     if (qtSettings.app != GTK_APP_NEW_MOZILLA &&
1227                         opts.menuitemAppearance == APPEARANCE_FADE &&
1228                         (thunderbird || mozThunderbird)) {
1229                         opts.menuitemAppearance = APPEARANCE_FLAT;
1230                     }
1231                 } else if (strcmp(qtSettings.appName, "soffice.bin") == 0) {
1232                     qtSettings.app = GTK_APP_OPEN_OFFICE;
1233                 } else if (strcmp(qtSettings.appName, "vmplayer") == 0) {
1234                     qtSettings.app = GTK_APP_VMPLAYER;
1235                 } else if (Str::startsWith(qtSettings.appName, "gimp")) {
1236                     qtSettings.app = GTK_APP_GIMP;
1237                 } else if (strcmp(qtSettings.appName, "java") == 0) {
1238                     qtSettings.app = GTK_APP_JAVA;
1239                 } else if (strcmp(qtSettings.appName, "evolution") == 0) {
1240                     qtSettings.app = GTK_APP_EVOLUTION;
1241                 } else if (strcmp(qtSettings.appName, "eclipse") == 0) {
1242                     qtSettings.app = GTK_APP_JAVA_SWT;
1243                 } else if (strcmp(qtSettings.appName, "ghb") == 0) {
1244                     qtSettings.app = GTK_APP_GHB;
1245                 }
1246             }
1247 
1248             if(qtSettings.debug)
1249                 fprintf(stderr, DEBUG_PREFIX"Application name: \"%s\"\n", qtSettings.appName ? qtSettings.appName : "<unknown>");
1250 
1251             /* Eclipse sets a application name, so if this is set then we're not a Swing java app */
1252             if(GTK_APP_JAVA==qtSettings.app && g_get_application_name() && 0!=strcmp(g_get_application_name(), "<unknown>"))
1253                 qtSettings.app=GTK_APP_JAVA_SWT;
1254 
1255             if(GTK_APP_JAVA==qtSettings.app)
1256                 opts.sliderStyle=SLIDER_PLAIN;
1257 
1258             if (oneOf(qtSettings.app, GTK_APP_JAVA, GTK_APP_JAVA_SWT,
1259                       GTK_APP_OPEN_OFFICE) || isMozilla()) {
1260                 opts.square |= SQUARE_POPUP_MENUS;
1261                 opts.bgndAppearance = APPEARANCE_FLAT;
1262                 opts.bgndImage.type = IMG_NONE;
1263                 if (FRAME_SHADED == opts.groupBox)
1264                     opts.groupBox = FRAME_PLAIN;
1265                 opts.gbFactor = 0;
1266                 opts.highlightScrollViews = false;
1267             }
1268 
1269             if(!qtcIsFlat(opts.bgndAppearance) && excludedApp(opts.noBgndGradientApps))
1270                 opts.bgndAppearance=APPEARANCE_FLAT;
1271 
1272             if(IMG_NONE!=opts.bgndImage.type && excludedApp(opts.noBgndImageApps))
1273                 opts.bgndImage.type=IMG_NONE;
1274 
1275             if (oneOf(qtSettings.app, GTK_APP_OPEN_OFFICE, GTK_APP_JAVA,
1276                       GTK_APP_JAVA_SWT) || isMozilla()) {
1277                 opts.bgndOpacity = opts.dlgOpacity = opts.menuBgndOpacity = 100;
1278                 qtSettings.useAlpha = false;
1279             }
1280 
1281             if(excludedApp(opts.noBgndOpacityApps))
1282                 opts.bgndOpacity=opts.dlgOpacity=100;
1283 
1284             if(excludedApp(opts.noMenuBgndOpacityApps))
1285                 opts.menuBgndOpacity=100, qtSettings.useAlpha=false;
1286 
1287             /* Disable usage of alpha channel for older configs, unless app is uing opacity... */
1288             if(qtSettings.useAlpha && opts.version<qtcMakeVersion(1, 7, 2) && 100==opts.menuBgndOpacity && 100==opts.dlgOpacity && 100==opts.bgndOpacity)
1289                 qtSettings.useAlpha=false;
1290 
1291             if(opts.menuStripe && excludedApp(opts.noMenuStripeApps))
1292                 opts.menuStripe=SHADE_NONE;
1293 
1294             if (GTK_APP_JAVA != qtSettings.app) {
1295                 /* KDE's "apply colors to non-KDE apps" messes up firefox,
1296                    (and progress bar text) so need to fix this! */
1297                 /* ...and inactive highlight!!! */
1298                 GdkColor *highlightedMenuCol =
1299                     (opts.useHighlightForMenu ?
1300                      &qtSettings.colors[PAL_ACTIVE][COLOR_TEXT_SELECTED] :
1301                      &qtSettings.colors[PAL_ACTIVE][COLOR_TEXT]);
1302                 qtc_gtkrc_printf(str_buff, "style \"" RC_SETTING "MTxt\""
1303                                  " {fg[ACTIVE]=\"#%02X%02X%02X\""
1304                                  " fg[PRELIGHT]=\"#%02X%02X%02X\"}"
1305                                  " style \"" RC_SETTING "PTxt\""
1306                                  " {fg[ACTIVE]=\"#%02X%02X%02X\""
1307                                  " fg[PRELIGHT]=\"#%02X%02X%02X\"}"
1308                                  " class \"*MenuItem\" style \"" RC_SETTING
1309                                  "MTxt\" widget_class \"*.*MenuItem*\" "
1310                                  "style \"" RC_SETTING "MTxt\" "
1311                                  " widget_class \"*.*ProgressBar\" "
1312                                  "style \"" RC_SETTING "PTxt\"",
1313                                  toQtColor(highlightedMenuCol->red),
1314                                  toQtColor(highlightedMenuCol->green),
1315                                  toQtColor(highlightedMenuCol->blue),
1316                                  toQtColor(highlightedMenuCol->red),
1317                                  toQtColor(highlightedMenuCol->green),
1318                                  toQtColor(highlightedMenuCol->blue),
1319                                  toQtColor(qtSettings.colors[PAL_ACTIVE]
1320                                            [COLOR_TEXT_SELECTED].red),
1321                                  toQtColor(qtSettings.colors[PAL_ACTIVE]
1322                                            [COLOR_TEXT_SELECTED].green),
1323                                  toQtColor(qtSettings.colors[PAL_ACTIVE]
1324                                            [COLOR_TEXT_SELECTED].blue),
1325                                  toQtColor(qtSettings.colors[PAL_ACTIVE]
1326                                            [COLOR_TEXT_SELECTED].red),
1327                                  toQtColor(qtSettings.colors[PAL_ACTIVE]
1328                                            [COLOR_TEXT_SELECTED].green),
1329                                  toQtColor(qtSettings.colors[PAL_ACTIVE]
1330                                            [COLOR_TEXT_SELECTED].blue));
1331                 if (GTK_APP_OPEN_OFFICE == qtSettings.app) {
1332                     GdkColor *active = nullptr;
1333                     GdkColor *inactive = nullptr;
1334 
1335                     if (SHADE_WINDOW_BORDER == opts.shadeMenubars) {
1336                         active = (&qtSettings.colors[PAL_ACTIVE][
1337                                       opts.useHighlightForMenu ?
1338                                       COLOR_TEXT_SELECTED :
1339                                       COLOR_WINDOW_BORDER_TEXT]);
1340                         inactive = &qtSettings.colors[PAL_ACTIVE][
1341                             COLOR_WINDOW_BORDER_TEXT];
1342                     } else if (opts.customMenuTextColor) {
1343                         active = &opts.customMenuSelTextColor;
1344                         inactive = &opts.customMenuNormTextColor;
1345                     } else if (SHADE_BLEND_SELECTED == opts.shadeMenubars ||
1346                                SHADE_SELECTED == opts.shadeMenubars ||
1347                                (SHADE_CUSTOM == opts.shadeMenubars &&
1348                                 TOO_DARK(qtcPalette.menubar[ORIGINAL_SHADE]))) {
1349                         active = &qtSettings.colors[PAL_ACTIVE][
1350                             COLOR_TEXT_SELECTED];
1351                         inactive = &qtSettings.colors[PAL_ACTIVE][
1352                             COLOR_TEXT_SELECTED];
1353                     }
1354 
1355                     if (active && inactive) {
1356                         qtc_gtkrc_printf(
1357                             str_buff, "style \"" RC_SETTING "MnuTxt\""
1358                             " {fg[NORMAL]=\"#%02X%02X%02X\" "
1359                             "fg[PRELIGHT]=\"#%02X%02X%02X\" "
1360                             "fg[ACTIVE]=\"#%02X%02X%02X\" "
1361                             "fg[SELECTED]=\"#%02X%02X%02X\" "
1362                             "text[NORMAL]=\"#%02X%02X%02X\"} "
1363                             "widget_class \"*<GtkMenuBar>*\" style \""
1364                             RC_SETTING "MnuTxt\" %s", toQtColor(inactive->red),
1365                             toQtColor(inactive->green),
1366                             toQtColor(inactive->blue), toQtColor(active->red),
1367                             toQtColor(active->green), toQtColor(active->blue),
1368                             toQtColor(active->red), toQtColor(active->green),
1369                             toQtColor(active->blue), toQtColor(active->red),
1370                             toQtColor(active->green), toQtColor(active->blue),
1371                             toQtColor(inactive->red),
1372                             toQtColor(inactive->green),
1373                             toQtColor(inactive->blue),
1374                             opts.shadePopupMenu ?
1375                             " widget_class \"*<GtkMenuItem>*\" style \""
1376                             RC_SETTING "MnuTxt\" " : " ");
1377                     }
1378                 }
1379             }
1380 
1381             if (GTK_APP_VMPLAYER == qtSettings.app) {
1382                 opts.shadeMenubars = SHADE_NONE;
1383                 opts.menubarHiding = HIDE_NONE;
1384                 opts.statusbarHiding = HIDE_NONE;
1385             }
1386 
1387             if (opts.mapKdeIcons && qtSettings.icons) {
1388                 qtc_gtkrc_printf(str_buff, "gtk-icon-theme-name=\"%s\"",
1389                                  qtSettings.icons);
1390             }
1391 
1392             if(opts.mapKdeIcons && (path = getIconPath()))
1393             {
1394                 const char *iconTheme=qtSettings.icons ? qtSettings.icons : "XX";
1395                 /* '#' VERSION ' '<kde version> <..nums above..>\0 */
1396                 int versionLen = (1 + strlen(qtcVersion()) + 1 +
1397                                   strlen(iconTheme) + 1 + 2 + 6 * 2 + 1);
1398                 char *version = (char*)malloc(versionLen);
1399 
1400                 tmpStr = getConfFile("gtk-icons", tmpStr);
1401                 sprintf(version, "#%s %s %02X%02X%02X%02X%02X%02X%02X",
1402                         qtcVersion(), iconTheme, 4,
1403                         qtSettings.iconSizes.smlTbSize,
1404                         qtSettings.iconSizes.tbSize,
1405                         qtSettings.iconSizes.dndSize,
1406                         qtSettings.iconSizes.btnSize,
1407                         qtSettings.iconSizes.mnuSize,
1408                         qtSettings.iconSizes.dlgSize);
1409 
1410                 if (!checkFileVersion(tmpStr, version, versionLen)) {
1411                     static const char *constCmdStrFmt = "perl " QTC_GTK2_THEME_DIR "/map_kde_icons.pl " QTC_GTK2_THEME_DIR "/icons%d %s %d %d %d %d %d %d %d %s %s > %s.%d && mv %s.%d %s";
1412 
1413                     const char *kdeprefix = kdeIconsPrefix();
1414                     int fileNameLen = strlen(tmpStr);
1415                     char *cmdStr = (char*)malloc(strlen(constCmdStrFmt) + 2 +
1416                                                  4 * 6 + 2 + strlen(iconTheme) +
1417                                                  (kdeprefix ?
1418                                                   strlen(kdeprefix) :
1419                                                   DEFAULT_ICON_PREFIX_LEN) +
1420                                                  fileNameLen * 3 + 64 +
1421                                                  strlen(qtcVersion()) + 1);
1422 
1423                     sprintf(cmdStr, constCmdStrFmt, 4,
1424                             kdeprefix ? kdeprefix : DEFAULT_ICON_PREFIX, 4,
1425                             qtSettings.iconSizes.smlTbSize,
1426                             qtSettings.iconSizes.tbSize,
1427                             qtSettings.iconSizes.dndSize,
1428                             qtSettings.iconSizes.btnSize,
1429                             qtSettings.iconSizes.mnuSize,
1430                             qtSettings.iconSizes.dlgSize,
1431                             iconTheme, qtcVersion(), tmpStr, getpid(),
1432                             tmpStr, getpid(), tmpStr);
1433                     system(cmdStr);
1434                     free(cmdStr);
1435                 }
1436                 free(version);
1437                 gtk_rc_parse_string(path);
1438                 gtk_rc_parse(tmpStr);
1439             }
1440 
1441             if((settings=gtk_settings_get_default()))
1442             {
1443                 if(qtSettings.fonts[FONT_GENERAL])
1444                     g_object_set(settings, "gtk-font-name", qtSettings.fonts[FONT_GENERAL], nullptr);
1445 
1446                 gtk_settings_set_long_property(settings, "gtk-toolbar-style", qtSettings.toolbarStyle, "KDE-Settings");
1447                 if(qtSettings.debug) fprintf(stderr, DEBUG_PREFIX "gtk-toolbar-style %d\n", qtSettings.toolbarStyle);
1448                 if (gtk_check_version(2, 4, 0) == nullptr) {
1449                     /* The following settings only apply for GTK>=2.4.0 */
1450                     if(qtSettings.debug) fprintf(stderr, DEBUG_PREFIX "gtk-button-images %d\n", qtSettings.buttonIcons);
1451                     gtk_settings_set_long_property(settings, "gtk-button-images", qtSettings.buttonIcons, "KDE-Settings");
1452 #if 0
1453                     if(opts.drawStatusBarFrames)
1454                         gtk_rc_parse_string("style \"" RC_SETTING "StBar\""
1455                                             "{ GtkStatusbar::shadow-type = 1 }" /*GtkStatusbar::has-resize-grip = false }" */
1456                                             "class \"GtkStatusbar\" style"
1457                                             " \"" RC_SETTING "StBar\"");
1458                     else
1459                         gtk_rc_parse_string("style \"" RC_SETTING "SBar\""
1460                                             "{ GtkStatusbar::shadow-type = 0 }" /*GtkStatusbar::has-resize-grip = false }" */
1461                                             "class \"GtkStatusbar\" style"
1462                                             " \"" RC_SETTING "SBar\"");
1463 #endif
1464                 }
1465 
1466                 /* The following settings only apply for GTK>=2.6.0 */
1467                 if(!opts.gtkButtonOrder && nullptr==gtk_check_version(2, 6, 0))
1468                     g_object_set(settings, "gtk-alternative-button-order", true, nullptr);
1469 
1470                 gtk_settings_set_long_property(settings, "gtk-menu-popup-delay", opts.menuDelay, "KDE-Settings");
1471             }
1472 
1473             if(qtSettings.fonts[FONT_GENERAL])
1474             {
1475                 static const char *constFormat="style \"" RC_SETTING "Fnt\" {font_name=\"%s\"} "
1476                                                "widget_class \"*\" style \"" RC_SETTING "Fnt\" ";
1477                 tmpStr=(char *)realloc(tmpStr, strlen(constFormat)+strlen(qtSettings.fonts[FONT_GENERAL])+1);
1478 
1479                 sprintf(tmpStr, constFormat, qtSettings.fonts[FONT_GENERAL]);
1480                 gtk_rc_parse_string(tmpStr);
1481             }
1482 
1483             if(qtSettings.fonts[FONT_BOLD] && qtSettings.fonts[FONT_GENERAL] && strcmp(qtSettings.fonts[FONT_BOLD], qtSettings.fonts[FONT_GENERAL]))
1484             {
1485                 static const char *constBoldPrefix="style \"" RC_SETTING "BFnt\"{font_name=\"";
1486                 static const char *constBoldSuffix="\"} class \"GtkProgress\" style \"" RC_SETTING "BFnt\" "
1487                                                    "widget_class \"*GtkProgress*\" style \"" RC_SETTING "BFnt\" ";
1488 
1489                 if(opts.gbLabel&GB_LBL_BOLD)
1490                 {
1491                     static const char *constStdPrefix="style \"" RC_SETTING "Fnt\"{font_name=\"";
1492                     static const char *constStdSuffix="\"} ";
1493                     static const char *constGrpBoxBoldSuffix="widget_class \"*Frame.GtkLabel\" style \"" RC_SETTING "BFnt\" "
1494                                                              "widget_class \"*Statusbar.*Frame.GtkLabel\" style \"" RC_SETTING "Fnt\"";
1495                     tmpStr=(char *)realloc(tmpStr, strlen(constStdPrefix)+strlen(qtSettings.fonts[FONT_GENERAL])+strlen(constStdSuffix)+
1496                                                    strlen(constBoldPrefix)+strlen(qtSettings.fonts[FONT_BOLD])+
1497                                                    (opts.boldProgress ? strlen(constBoldSuffix) : strlen(constStdSuffix))+
1498                                                    strlen(constGrpBoxBoldSuffix)+1);
1499 
1500                     sprintf(tmpStr, "%s%s%s%s%s%s%s",
1501                                     constStdPrefix, qtSettings.fonts[FONT_GENERAL], constStdSuffix,
1502                                     constBoldPrefix, qtSettings.fonts[FONT_BOLD], opts.boldProgress ? constBoldSuffix : constStdSuffix,
1503                                     constGrpBoxBoldSuffix);
1504                 }
1505                 else if(opts.boldProgress)
1506                 {
1507                     tmpStr=(char *)realloc(tmpStr, strlen(constBoldPrefix)+strlen(qtSettings.fonts[FONT_BOLD])+strlen(constBoldSuffix)+1);
1508                     sprintf(tmpStr, "%s%s%s", constBoldPrefix, qtSettings.fonts[FONT_BOLD], constBoldSuffix);
1509                 }
1510 
1511                 gtk_rc_parse_string(tmpStr);
1512             }
1513 
1514             if(qtSettings.fonts[FONT_MENU] && qtSettings.fonts[FONT_GENERAL] && strcmp(qtSettings.fonts[FONT_MENU], qtSettings.fonts[FONT_GENERAL]))
1515             {
1516                 static const char *constFormat="style \"" RC_SETTING "MFnt\" {font_name=\"%s\"} "
1517                                                "widget_class \"*.*MenuItem.*\" style \"" RC_SETTING "MFnt\" ";
1518                 tmpStr=(char *)realloc(tmpStr, strlen(constFormat)+strlen(qtSettings.fonts[FONT_MENU])+1);
1519 
1520                 sprintf(tmpStr, constFormat, qtSettings.fonts[FONT_MENU]);
1521                 gtk_rc_parse_string(tmpStr);
1522             }
1523 
1524             if(qtSettings.fonts[FONT_TOOLBAR] && qtSettings.fonts[FONT_GENERAL] && strcmp(qtSettings.fonts[FONT_TOOLBAR], qtSettings.fonts[FONT_GENERAL]))
1525             {
1526                 static const char *constFormat="style \"" RC_SETTING "TbFnt\" {font_name=\"%s\"} "
1527                                                "widget_class \"*.*Toolbar.*\" style \"" RC_SETTING "TbFnt\" ";
1528                 tmpStr=(char *)realloc(tmpStr, strlen(constFormat)+strlen(qtSettings.fonts[FONT_TOOLBAR])+1);
1529 
1530                 sprintf(tmpStr, constFormat, qtSettings.fonts[FONT_TOOLBAR]);
1531                 gtk_rc_parse_string(tmpStr);
1532             }
1533 
1534             if((opts.thin&THIN_MENU_ITEMS))
1535                 gtk_rc_parse_string("style \"" RC_SETTING "Mi\" {xthickness = 1 ythickness = 2 } "
1536                                     "class \"*MenuItem\" style \"" RC_SETTING "Mi\"");
1537 
1538             /* Set password character... */
1539 /*
1540             {
1541                 static const char *constPasswdStrFormat="style \"QtCPasswd\" { GtkEntry::invisible-char='$' } class \"*\" style \"QtCPasswd\"";
1542 
1543                 tmpStr=(char *)realloc(tmpStr, strlen(constPasswdStrFormat)+16);
1544                 sprintf(tmpStr, constPasswdStrFormat, opts.passwordChar);
1545                 gtk_rc_parse_string(tmpStr);
1546             }
1547 */
1548             /* For some reason Firefox 3beta4 goes mad if GtkComboBoxEntry::appears-as-list = 1 !!!! */
1549             if(isMozilla())
1550                 gtk_rc_parse_string("style \"" RC_SETTING "Mz\" { GtkComboBoxEntry::appears-as-list = 0 } class \"*\" style \"" RC_SETTING "Mz\"");
1551             else if(!opts.gtkComboMenus)
1552             {
1553                 gtk_rc_parse_string("style \"" RC_SETTING "Cmb\" { GtkComboBox::appears-as-list = 1 } class \"*\" style \"" RC_SETTING "Cmb\"");
1554                 gtk_rc_parse_string("style \"" RC_SETTING "Cmbf\" { xthickness=5 } widget_class \"*.GtkComboBox.GtkFrame\" style \"" RC_SETTING "Cmbf\"");
1555             }
1556 
1557             if (oneOf(qtSettings.app, GTK_APP_MOZILLA, GTK_APP_JAVA) ||
1558                 (opts.scrollbarType == SCROLLBAR_NONE && isMozilla())) {
1559                 opts.scrollbarType = SCROLLBAR_WINDOWS;
1560             } else {
1561                 static const char *constSbStrFormat="style \"" RC_SETTING "SBt\" "
1562                                                     "{ GtkScrollbar::has-backward-stepper=%d "
1563                                                       "GtkScrollbar::has-forward-stepper=%d "
1564                                                       "GtkScrollbar::has-secondary-backward-stepper=%d "
1565                                                       "GtkScrollbar::has-secondary-forward-stepper=%d } "
1566                                                     "class \"*\" style \"" RC_SETTING "SBt\"";
1567                 tmpStr=(char *)realloc(tmpStr, strlen(constSbStrFormat)+1);
1568 
1569                 if(GTK_APP_OPEN_OFFICE==qtSettings.app)
1570                 {
1571                     if(SCROLLBAR_NEXT==opts.scrollbarType)
1572                         opts.scrollbarType=SCROLLBAR_KDE;
1573                     else if(SCROLLBAR_NONE==opts.scrollbarType)
1574                         opts.scrollbarType=SCROLLBAR_WINDOWS;
1575                 }
1576 
1577                 switch(opts.scrollbarType)
1578                 {
1579                     default:
1580                     case SCROLLBAR_KDE:
1581                         sprintf(tmpStr, constSbStrFormat, 1, 1, 1, 0);
1582                         break;
1583                     case SCROLLBAR_WINDOWS:
1584                         sprintf(tmpStr, constSbStrFormat, 1, 1, 0, 0);
1585                         break;
1586                     case SCROLLBAR_PLATINUM:
1587                         sprintf(tmpStr, constSbStrFormat, 0, 1, 1, 0);
1588                         break;
1589                     case SCROLLBAR_NEXT:
1590                         sprintf(tmpStr, constSbStrFormat, 1, 0, 0, 1);
1591                         break;
1592                     case SCROLLBAR_NONE:
1593                         sprintf(tmpStr, constSbStrFormat, 0, 0, 0, 0);
1594                         break;
1595                 }
1596 
1597                 gtk_rc_parse_string(tmpStr);
1598             }
1599 
1600             /* Set cursor colours... */
1601             const char *constStrFormat="style \"" RC_SETTING "Crsr\" "
1602                 "{ GtkWidget::cursor-color=\"#%02X%02X%02X\" "
1603                 "GtkWidget::secondary-cursor-color=\"#%02X%02X%02X\" } "
1604                 "class \"*\" style \"" RC_SETTING "Crsr\"";
1605             tmpStr=(char *)realloc(tmpStr, strlen(constStrFormat)+1);
1606 
1607             sprintf(tmpStr, constStrFormat,
1608                     qtSettings.colors[PAL_ACTIVE][COLOR_TEXT].red>>8,
1609                     qtSettings.colors[PAL_ACTIVE][COLOR_TEXT].green>>8,
1610                     qtSettings.colors[PAL_ACTIVE][COLOR_TEXT].blue>>8,
1611                     qtSettings.colors[PAL_ACTIVE][COLOR_TEXT].red>>8,
1612                     qtSettings.colors[PAL_ACTIVE][COLOR_TEXT].green>>8,
1613                     qtSettings.colors[PAL_ACTIVE][COLOR_TEXT].blue>>8);
1614             gtk_rc_parse_string(tmpStr);
1615 
1616             if(!opts.gtkScrollViews && nullptr!=gtk_check_version(2, 12, 0))
1617                 opts.gtkScrollViews=true;
1618 
1619             bool doEffect=EFFECT_NONE!=opts.buttonEffect;
1620             int  thickness=2;
1621 
1622             constStrFormat =
1623                 "style \"" RC_SETTING "Etch2\" "
1624                 "{ xthickness = 3 ythickness = %d} "
1625                 "class \"*Button\" style \"" RC_SETTING "Etch2\""
1626                 "class \"*GtkOptionMenu\" style \"" RC_SETTING "Etch2\"";
1627 
1628             tmpStr = (char*)realloc(tmpStr, strlen(constStrFormat) + 2);
1629             sprintf(tmpStr, constStrFormat, (opts.thin & THIN_BUTTONS) ||
1630                     !doEffect ? 1 : 2);
1631             gtk_rc_parse_string(tmpStr);
1632 
1633             constStrFormat =
1634                 "style \"" RC_SETTING "EtchE\" { xthickness = %d "
1635                 "ythickness = %d } style \"" RC_SETTING "EtchS\" "
1636                 "{ xthickness = %d ythickness = %d } widget_class "
1637                 "\"*Toolbar*GtkSpinButton\" style \"" RC_SETTING "EtchE\" "
1638                 "class \"*GtkEntry\" style  \"" RC_SETTING "EtchE\" "
1639                 "widget_class \"*Toolbar*Entry\" style \"" RC_SETTING "EtchE\" "
1640                 "class \"*GtkSpinButton\" style \"" RC_SETTING "EtchS\" ";
1641 
1642             int thick = /*opts.etchEntry && doEffect ?*/ 4 /*: 3*/;
1643             tmpStr = (char*)realloc(tmpStr, strlen(constStrFormat) + 8);
1644             sprintf(tmpStr, constStrFormat, thick, thick, thick, thick);
1645             gtk_rc_parse_string(tmpStr);
1646 
1647             if (isMozilla()) {
1648                 constStrFormat =
1649                     "style \"" RC_SETTING "EtchEM\" { xthickness = %d "
1650                     "ythickness = %d } widget_class "
1651                     "\"*GtkFixed*GtkSpinButton\" style \"" RC_SETTING
1652                     "EtchEM\" widget_class \"*GtkFixed*Entry\" style \""
1653                     RC_SETTING "EtchEM\" ";
1654 
1655                 int thick = opts.etchEntry && doEffect ? 3 : 2;
1656                 tmpStr = (char*)realloc(tmpStr, strlen(constStrFormat) + 4);
1657                 sprintf(tmpStr, constStrFormat, thick, thick);
1658                 gtk_rc_parse_string(tmpStr);
1659             }
1660 
1661             if(!opts.gtkScrollViews)
1662                 gtk_rc_parse_string("style \"" RC_SETTING "SV\""
1663                                     " { GtkScrolledWindow::scrollbar-spacing = 0 "
1664                                       " GtkScrolledWindow::scrollbars-within-bevel = 1 } "
1665                                     "class \"GtkScrolledWindow\" style \"" RC_SETTING "SV\"");
1666             else if(opts.etchEntry)
1667                 gtk_rc_parse_string("style \"" RC_SETTING "SV\""
1668                                     " { GtkScrolledWindow::scrollbar-spacing = 2 } "
1669                                     "class \"GtkScrolledWindow\" style \"" RC_SETTING "SV\"");
1670 
1671             /* Scrolled windows */
1672             if((opts.square&SQUARE_SCROLLVIEW))
1673                 thickness=!opts.highlightScrollViews && (opts.gtkScrollViews || opts.thinSbarGroove || !opts.borderSbarGroove) ? 1 : 2;
1674             else if(opts.etchEntry)
1675                 thickness=3;
1676 
1677             constStrFormat =
1678                 "style \"" RC_SETTING "SVt\" { xthickness = %d "
1679                 "ythickness = %d } class \"*GtkScrolledWindow\" style \""
1680                 RC_SETTING "SVt\"";
1681             tmpStr = (char*)realloc(tmpStr, strlen(constStrFormat) + 1);
1682             sprintf(tmpStr, constStrFormat, thickness, thickness);
1683             gtk_rc_parse_string(tmpStr);
1684 
1685             constStrFormat =
1686                 "style \"" RC_SETTING "Pbar\" { xthickness = %d "
1687                 "ythickness = %d } widget_class \"*GtkProgressBar\" style \""
1688                 RC_SETTING "Pbar\"";
1689             int pthickness = (opts.fillProgress ?
1690                               doEffect && opts.borderProgress ? 1 : 0 :
1691                               doEffect ? 2 : 1);
1692             tmpStr = (char*)realloc(tmpStr, strlen(constStrFormat) + 1);
1693             sprintf(tmpStr, constStrFormat, pthickness, pthickness);
1694             gtk_rc_parse_string(tmpStr);
1695 
1696             constStrFormat =
1697                 "style \"" RC_SETTING "TT\" { xthickness = 4 "
1698                 "ythickness = 4 bg[NORMAL] = \"#%02X%02X%02X\" "
1699                 "fg[NORMAL] = \"#%02X%02X%02X\"} widget \"gtk-tooltips*\" "
1700                 "style \"" RC_SETTING "TT\" widget \"gtk-tooltip*\" style \""
1701                 RC_SETTING "TT\"";
1702 
1703             tmpStr = (char*)realloc(tmpStr, strlen(constStrFormat) + 1);
1704             sprintf(tmpStr, constStrFormat,
1705                     toQtColor(qtSettings.colors[PAL_ACTIVE][COLOR_TOOLTIP].red),
1706                     toQtColor(qtSettings.colors[PAL_ACTIVE][COLOR_TOOLTIP].green),
1707                     toQtColor(qtSettings.colors[PAL_ACTIVE][COLOR_TOOLTIP].blue),
1708                     toQtColor(
1709                         qtSettings.colors[PAL_ACTIVE][COLOR_TOOLTIP_TEXT].red),
1710                     toQtColor(
1711                         qtSettings.colors[PAL_ACTIVE][COLOR_TOOLTIP_TEXT].green),
1712                     toQtColor(
1713                         qtSettings.colors[PAL_ACTIVE][COLOR_TOOLTIP_TEXT].blue));
1714             gtk_rc_parse_string(tmpStr);
1715 
1716             if( EFFECT_NONE==opts.buttonEffect)
1717                 gtk_rc_parse_string("style \"" RC_SETTING "Cmb\" { xthickness = 4 ythickness = 2 }"
1718                                     "widget_class \"*.GtkCombo.GtkEntry\" style \"" RC_SETTING "Cmb\"");
1719 
1720             if(opts.round>=ROUND_FULL && EFFECT_NONE!=opts.buttonEffect)
1721                 gtk_rc_parse_string("style \"" RC_SETTING "Swt\" { xthickness = 3 ythickness = 2 }"
1722                                     "widget_class \"*.SwtFixed.GtkCombo.GtkButton\" style \"" RC_SETTING "Swt\""
1723                                     "widget_class \"*.SwtFixed.GtkCombo.GtkEntry\" style \"" RC_SETTING "Swt\"");
1724 
1725 
1726             gtk_rc_parse_string("style \"" RC_SETTING "MnuTb\" "
1727                                 "{ xthickness=1 ythickness=1"
1728                                 " GtkButton::focus-padding=0 GtkWidget::focus-line-width=0} "
1729                                 "class \"*GtkMenuToolButton\" style \"" RC_SETTING "MnuTb\""
1730                                 "widget_class \"*.GtkMenuToolButton.*Box.GtkToggleButton\" style \"" RC_SETTING "MnuTb\"");
1731 
1732             if(!opts.popupBorder)
1733                 gtk_rc_parse_string("style \"" RC_SETTING "M\" { xthickness=0 ythickness=0 }\n"
1734                                     "class \"*GtkMenu\" style \"" RC_SETTING "M\"");
1735             else if(!qtcDrawMenuBorder(opts) && !opts.borderMenuitems &&
1736                     opts.square & SQUARE_POPUP_MENUS)
1737                 gtk_rc_parse_string("style \"" RC_SETTING "M\" { xthickness=1 ythickness=1 }\n"
1738                                     "class \"*GtkMenu\" style \"" RC_SETTING "M\"");
1739 
1740             constStrFormat =
1741                 "style \""  RC_SETTING  "Tree\" { GtkTreeView::odd-row-color = "
1742                 "\"#%02X%02X%02X\" GtkTreeView::even-row-color = "
1743                 "\"#%02X%02X%02X\"} widget \"*GtkTreeView*\" style \""
1744                 RC_SETTING "Tree\"";
1745             int alt = haveAlternateListViewCol() ? COLOR_LV : COLOR_BACKGROUND;
1746 
1747             tmpStr = (char*)realloc(tmpStr, strlen(constStrFormat) + 1);
1748             sprintf(tmpStr, constStrFormat,
1749                     toQtColor(qtSettings.colors[PAL_ACTIVE][alt].red),
1750                     toQtColor(qtSettings.colors[PAL_ACTIVE][alt].green),
1751                     toQtColor(qtSettings.colors[PAL_ACTIVE][alt].blue),
1752                     toQtColor(
1753                         qtSettings.colors[PAL_ACTIVE][COLOR_BACKGROUND].red),
1754                     toQtColor(
1755                         qtSettings.colors[PAL_ACTIVE][COLOR_BACKGROUND].green),
1756                     toQtColor(
1757                         qtSettings.colors[PAL_ACTIVE][COLOR_BACKGROUND].blue));
1758             gtk_rc_parse_string(tmpStr);
1759 
1760             if (!opts.useHighlightForMenu) {
1761                 constStrFormat =
1762                     "style \"" RC_SETTING "Mnu\" { text[ACTIVE] = "
1763                     "\"#%02X%02X%02X\"  text[SELECTED] = \"#%02X%02X%02X\" } "
1764                     " class \"*MenuItem\" style \"" RC_SETTING "Mnu\""
1765                     " widget_class \"*MenuBar*MenuItem\" style \"" RC_SETTING
1766                     "Mnu\" widget_class \"*.GtkAccelMenuItem\" style \""
1767                     RC_SETTING "Mnu\" widget_class \"*.GtkRadioMenuItem\" "
1768                     "style \"" RC_SETTING "Mnu\" widget_class "
1769                     "\"*.GtkCheckMenuItem\" style \"" RC_SETTING "Mnu\""
1770                     " widget_class \"*.GtkImageMenuItem\" style \"" RC_SETTING
1771                     "Mnu\"";
1772 
1773                 tmpStr = (char*)realloc(tmpStr, strlen(constStrFormat) + 1);
1774                 sprintf(tmpStr, constStrFormat,
1775                         toQtColor(qtSettings.colors[PAL_ACTIVE][COLOR_TEXT].red),
1776                         toQtColor(qtSettings.colors[PAL_ACTIVE][COLOR_TEXT].green),
1777                         toQtColor(qtSettings.colors[PAL_ACTIVE][COLOR_TEXT].blue),
1778                         toQtColor(qtSettings.colors[PAL_ACTIVE][COLOR_TEXT].red),
1779                         toQtColor(qtSettings.colors[PAL_ACTIVE][COLOR_TEXT].green),
1780                         toQtColor(qtSettings.colors[PAL_ACTIVE][COLOR_TEXT].blue));
1781                 gtk_rc_parse_string(tmpStr);
1782             }
1783 
1784             /* Mozilla seems to assume that all scrolledviews are square :-(
1785                So, set the xthickness and ythickness to 1, and in qtcurve.c draw these as square */
1786             if(isMozilla())
1787                 gtk_rc_parse_string("style \"" RC_SETTING "SVm\""
1788                                     " { xthickness=1 ythickness=1 } "
1789                                     "widget_class \"GtkWindow.GtkFixed.GtkScrolledWindow\" style \"" RC_SETTING "SVm\"");
1790 
1791             if(TAB_MO_GLOW==opts.tabMouseOver)
1792                 gtk_rc_parse_string("style \"" RC_SETTING "Tab\" { GtkNotebook::tab-overlap = 0 } class \"*GtkNotebook\" style \"" RC_SETTING "Tab\"");
1793 
1794             if (!opts.useHighlightForMenu &&
1795                 GTK_APP_OPEN_OFFICE == qtSettings.app) {
1796                 constStrFormat =
1797                     "style \"" RC_SETTING "OOMnu\" "
1798                     "{ bg[SELECTED] = \"#%02X%02X%02X\" } "
1799                     " class \"*Menu*\" style \"" RC_SETTING "OOMnu\" "
1800                     " widget_class \"*Menu*\" style \"" RC_SETTING "OOMnu\" ";
1801 
1802 
1803                 shadeColors(&qtSettings.colors[PAL_ACTIVE][COLOR_WINDOW], qtcPalette.background);
1804                 tmpStr = (char*)realloc(tmpStr, strlen(constStrFormat)+1);
1805                 sprintf(tmpStr, constStrFormat,
1806                         toQtColor(qtcPalette.background[4].red),
1807                         toQtColor(qtcPalette.background[4].green),
1808                         toQtColor(qtcPalette.background[4].blue));
1809                 gtk_rc_parse_string(tmpStr);
1810             }
1811 
1812             if (DEFAULT_SLIDER_WIDTH != opts.sliderWidth) {
1813                 constStrFormat =
1814                     "style \"" RC_SETTING "SbarW\" "
1815                     "{ GtkRange::slider_width = %d GtkRange::stepper_size = %d "
1816                     "  GtkScrollbar::min_slider_length = %d } "
1817                     " class \"*\" style \"" RC_SETTING "SbarW\" ";
1818 
1819                 tmpStr = (char*)realloc(tmpStr, strlen(constStrFormat) + 16);
1820                 sprintf(tmpStr, constStrFormat, opts.sliderWidth,
1821                         opts.sliderWidth, opts.sliderWidth+1);
1822                 gtk_rc_parse_string(tmpStr);
1823             }
1824 
1825             bool customSliderW = opts.sliderWidth != DEFAULT_SLIDER_WIDTH;
1826             int glowSize = (opts.buttonEffect != EFFECT_NONE &&
1827                             opts.coloredMouseOver == MO_GLOW ? 2 : 0);
1828             int length = (SLIDER_CIRCULAR==opts.sliderStyle ?
1829                           CIRCULAR_SLIDER_SIZE :
1830                           SLIDER_TRIANGULAR == opts.sliderStyle ? 11 :
1831                           SLIDER_PLAIN_ROTATED == opts.sliderStyle ||
1832                           SLIDER_ROUND_ROTATED == opts.sliderStyle ?
1833                           (customSliderW ? SLIDER_SIZE - 2 : 13) :
1834                           (customSliderW ? SLIDER_SIZE + 6 : 21)) + glowSize;
1835             int width = (SLIDER_CIRCULAR == opts.sliderStyle ?
1836                          CIRCULAR_SLIDER_SIZE :
1837                          SLIDER_TRIANGULAR == opts.sliderStyle ? 18 :
1838                          SLIDER_PLAIN_ROTATED == opts.sliderStyle ||
1839                          SLIDER_ROUND_ROTATED == opts.sliderStyle ?
1840                          (customSliderW ? SLIDER_SIZE + 6 : 21) :
1841                          (customSliderW ? SLIDER_SIZE - 2 : 13)) + glowSize;
1842 
1843             constStrFormat =
1844                 "style \"" RC_SETTING "Sldr\" "
1845                 "{GtkScale::slider_length = %d GtkScale::slider_width = %d} "
1846                 "class \"*\" style \"" RC_SETTING "Sldr\"";
1847 
1848             tmpStr = (char*)realloc(tmpStr, strlen(constStrFormat) + 8);
1849             sprintf(tmpStr, constStrFormat, length, width);
1850             gtk_rc_parse_string(tmpStr);
1851 
1852             if(!opts.menuIcons)
1853                 gtk_rc_parse_string("gtk-menu-images=0");
1854 
1855             if(opts.hideShortcutUnderline)
1856                 gtk_rc_parse_string("gtk-auto-mnemonics=1");
1857 
1858             if(LINE_1DOT==opts.splitters)
1859                 gtk_rc_parse_string("style \"" RC_SETTING "Spl\" { GtkPaned::handle_size=7 GtkPaned::handle_width = 7 } "
1860                                     "class \"*GtkWidget\" style \"" RC_SETTING "Spl\"");
1861 
1862             if (oneOf(opts.bgndImage.type, IMG_PLAIN_RINGS,
1863                       IMG_BORDERED_RINGS, IMG_SQUARE_RINGS) ||
1864                 oneOf(opts.menuBgndImage.type, IMG_PLAIN_RINGS,
1865                       IMG_BORDERED_RINGS, IMG_SQUARE_RINGS)) {
1866                 qtcCalcRingAlphas(&qtSettings.colors[PAL_ACTIVE][COLOR_WINDOW]);
1867             }
1868 
1869             if (isMozilla())
1870                 opts.crSize = CR_SMALL_SIZE;
1871 
1872             if (opts.crSize != CR_LARGE_SIZE) {
1873                 constStrFormat =
1874                     "style \"" RC_SETTING "CRSize\" "
1875                     "{ GtkCheckButton::indicator_size = %d }"
1876                     " class \"*\" style \"" RC_SETTING "CRSize\" ";
1877                 tmpStr = (char*)realloc(tmpStr, strlen(constStrFormat) + 16);
1878                 sprintf(tmpStr, constStrFormat, opts.crSize);
1879                 gtk_rc_parse_string(tmpStr);
1880             }
1881 
1882 #if 0
1883 // Remove because, in KDE4 at least, if have two locked toolbars together then the last/first items are too close
1884             if(TB_NONE==opts.toolbarBorders)
1885                 gtk_rc_parse_string("style \"" RC_SETTING "TbB\" { xthickness = 0 ythickness = 0 GtkToolbar::internal-padding = 0 }"
1886                                     " widget_class \"*<GtkToolbar>\" style  \"" RC_SETTING "TbB\"");
1887 #endif
1888 
1889             if(TBTN_RAISED==opts.tbarBtns || TBTN_JOINED==opts.tbarBtns)
1890                 gtk_rc_parse_string("style \"" RC_SETTING "TbJ\" { GtkToolbar::button-relief = 1 } "
1891                                     "widget_class \"*<GtkToolbar>\"  style \"" RC_SETTING "TbJ\"");
1892 
1893             free(tmpStr);
1894 
1895             if(opts.shadeMenubarOnlyWhenActive && SHADE_WINDOW_BORDER==opts.shadeMenubars &&
1896                EQUAL_COLOR(qtSettings.colors[PAL_ACTIVE][COLOR_WINDOW_BORDER], qtSettings.colors[PAL_INACTIVE][COLOR_WINDOW_BORDER]))
1897                 opts.shadeMenubarOnlyWhenActive=false;
1898 
1899             if (!(opts.square&SQUARE_POPUP_MENUS) || !(opts.square&SQUARE_TOOLTIPS))
1900             {
1901                 readKwinrc();
1902             }
1903             setlocale(LC_NUMERIC, locale);
1904         }
1905         return true;
1906     }
1907     return false;
1908 }
1909 
1910 #if 0
1911 static void qtSettingsExit()
1912 {
1913     qt_refs--;
1914     if (!qt_refs) {
1915         for(int i = 0;i < FONT_NUM_TOTAL;++i) {
1916             free(qtSettings.fonts[i]);
1917             qtSettings.fonts[i] = nullptr;
1918         }
1919         free(qtSettings.icons);
1920         qtSettings.icons = nullptr;
1921     }
1922 }
1923 #endif
1924 
1925 #define SET_COLOR_PAL(st, rc, itm, ITEM, state, QTP_COL, PAL, USE_DIS) \
1926     st->itm[state]=rc->color_flags[state]&ITEM \
1927         ? rc->itm[state] \
1928         : qtSettings.colors[state==GTK_STATE_INSENSITIVE && USE_DIS\
1929                                 ? PAL_DISABLED \
1930                                 : PAL ][QTP_COL];
1931 
1932 #define SET_COLOR_PAL_ACT(st, rc, itm, ITEM, state, QTP_COL) \
1933     st->itm[state]=rc->color_flags[state]&ITEM \
1934         ? rc->itm[state] \
1935         : qtSettings.colors[PAL_ACTIVE][QTP_COL];
1936 
1937 #define SET_COLOR_X(st, rc, itm, ITEM, state, QTP_COL, USE_DIS) \
1938     SET_COLOR_PAL(st, rc, itm, ITEM, state, QTP_COL, PAL_ACTIVE, USE_DIS)
1939 
1940 #define SET_COLOR(st, rc, itm, ITEM, state, QTP_COL) \
1941     SET_COLOR_PAL(st, rc, itm, ITEM, state, QTP_COL, PAL_ACTIVE, true)
1942 
qtSettingsSetColors(GtkStyle * style,GtkRcStyle * rc_style)1943 void qtSettingsSetColors(GtkStyle *style, GtkRcStyle *rc_style)
1944 {
1945     SET_COLOR(style, rc_style, bg, GTK_RC_BG, GTK_STATE_NORMAL, COLOR_WINDOW)
1946     SET_COLOR(style, rc_style, bg, GTK_RC_BG, GTK_STATE_SELECTED, COLOR_SELECTED)
1947     SET_COLOR_X(style, rc_style, bg, GTK_RC_BG, GTK_STATE_INSENSITIVE, COLOR_WINDOW, false)
1948     SET_COLOR(style, rc_style, bg, GTK_RC_BG, GTK_STATE_ACTIVE, COLOR_MID)
1949     SET_COLOR(style, rc_style, bg, GTK_RC_BG, GTK_STATE_PRELIGHT, COLOR_WINDOW)
1950 
1951     SET_COLOR(style, rc_style, base, GTK_RC_BASE, GTK_STATE_NORMAL, COLOR_BACKGROUND)
1952     SET_COLOR(style, rc_style, base, GTK_RC_BASE, GTK_STATE_SELECTED, COLOR_SELECTED)
1953     SET_COLOR_PAL_ACT(style, rc_style, base, GTK_RC_BASE, GTK_STATE_INSENSITIVE, COLOR_WINDOW)
1954     SET_COLOR(style, rc_style, base, GTK_RC_BASE, GTK_STATE_ACTIVE, COLOR_SELECTED)
1955     if(qtSettings.inactiveChangeSelectionColor)
1956         style->base[GTK_STATE_ACTIVE]=qtSettings.colors[PAL_INACTIVE][COLOR_SELECTED];
1957     SET_COLOR(style, rc_style, base, GTK_RC_BASE, GTK_STATE_PRELIGHT, COLOR_BACKGROUND)
1958 
1959     SET_COLOR(style, rc_style, text, GTK_RC_TEXT, GTK_STATE_NORMAL, COLOR_TEXT)
1960     SET_COLOR(style, rc_style, text, GTK_RC_TEXT, GTK_STATE_SELECTED, COLOR_TEXT_SELECTED)
1961     SET_COLOR(style, rc_style, text, GTK_RC_TEXT, GTK_STATE_INSENSITIVE, COLOR_TEXT)
1962     SET_COLOR(style, rc_style, text, GTK_RC_TEXT, GTK_STATE_ACTIVE, COLOR_TEXT_SELECTED)
1963 
1964 //     if(opts.inactiveHighlight)
1965 //         SET_COLOR(style, rc_style, text, GTK_RC_TEXT, GTK_STATE_ACTIVE, COLOR_TEXT)
1966 //     else
1967 //         SET_COLOR_PAL(style, rc_style, text, GTK_RC_TEXT, GTK_STATE_ACTIVE, COLOR_TEXT_SELECTED, PAL_INACTIVE)
1968 
1969     SET_COLOR(style, rc_style, text, GTK_RC_TEXT, GTK_STATE_PRELIGHT, COLOR_TEXT)
1970 
1971     SET_COLOR(style, rc_style, fg, GTK_RC_FG, GTK_STATE_NORMAL, COLOR_WINDOW_TEXT)
1972     SET_COLOR(style, rc_style, fg, GTK_RC_FG, GTK_STATE_SELECTED, COLOR_TEXT_SELECTED)
1973 //     if (isMozilla())
1974         SET_COLOR(style, rc_style, fg, GTK_RC_FG, GTK_STATE_INSENSITIVE, COLOR_TEXT)
1975 //     else
1976 //         SET_COLOR(style, rc_style, fg, GTK_RC_FG, GTK_STATE_INSENSITIVE, COLOR_MID)
1977     SET_COLOR(style, rc_style, fg, GTK_RC_FG, GTK_STATE_ACTIVE, COLOR_WINDOW_TEXT)
1978     SET_COLOR(style, rc_style, fg, GTK_RC_FG, GTK_STATE_PRELIGHT, COLOR_WINDOW_TEXT)
1979 }
1980 
1981 }
1982