1 /*
2 * Copyright (c) 2003 Sasha Vasko <sasha at aftercode.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 *
18 */
19
20 #define LOCAL_DEBUG
21
22 #include "../configure.h"
23 #include "../libAfterStep/asapp.h"
24 #include "../libAfterStep/afterstep.h"
25 #include "../libAfterStep/parser.h"
26 #include "../libAfterStep/colorscheme.h"
27 #include "../libAfterStep/session.h"
28 #include "../libAfterStep/screen.h"
29 #include "../libAfterStep/kde.h"
30 #include "../libAfterBase/xml.h"
31
32 #include <unistd.h>
33
34 #include "afterconf.h"
35
36
37 /*****************************************************************************
38 *
39 * This routine is responsible for reading and parsing the colors config
40 * file
41 *
42 ****************************************************************************/
43 #define COLOR_TERM(n,len) {TF_NO_MYNAME_PREPENDING, #n, len, TT_COLOR, COLOR_##n##_ID , NULL}
44
45 TermDef ColorTerms[] = {
46 COLOR_TERM (Base, 4),
47 COLOR_TERM (Inactive1, 9),
48 COLOR_TERM (Inactive2, 9),
49 COLOR_TERM (Active, 6),
50 COLOR_TERM (InactiveText1, 13),
51 COLOR_TERM (InactiveText2, 13),
52 COLOR_TERM (ActiveText, 10),
53 COLOR_TERM (HighInactive, 12),
54 COLOR_TERM (HighActive, 10),
55 COLOR_TERM (HighInactiveBack, 16),
56 COLOR_TERM (HighActiveBack, 14),
57 COLOR_TERM (HighInactiveText, 16),
58 COLOR_TERM (HighActiveText, 14),
59 COLOR_TERM (DisabledText, 12),
60 COLOR_TERM (BaseDark, 8),
61 COLOR_TERM (BaseLight, 9),
62 COLOR_TERM (Inactive1Dark, 13),
63 COLOR_TERM (Inactive1Light, 14),
64 COLOR_TERM (Inactive2Dark, 13),
65 COLOR_TERM (Inactive2Light, 14),
66 COLOR_TERM (ActiveDark, 10),
67 COLOR_TERM (ActiveLight, 11),
68 COLOR_TERM (HighInactiveDark, 16),
69 COLOR_TERM (HighInactiveLight, 17),
70 COLOR_TERM (HighActiveDark, 14),
71 COLOR_TERM (HighActiveLight, 15),
72 COLOR_TERM (HighInactiveBackDark, 20),
73 COLOR_TERM (HighInactiveBackLight, 21),
74 COLOR_TERM (HighActiveBackDark, 24),
75 COLOR_TERM (HighActiveBackLight, 25),
76 COLOR_TERM (Cursor, 7),
77 {TF_NO_MYNAME_PREPENDING, "Angle", 5, TT_UINTEGER, COLOR_Angle_ID, NULL}
78 ,
79
80 {0, NULL, 0, 0, 0}
81 };
82
83
84 SyntaxDef ColorSyntax = {
85 '\n',
86 '\0',
87 ColorTerms,
88 0, /* use default hash size */
89 ' ',
90 "",
91 "\t",
92 "Custom Color Scheme",
93 "ColorScheme",
94 "defines color values for standard set of internal color names, to be used in other configuration files",
95 NULL,
96 0
97 };
98
CreateColorConfig()99 ColorConfig *CreateColorConfig ()
100 {
101 return safecalloc (1, sizeof (ColorConfig));
102 }
103
DestroyColorConfig(ColorConfig * config)104 void DestroyColorConfig (ColorConfig * config)
105 {
106 if (config) {
107 DestroyFreeStorage (&(config->more_stuff));
108 free (config);
109 }
110 }
111
112
PrintColorConfig(ColorConfig * config)113 void PrintColorConfig (ColorConfig * config)
114 {
115 }
116
ParseColorOptions(const char * filename,char * myname)117 ColorConfig *ParseColorOptions (const char *filename, char *myname)
118 {
119 ColorConfig *config = CreateColorConfig ();
120 FreeStorageElem *Storage = NULL, *pCurr;
121 ConfigItem item;
122
123 Storage =
124 file2free_storage (filename, myname, &ColorSyntax, NULL,
125 &(config->more_stuff));
126 if (Storage == NULL)
127 return config;
128
129 item.memory = NULL;
130
131 LOCAL_DEBUG_OUT ("Storage = %p", Storage);
132
133 for (pCurr = Storage; pCurr; pCurr = pCurr->next) {
134 int index;
135
136 LOCAL_DEBUG_OUT ("pCurr = %p", pCurr);
137 if (pCurr->term == NULL)
138 continue;
139 if (!ReadConfigItem (&item, pCurr))
140 continue;
141 index = pCurr->term->id - COLOR_ID_START;
142 LOCAL_DEBUG_OUT ("id %d, index = %d", pCurr->term->id, index);
143 if (index >= 0 && index < ASMC_MainColors) {
144 LOCAL_DEBUG_OUT ("index %d is \"%s\"", index, item.data.string);
145 if (parse_argb_color
146 (item.data.string,
147 &(config->main_colors[index])) != item.data.string) {
148 LOCAL_DEBUG_OUT ("Parsed color %d as #%8.8lX", index,
149 (unsigned long)config->main_colors[index]);
150 set_flags (config->set_main_colors, (0x01 << index));
151 }
152 } else if (pCurr->term->id == COLOR_Angle_ID) {
153 config->angle = item.data.integer;
154 set_flags (config->set_main_colors, COLOR_Angle);
155 }
156 item.ok_to_free = 1;
157 }
158 ReadConfigItem (&item, NULL);
159
160 DestroyFreeStorage (&Storage);
161 return config;
162 }
163
164 /* returns:
165 * 0 on success
166 * 1 if data is empty
167 * 2 if ConfigWriter cannot be initialized
168 *
169 */
170 int
WriteColorOptions(const char * filename,char * myname,ColorConfig * config,unsigned long flags)171 WriteColorOptions (const char *filename, char *myname,
172 ColorConfig * config, unsigned long flags)
173 {
174 ConfigDef *ColorConfigWriter = NULL;
175 FreeStorageElem *Storage = NULL, **tail = &Storage;
176 ConfigData cd;
177
178 char color_buffer[128];
179 int i;
180
181 if (config == NULL)
182 return 1;
183 cd.filename = filename;
184 if ((ColorConfigWriter =
185 InitConfigWriter (myname, &ColorSyntax, CDT_Filename, cd)) == NULL)
186 return 2;
187
188 CopyFreeStorage (&Storage, config->more_stuff);
189
190 /* building free storage here */
191 LOCAL_DEBUG_OUT ("0x%lX", config->set_main_colors);
192 for (i = 0; i < ASMC_MainColors; ++i) {
193 ARGB32 c = config->main_colors[i];
194 CARD32 a, r, g, b, h, s, v;
195 char *tmp[1];
196 FreeStorageElem **pelem;
197
198 a = ARGB32_ALPHA8 (c);
199 r = ARGB32_RED16 (c);
200 g = ARGB32_GREEN16 (c);
201 b = ARGB32_BLUE16 (c);
202 h = rgb2hsv (r, g, b, &s, &v);
203 h = hue162degrees (h);
204 s = val162percent (s);
205 v = val162percent (v);
206 r = r >> 8;
207 g = g >> 8;
208 b = b >> 8;
209 tmp[0] = &(color_buffer[0]);
210 sprintf (color_buffer,
211 "#%2.2lX%2.2lX%2.2lX%2.2lX \t\t# or ahsv(%ld,%ld,%ld,%ld) or argb(%ld,%ld,%ld,%ld)",
212 (unsigned long)a, (unsigned long)r, (unsigned long)g,
213 (unsigned long)b, (long)a, (long)h, (long)s, (long)v, (long)a,
214 (long)r, (long)g, (long)b);
215 pelem = tail;
216 LOCAL_DEBUG_OUT ("tail = %p", tail);
217 tail =
218 Strings2FreeStorage (&ColorSyntax, tail, &(tmp[0]), 1,
219 COLOR_ID_START + i);
220
221 LOCAL_DEBUG_OUT ("i = %d, tail = %p, *pelem = %p", i, tail, pelem);
222 if (*pelem && !get_flags (config->set_main_colors, 0x01 << i)
223 && i != ASMC_Base)
224 set_flags ((*pelem)->flags, CF_DISABLED_OPTION);
225 }
226
227 /* colorscheme angle */
228 if (get_flags (config->set_main_colors, COLOR_Angle))
229 tail =
230 Integer2FreeStorage (&ColorSyntax, tail, NULL, config->angle,
231 COLOR_Angle_ID);
232
233 /* writing config into the file */
234 cd.filename = filename;
235 WriteConfig (ColorConfigWriter, Storage, CDT_Filename, &cd, flags);
236 DestroyFreeStorage (&Storage);
237 DestroyConfig (ColorConfigWriter);
238
239 if (Storage) {
240 fprintf (stderr,
241 "\n%s:Config Writing warning: Not all Free Storage discarded! Trying again...",
242 myname);
243 DestroyFreeStorage (&Storage);
244 fprintf (stderr, (Storage != NULL) ? " failed." : " success.");
245 }
246 return 0;
247 }
248
ASColorScheme2ColorConfig(ASColorScheme * cs)249 ColorConfig *ASColorScheme2ColorConfig (ASColorScheme * cs)
250 {
251 ColorConfig *config = NULL;
252
253 if (cs) {
254 int i;
255
256 config = CreateColorConfig ();
257 config->angle = cs->angle;
258 for (i = 0; i < ASMC_MainColors; ++i)
259 config->main_colors[i] = cs->main_colors[i];
260 config->set_main_colors = cs->set_main_colors;
261 }
262 return config;
263 }
264
ColorConfig2ASColorScheme(ColorConfig * config)265 ASColorScheme *ColorConfig2ASColorScheme (ColorConfig * config)
266 {
267 ASColorScheme *cs = NULL;
268
269 if (config) {
270 int i;
271 int angle = ASCS_DEFAULT_ANGLE;
272
273 if (get_flags (config->set_main_colors, COLOR_Angle))
274 angle = config->angle;
275 cs = make_ascolor_scheme (config->main_colors[ASMC_Base], angle);
276 for (i = 0; i < ASMC_MainColors; ++i)
277 if (i != ASMC_Base
278 && get_flags (config->set_main_colors, (0x01 << i)))
279 cs->main_colors[i] = config->main_colors[i];
280
281 for (i = 0; i < ASMC_MainColors; ++i)
282 make_color_scheme_hsv (cs->main_colors[i], &(cs->main_hues[i]),
283 &(cs->main_saturations[i]),
284 &(cs->main_values[i]));
285
286 cs->set_main_colors = config->set_main_colors;
287 }
288 return cs;
289 }
290
LoadColorScheme()291 void LoadColorScheme ()
292 {
293 ASColorScheme *cs = NULL;
294 const char *const_configfile;
295
296 /* first we need to load the colorscheme */
297 if ((const_configfile =
298 get_session_file (Session, get_screen_current_desk (NULL),
299 F_CHANGE_COLORSCHEME, False)) != NULL) {
300 ColorConfig *config = ParseColorOptions (const_configfile, MyName);
301
302 if (config) {
303 cs = ColorConfig2ASColorScheme (config);
304 DestroyColorConfig (config);
305 show_progress ("COLORSCHEME loaded from \"%s\" ...",
306 const_configfile);
307 } else
308 show_progress
309 ("COLORSCHEME file format is unrecognizeable in \"%s\" ...",
310 const_configfile);
311
312 } else
313 show_warning ("COLORSCHEME is not set");
314
315 if (cs == NULL)
316 cs = make_default_ascolor_scheme ();
317
318 populate_ascs_colors_rgb (cs);
319 populate_ascs_colors_xml (cs);
320 free (cs);
321 }
322
323 Bool
translate_gtkrc_template_file(const char * template_fname,const char * output_fname)324 translate_gtkrc_template_file (const char *template_fname,
325 const char *output_fname)
326 {
327 static char buffer[MAXLINELENGTH];
328 FILE *src_fp = NULL, *dst_fp = NULL;
329 int good_strings = 0;
330
331 if (template_fname == NULL || output_fname == NULL)
332 return False;;
333
334 src_fp = fopen (template_fname, "r");
335 dst_fp = fopen (output_fname, "w");
336 if (dst_fp == NULL)
337 show_warning ("Failed to open file \"%s\" for writing", output_fname);
338 if (src_fp != NULL && dst_fp != NULL) {
339 while (fgets (&buffer[0], MAXLINELENGTH, src_fp)) {
340 int i = 0;
341
342 while (isspace (buffer[i]))
343 ++i;
344 if (buffer[i] != '\n' && buffer[i] != '#' && buffer[i] != '\0'
345 && buffer[i] != '\r') {
346 ++good_strings;
347 if (strncmp (&buffer[i], "fg[", 3) == 0 ||
348 strncmp (&buffer[i], "bg[", 3) == 0 ||
349 strncmp (&buffer[i], "text[", 5) == 0 ||
350 strncmp (&buffer[i], "base[", 5) == 0 ||
351 strncmp (&buffer[i], "light[", 6) == 0 ||
352 strncmp (&buffer[i], "dark[", 5) == 0
353 || strncmp (&buffer[i], "mid[", 4) == 0) {
354 while (buffer[i] != '\0' && buffer[i] != '\"'
355 && buffer[i] != '\{')
356 ++i;
357 if (buffer[i] == '\"') {
358 char *token = &buffer[i + 1];
359
360 if (isalpha (token[0])) {
361 int len = 0;
362
363 while (token[len] != '\0' && token[len] != '\"')
364 ++len;
365 if (token[len] == '\"' && len > 0) {
366 ARGB32 argb;
367
368 if (parse_argb_color (token, &argb) != token) {
369 fwrite (&(buffer[0]), 1, i + 1, dst_fp);
370 fprintf (dst_fp, "#%2.2lX%2.2lX%2.2lX",
371 (unsigned long)ARGB32_RED8 (argb),
372 (unsigned long)ARGB32_GREEN8 (argb),
373 (unsigned long)ARGB32_BLUE8 (argb));
374 fwrite (&(token[len]), 1, strlen (&(token[len])),
375 dst_fp);
376 continue;
377 }
378 }
379 }
380 }
381 }
382 }
383 fwrite (&buffer[0], 1, strlen (&buffer[0]), dst_fp);
384 }
385
386 }
387 if (src_fp)
388 fclose (src_fp);
389 if (dst_fp)
390 fclose (dst_fp);
391 return (good_strings > 0);
392 }
393
394 Bool
translate_kcsrc_template_file(const char * template_fname,const char * output_fname)395 translate_kcsrc_template_file (const char *template_fname,
396 const char *output_fname)
397 {
398 /* this prolly needs to be rewritten using libAfterBase/kde.c code : */
399 int good_strings = 0;
400 xml_elem_t *KDE_cs, *group;
401
402 if (template_fname == NULL || output_fname == NULL)
403 return False;;
404
405 KDE_cs = load_KDE_config (template_fname);
406 for (group = KDE_cs->child; group != NULL; group = group->next) {
407 xml_elem_t *item;
408
409 for (item = group->child; item != NULL; item = item->next)
410 if (item->tag_id == KDEConfig_item && IsTagCDATA (item->child)) {
411 char *parm = item->child->parm;
412
413 ++good_strings;
414 if (*parm == '\"') {
415 ARGB32 argb;
416
417 ++parm;
418 if (parse_argb_color (parm, &argb) != parm) {
419 char *tmp = safemalloc (32);
420
421 sprintf (tmp, "%ld,%ld,%ld", (unsigned long)ARGB32_RED8 (argb),
422 (unsigned long)ARGB32_GREEN8 (argb),
423 (unsigned long)ARGB32_BLUE8 (argb));
424 free (item->child->parm);
425 item->child->parm = tmp;
426 }
427 }
428 }
429 }
430 save_KDE_config (output_fname, KDE_cs);
431 xml_elem_delete (NULL, KDE_cs);
432
433 return (good_strings > 0);
434 }
435
436
UpdateGtkRC(ASEnvironment * e)437 Bool UpdateGtkRC (ASEnvironment * e)
438 {
439 Bool result = False;
440 char *src;
441
442 /* first we need to load the colorscheme */
443 if (e == NULL)
444 return False;
445 if (e->gtkrc_path != NULL && strcmp (e->gtkrc_path, "/dev/null") != 0) {
446 src = make_session_file (Session, GTKRC_TEMPLATE_FILE, False);
447 if (src)
448 result = translate_gtkrc_template_file (src, e->gtkrc_path);
449
450 destroy_string (&src);
451 }
452
453 if (e->gtkrc20_path != NULL
454 && strcmp (e->gtkrc20_path, "/dev/null") != 0) {
455 src = make_session_file (Session, GTKRC20_TEMPLATE_FILE, False);
456 /* first we need to load the colorscheme */
457 if (src)
458 if (translate_gtkrc_template_file (src, e->gtkrc20_path))
459 result = True;
460 destroy_string (&src);
461 }
462 return result;
463 }
464
465 static Bool
SetKDEGlobalsColorScheme(const char * new_cs_file,const char * cs_name)466 SetKDEGlobalsColorScheme (const char *new_cs_file, const char *cs_name)
467 {
468 char *kdeglobals_fname = copy_replace_envvar (KDEGLOBALS_FILE);
469 xml_elem_t *KDE_cs = load_KDE_config (new_cs_file);
470 xml_elem_t *KDE_globals = load_KDE_config (kdeglobals_fname);
471 xml_elem_t *KDE_group = get_KDE_config_group (KDE_globals, "KDE", True);
472 xml_elem_t *CS_group =
473 get_KDE_config_group (KDE_cs, "Color Scheme", False);
474
475 if (CS_group) {
476 xml_elem_t *WM_group = get_KDE_config_group (KDE_globals, "WM", True);
477 xml_elem_t *General_group =
478 get_KDE_config_group (KDE_globals, "General", True);
479
480 merge_KDE_config_groups (CS_group, WM_group);
481 merge_KDE_config_groups (CS_group, General_group);
482 }
483
484 set_KDE_config_group_item (KDE_group, "colorScheme",
485 cs_name ? cs_name : new_cs_file);
486
487 save_KDE_config (kdeglobals_fname, KDE_globals);
488 xml_elem_delete (NULL, KDE_globals);
489 xml_elem_delete (NULL, KDE_cs);
490
491 free (kdeglobals_fname);
492
493 add_KDE_colorscheme (new_cs_file);
494 return (CS_group != NULL);
495 }
496
UpdateKCSRC()497 Bool UpdateKCSRC ()
498 {
499 Bool result = False;
500 char *src = make_session_file (Session, KSCRC_TEMPLATE_FILE, False);
501 char *dst = make_session_rc_file (Session, KCSRC_FILE);
502
503 /* first we need to load the colorscheme */
504 if (src && dst)
505 result = translate_kcsrc_template_file (src, dst);
506
507 if (result) {
508 char *cs_filename = dst;
509 char *kcs_path = copy_replace_envvar (KDECS_DIR);
510
511 if (CheckDir (kcs_path) == 0) {
512 char *fullcs_filename;
513
514 cs_filename = mystrdup (AS_KCSRC_FILE);
515 fullcs_filename = make_file_name (kcs_path, cs_filename);
516 CopyFile (dst, fullcs_filename);
517 free (fullcs_filename);
518 }
519 free (kcs_path);
520
521 if (!SetKDEGlobalsColorScheme (dst, cs_filename))
522 result = False;
523 if (cs_filename != dst)
524 free (cs_filename);
525 }
526 destroy_string (&src);
527 destroy_string (&dst);
528
529 return result;
530 }
531
532
533 #if 0
534 /* relevant KDE code for reference : */
535
536 void KColorScheme::load ()
537 {
538 KConfig *config = KGlobal::config ();
539
540 config->setGroup ("KDE");
541 QString currentScheme = config->readEntry ("colorScheme");
542
543 QString currentSchemeSearch =
544 currentScheme.left (currentScheme.length () -
545 QString (".kcsrc").length ());
546
547 if (SchemeListItem * item = findSchemeListItem (currentSchemeSearch)) {
548 item->setSelected (true);
549 m_ui->schemeList->setCurrentItem (item);
550 m_ui->schemeList->ensureItemVisible (item);
551 }
552 m_currentScheme->setInheritedScheme (currentSchemeSearch);
553 currentSchemeChanged ();
554
555 KConfig cfg ("kcmdisplayrc", true, false);
556
557 cfg.setGroup ("X11");
558 bool exportColors = cfg.readBoolEntry ("exportKDEColors", true);
559
560 m_ui->exportColorsCB->setChecked (exportColors);
561
562 emit changed (false);
563 }
564
565
566
567
568 void KColorScheme::save ()
569 {
570 // apply the current scheme data
571 if (m_selectedScheme && m_currentScheme) {
572 KConfig *c = KGlobal::config ();
573
574 writeSchemeConfig (c, "General", "WM", "KDE", *m_currentScheme);
575 // this also translates into :
576 KConfig *cfg = KGlobal::config ();
577
578 cfg->setGroup ("General");
579 cfg->writeEntry ("background", cs->back, true, true);
580 cfg->writeEntry ("selectBackground", cs->select, true, true);
581 cfg->writeEntry ("foreground", cs->txt, true, true);
582 cfg->writeEntry ("windowForeground", cs->windowTxt, true, true);
583 cfg->writeEntry ("windowBackground", cs->window, true, true);
584 cfg->writeEntry ("selectForeground", cs->selectTxt, true, true);
585 cfg->writeEntry ("buttonBackground", cs->button, true, true);
586 cfg->writeEntry ("buttonForeground", cs->buttonTxt, true, true);
587
588 cfg->setGroup ("WM");
589 cfg->writeEntry ("activeForeground", cs->aTxt, true, true);
590 cfg->writeEntry ("inactiveBackground", cs->iaTitle, true, true);
591 cfg->writeEntry ("inactiveBlend", cs->iaBlend, true, true);
592 cfg->writeEntry ("activeBackground", cs->aTitle, true, true);
593 cfg->writeEntry ("activeBlend", cs->aBlend, true, true);
594 cfg->writeEntry ("inactiveForeground", cs->iaTxt, true, true);
595 cfg->writeEntry ("activeTitleBtnFg", cs->aTitleBtn, true, true);
596 cfg->writeEntry ("inactiveTitleBtnFg", cs->iTitleBtn, true, true);
597 cfg->writeEntry ("activeTitleBtnBg", cs->aTitleBtnBack, true, true);
598 cfg->writeEntry ("inactiveTitleBtnBg", cs->iTitleBtnBack, true, true);
599 if (cs->aTitleBtnBlend != cs->aTitleBtnBack)
600 cfg->writeEntry ("activeTitleBtnBlend", cs->aTitleBtnBlend, true,
601 true);
602 else
603 cfg->writeEntry ("activeTitleBtnBlend", "", true, true);
604 if (cs->iTitleBtnBlend != cs->iTitleBtnBack)
605 cfg->writeEntry ("inactiveTitleBtnBlend", cs->iTitleBtnBlend, true,
606 true);
607 else
608 cfg->writeEntry ("inactiveTitleBtnBlend", "", true, true);
609
610 cfg->setGroup ("KDE");
611 cfg->writeEntry ("contrast", cs->contrast, true, true);
612 cfg->sync ();
613
614 c->writeEntry ("colorScheme",
615 QString ("%1.kcsrc").arg (m_selectedScheme->
616 visibleName ()), true, true);
617 c->sync ();
618
619 // KDE-1.x support
620 KSimpleConfig *c2 =
621 new KSimpleConfig (QDir::homeDirPath () + "/.kderc");
622
623 c2->setGroup ("General");
624 write (c2, CS_StandardBackground, *m_currentScheme);
625 write (c2, CS_SelecedBackground, *m_currentScheme);
626 write (c2, CS_Text, *m_currentScheme);
627 write (c2, CS_StandardText, *m_currentScheme);
628 write (c2, CS_Background, *m_currentScheme);
629 write (c2, CS_SelectedText, *m_currentScheme);
630 c2->sync ();
631 delete c2;
632 }
633
634 KConfig cfg2 ("kcmdisplayrc", false, false);
635
636 cfg2.setGroup ("X11");
637 bool exportColors = m_ui->exportColorsCB->isChecked ();
638
639 cfg2.writeEntry ("exportKDEColors", exportColors);
640 cfg2.sync ();
641 QApplication::syncX ();
642
643 // Notify all qt-only apps of the KDE palette changes
644 uint flags = KRdbExportQtColors;
645
646 if (exportColors)
647 flags |= KRdbExportColors;
648 else {
649 #if defined Q_WS_X11 && !defined K_WS_QTONLY
650 // Undo the property xrdb has placed on the root window (if any),
651 // i.e. remove all entries, including ours
652 XDeleteProperty (qt_xdisplay (), qt_xrootwin (), XA_RESOURCE_MANAGER);
653 #endif
654 }
655 runRdb (flags); // Save the palette to qtrc for KStyles
656
657 // Notify all KDE applications
658 KIPC::sendMessageAll (KIPC::PaletteChanged);
659
660 emit changed (false);
661 }
662
663 void runRdb (uint flags)
664 {
665 // Obtain the application palette that is about to be set.
666 QPalette newPal = KApplication::createApplicationPalette ();
667 bool exportColors = flags & KRdbExportColors;
668 bool exportQtColors = flags & KRdbExportQtColors;
669 bool exportQtSettings = flags & KRdbExportQtSettings;
670 bool exportXftSettings = flags & KRdbExportXftSettings;
671
672 KConfig kglobals ("kdeglobals", true, false);
673
674 kglobals.setGroup ("KDE");
675
676 KTempFile tmpFile;
677
678 if (tmpFile.status () != 0) {
679 kdDebug () << "Couldn't open temp file" << endl;
680 exit (0);
681 }
682
683 QFile & tmp = *(tmpFile.file ());
684
685 // Export colors to non-(KDE/Qt) apps (e.g. Motif, GTK+ apps)
686 if (exportColors) {
687 KGlobal::dirs ()->addResourceType ("appdefaults",
688 KStandardDirs::
689 kde_default ("data") +
690 "kdisplay/app-defaults/");
691 QColorGroup cg = newPal.active ();
692
693 KGlobal::locale ()->insertCatalogue ("krdb");
694 createGtkrc (true, cg, 1);
695 createGtkrc (true, cg, 2);
696
697 QString preproc;
698 QColor backCol = cg.background ();
699
700 addColorDef (preproc, "FOREGROUND", cg.foreground ());
701 addColorDef (preproc, "BACKGROUND", backCol);
702 addColorDef (preproc, "HIGHLIGHT",
703 backCol.light (100 +
704 (2 * KGlobalSettings::contrast () +
705 4) * 16 / 1));
706 addColorDef (preproc, "LOWLIGHT",
707 backCol.dark (100 +
708 (2 * KGlobalSettings::contrast () +
709 4) * 10));
710 addColorDef (preproc, "SELECT_BACKGROUND", cg.highlight ());
711 addColorDef (preproc, "SELECT_FOREGROUND", cg.highlightedText ());
712 addColorDef (preproc, "WINDOW_BACKGROUND", cg.base ());
713 addColorDef (preproc, "WINDOW_FOREGROUND", cg.foreground ());
714 addColorDef (preproc, "INACTIVE_BACKGROUND",
715 KGlobalSettings::inactiveTitleColor ());
716 addColorDef (preproc, "INACTIVE_FOREGROUND",
717 KGlobalSettings::inactiveTitleColor ());
718 addColorDef (preproc, "ACTIVE_BACKGROUND",
719 KGlobalSettings::activeTitleColor ());
720 addColorDef (preproc, "ACTIVE_FOREGROUND",
721 KGlobalSettings::activeTitleColor ());
722 //---------------------------------------------------------------
723
724 tmp.writeBlock (preproc.latin1 (), preproc.length ());
725
726 QStringList list;
727
728 QStringList adPaths = KGlobal::dirs ()->findDirs ("appdefaults", "");
729
730 for (QStringList::ConstIterator it = adPaths.begin ();
731 it != adPaths.end (); ++it) {
732 QDir dSys (*it);
733
734 if (dSys.exists ()) {
735 dSys.setFilter (QDir::Files);
736 dSys.setSorting (QDir::Name);
737 dSys.setNameFilter ("*.ad");
738 list += dSys.entryList ();
739 }
740 }
741
742 for (QStringList::ConstIterator it = list.begin (); it != list.end ();
743 it++)
744 copyFile (tmp, locate ("appdefaults", *it), true);
745 }
746 // Merge ~/.Xresources or fallback to ~/.Xdefaults
747 QString homeDir = QDir::homeDirPath ();
748 QString xResources = homeDir + "/.Xresources";
749
750 // very primitive support for ~/.Xresources by appending it
751 if (QFile::exists (xResources))
752 copyFile (tmp, xResources, true);
753 else
754 copyFile (tmp, homeDir + "/.Xdefaults", true);
755
756 // Export the Xcursor theme & size settings
757 QString theme = kglobals.readEntry ("cursorTheme", QString ());
758 QString size = kglobals.readEntry ("cursorSize", QString ());
759 QString contents;
760
761 if (!theme.isNull ())
762 contents = "Xcursor.theme: " + theme + '\n';
763
764 if (!size.isNull ())
765 contents += "Xcursor.size: " + size + '\n';
766
767 if (exportXftSettings) {
768 kglobals.setGroup ("General");
769
770 QString hintStyle (kglobals.readEntry ("XftHintStyle", "hintmedium")),
771 subPixel (kglobals.readEntry ("XftSubPixel"));
772
773 contents += "Xft.antialias: ";
774 if (QSettings ().readBoolEntry ("/qt/useXft"))
775 contents += "1";
776 else
777 contents += "0";
778
779 contents += "\nXft.hinting: ";
780 if (hintStyle.isEmpty ())
781 contents += "-1";
782 else {
783 if (hintStyle != "hintnone")
784 contents += "1";
785 else
786 contents += "0";
787 contents += "\nXft.hintstyle: " + hintStyle + '\n';
788 }
789 if (!subPixel.isEmpty ())
790 contents += "Xft.rgba: " + subPixel + '\n';
791 }
792
793 if (contents.length () > 0)
794 tmp.writeBlock (contents.latin1 (), contents.length ());
795
796 tmpFile.close ();
797
798 KProcess proc;
799
800 #ifndef NDEBUG
801 proc << "xrdb" << "-merge" << tmpFile.name ();
802 #else
803 proc << "xrdb" << "-quiet" << "-merge" << tmpFile.name ();
804 #endif
805 proc.start (KProcess::Block, KProcess::Stdin);
806
807 tmpFile.unlink ();
808
809 applyGtkStyles (exportColors, 1);
810 applyGtkStyles (exportColors, 2);
811
812 /* Qt exports */
813 if (exportQtColors || exportQtSettings) {
814 QSettings *settings = new QSettings;
815
816 if (exportQtColors)
817 applyQtColors (kglobals, *settings, newPal); // For kcmcolors
818
819 if (exportQtSettings)
820 applyQtSettings (kglobals, *settings); // For kcmstyle
821
822 delete settings;
823
824 QApplication::flushX ();
825
826 // We let KIPC take care of ourselves, as we are in a KDE app with
827 // QApp::setDesktopSettingsAware(false);
828 // Instead of calling QApp::x11_apply_settings() directly, we instead
829 // modify the timestamp which propagates the settings changes onto
830 // Qt-only apps without adversely affecting ourselves.
831
832 // Cheat and use the current timestamp, since we just saved to qtrc.
833 QDateTime settingsstamp = QDateTime::currentDateTime ();
834
835 static Atom qt_settings_timestamp = 0;
836
837 if (!qt_settings_timestamp) {
838 QString atomname ("_QT_SETTINGS_TIMESTAMP_");
839
840 atomname += XDisplayName (0); // Use the $DISPLAY envvar.
841 qt_settings_timestamp =
842 XInternAtom (qt_xdisplay (), atomname.latin1 (), False);
843 }
844
845 QBuffer stamp;
846 QDataStream s (stamp.buffer (), IO_WriteOnly);
847
848 s << settingsstamp;
849 XChangeProperty (qt_xdisplay (), qt_xrootwin (), qt_settings_timestamp,
850 qt_settings_timestamp, 8, PropModeReplace,
851 (unsigned char *)stamp.buffer ().data (),
852 stamp.buffer ().size ());
853 QApplication::flushX ();
854 }
855 }
856
857 static void
858 applyQtColors (KConfig & kglobals, QSettings & settings, QPalette & newPal)
859 {
860 QStringList actcg, inactcg, discg;
861
862 /* export kde color settings */
863 int i;
864
865 for (i = 0; i < QColorGroup::NColorRoles; i++)
866 actcg << newPal.color (QPalette::Active,
867 (QColorGroup::ColorRole) i).name ();
868 for (i = 0; i < QColorGroup::NColorRoles; i++)
869 inactcg << newPal.color (QPalette::Inactive,
870 (QColorGroup::ColorRole) i).name ();
871 for (i = 0; i < QColorGroup::NColorRoles; i++)
872 discg << newPal.color (QPalette::Disabled,
873 (QColorGroup::ColorRole) i).name ();
874
875 while (!settings.writeEntry ("/qt/Palette/active", actcg)) ;
876 settings.writeEntry ("/qt/Palette/inactive", inactcg);
877 settings.writeEntry ("/qt/Palette/disabled", discg);
878
879 // export kwin's colors to qtrc for kstyle to use
880 kglobals.setGroup ("WM");
881
882 // active colors
883 QColor clr = newPal.active ().background ();
884
885 clr = kglobals.readColorEntry ("activeBackground", &clr);
886 settings.writeEntry ("/qt/KWinPalette/activeBackground", clr.name ());
887 if (QPixmap::defaultDepth () > 8)
888 clr = clr.dark (110);
889 clr = kglobals.readColorEntry ("activeBlend", &clr);
890 settings.writeEntry ("/qt/KWinPalette/activeBlend", clr.name ());
891 clr = newPal.active ().highlightedText ();
892 clr = kglobals.readColorEntry ("activeForeground", &clr);
893 settings.writeEntry ("/qt/KWinPalette/activeForeground", clr.name ());
894 clr = newPal.active ().background ();
895 clr = kglobals.readColorEntry ("frame", &clr);
896 settings.writeEntry ("/qt/KWinPalette/frame", clr.name ());
897 clr = kglobals.readColorEntry ("activeTitleBtnBg", &clr);
898 settings.writeEntry ("/qt/KWinPalette/activeTitleBtnBg", clr.name ());
899
900 // inactive colors
901 clr = newPal.inactive ().background ();
902 clr = kglobals.readColorEntry ("inactiveBackground", &clr);
903 settings.writeEntry ("/qt/KWinPalette/inactiveBackground", clr.name ());
904 if (QPixmap::defaultDepth () > 8)
905 clr = clr.dark (110);
906 clr = kglobals.readColorEntry ("inactiveBlend", &clr);
907 settings.writeEntry ("/qt/KWinPalette/inactiveBlend", clr.name ());
908 clr = newPal.inactive ().background ().dark ();
909 clr = kglobals.readColorEntry ("inactiveForeground", &clr);
910 settings.writeEntry ("/qt/KWinPalette/inactiveForeground", clr.name ());
911 clr = newPal.inactive ().background ();
912 clr = kglobals.readColorEntry ("inactiveFrame", &clr);
913 settings.writeEntry ("/qt/KWinPalette/inactiveFrame", clr.name ());
914 clr = kglobals.readColorEntry ("inactiveTitleBtnBg", &clr);
915 settings.writeEntry ("/qt/KWinPalette/inactiveTitleBtnBg", clr.name ());
916
917 kglobals.setGroup ("KDE");
918 settings.writeEntry ("/qt/KDE/contrast",
919 kglobals.readNumEntry ("contrast", 7));
920 }
921
922 #endif
923