[go: up one dir, main page]

Menu

[f2b791]: / src / color.c  Maximize  Restore  History

Download this file

891 lines (736 with data), 23.0 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
/* $Id$
* Copyright (C) 1997-1999 Maciej Stachowiak and Greg J. Badros
*
* This module is derived from code by Rob Nation
* Copyright 1993, Robert Nation
* You may use this code for any purpose, as long as the original
* copyright remains in the source code and all documentation
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <guile/gh.h>
#include <libguile.h>
#include <X11/Xproto.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <float.h>
#define COLOR_IMPLEMENTATION
#include "color.h"
#include "scwm.h"
#include "screen.h"
#include "errors.h"
#include "borders.h"
#include "decor.h"
#include "colors.h"
#include "guile-compat.h"
#include "module-interface.h"
#ifdef USE_DMALLOC
#include "dmalloc.h"
#endif
#define COLOR_HASH_SIZE 20
static SCM color_hash_table = SCM_UNDEFINED;
static SCM protected_colors = SCM_UNDEFINED;
/**CONCEPT: Colors
Colors are first-class objects. However, anywhere that a color is
taken as an argument, a string containing an X color specification
will also be accepted, and will be automatically converted to the
proper color object. Using the same color specifier string more than
once is not inefficient, as caching ensures that color objects are
shared.
*/
/**CONCEPT: Shadow and Highlight Factors
Many decorations are supposed to look "three-dimensional".
To implement this, the decorations use three colors: the specified
decoration color, a brighter "highlight" color, and a darker "shadow"
color. For "raised" decorations, the top and left edges are drawn in
the highlight color, and the bottom and right edges are drawn in the
shadow color; this is reversed for "sunken" decorations.
The highlight and shadow colors are computed from the decoration color
using the highlight and shadow factors. The highlight factor should be
a floating-point number greater than 1. If the highlight factor is
1, then the highlight color is the same as the decoration color;
the larger the highlight factor, the brighter the highlight color.
The shadow factor should be a floating-point number between 0 and 1. If
the shadow factor is 1, then the shadow color is the same as the
decoration color; the smaller the shadow factor, the darker the
shadow color.
(It is actually possible to give a highlight factor which is less than
1 (which makes the highlight color darker than the decoration color)
and a shadow factor which is greater than 1 (which makes the shadow
color brighter than the decoration color); the effect is to reverse
"raised" and "sunken" elements throughout the user interface.)
*/
SCM_SYMBOL (sym_name,"name");
SCM_SYMBOL (sym_pixel,"pixel");
SCM
mark_color(SCM obj)
{
GC_MARK_SCM_IF_SET(COLORNAME(obj));
return SCM_BOOL_F;
}
size_t
free_color(SCM obj)
{
scwm_color *sc=COLOR(obj);
if (!sc->borrowed) {
XFreeColors(dpy, Scr.ScwmRoot.attr.colormap, &sc->pixel, 1, 0);
}
FREE(sc);
return 0;
}
int
print_color(SCM obj, SCM port, scm_print_state *ARG_IGNORE(pstate))
{
scm_puts("#<color ", port);
scm_write(COLORNAME(obj), port);
scm_putc('>', port);
return 1;
}
SCWM_PROC(color_p, "color?", 1, 0, 0,
(SCM obj))
/** Returns #t if OBJ is a color object, otherwise #f. */
#define FUNC_NAME s_color_p
{
return SCM_BOOL_FromBool(COLOR_P(obj));
}
#undef FUNC_NAME
/* MS:FIXME:: Should we extend this to return r, g and b values? Should we
perhaps even store those in the color structure? */
SCWM_PROC(color_properties, "color-properties", 1, 0, 0,
(SCM color))
/** Return an association list giving some properties of COLOR.
Currently defined properties are 'name, the string name of the
color, and 'pixel, the X pixel value it uses. */
#define FUNC_NAME s_color_properties
{
VALIDATE_ARG_COLOR(1,color);
return gh_list(gh_cons(sym_name, COLORNAME(color)),
gh_cons(sym_pixel, gh_int2scm(XCOLOR(color))),
SCM_UNDEFINED);
}
#undef FUNC_NAME
#undef ABS
#define ABS(x) (((x) < 0)? -(x): (x))
/* divisors are to do some simple (and fast) perceptual weighting
(green matters less than red which matters less than blue) */
#define COLOR_DISTANCE(r1, g1, b1, r2, g2, b2) \
( ABS((g1)-(g2))/4 + ABS((r1)-(r2))/2 + ABS((b1)-(b2)) )
/* Return True on success, false on failure */
Bool
ClosestColor(XColor *pcolor)
{
/* just deal with <=8 bit display
as that's all I have right now,
and that's where we need it most, anyway */
if (Scr.d_depth > 8)
return False;
{ /* scope */
XColor cols[256];
int i = 0;
/* the desired color we are matching against */
unsigned short
mr = pcolor->red,
mg = pcolor->green,
mb = pcolor->blue;
int ccols = 1 << Scr.d_depth;
/* track closest match distance in mindist, index into cols in icolBest */
double mindist = DBL_MAX;
int icolBest = -1;
for (i = 0; i < ccols; ++i ) {
cols[i].pixel = i;
cols[i].flags = DoRed | DoGreen | DoBlue;
}
XQueryColors(dpy,Scr.ScwmRoot.attr.colormap, cols, ccols);
for (i = 0; i < ccols; ++i) {
unsigned short
r = cols[i].red,
g = cols[i].green,
b = cols[i].blue;
double dist = COLOR_DISTANCE(mr,mg,mb,r,g,b);
if (dist < mindist) {
mindist = dist;
icolBest = i;
}
}
DBUG((WARN,"ClosestColor","Got match with error = %f",mindist));
*pcolor = cols[icolBest];
return True;
}
}
SCM
ScmMakeColor(const char *cn, int *perror_status)
{
SCM answer;
scwm_color *sc;
XColor color;
Bool fBorrowedColor = False;
if (perror_status)
*perror_status = 0;
color.pixel = 0;
if (!XParseColor(dpy, Scr.ScwmRoot.attr.colormap, cn, &color)) {
if (perror_status)
*perror_status = 1; /* cannot parse */
return SCM_BOOL_F;
} else if (!XAllocColor(dpy, Scr.ScwmRoot.attr.colormap, &color)) {
if (perror_status)
*perror_status = 2; /* cannot alloc */
if (ClosestColor(&color)) {
#ifdef WARN_CLOSE_MATCH /* GJB:FIXME:: need warnings to be run-time configurable */
scwm_msg(WARN,"ScmMakeColor","Allocated a close match for: %s",cn);
#endif
if (perror_status)
*perror_status = 3; /* got close match */
fBorrowedColor = True; /* we are not responsible for freeing this color! */
} else {
scwm_msg(WARN,"ScmMakeColor","Cannot allocate color or a close match: %s -- using black",cn);
return BLACK_COLOR;
}
}
sc = NEW(scwm_color);
sc->pixel = color.pixel;
sc->name = gh_str02scm(cn);
sc->borrowed = fBorrowedColor;
SCWM_NEWCELL_SMOB(answer, scm_tc16_scwm_color, sc);
/* GJB:FIXME:MS: why scm_string_copy? */
scm_hash_set_x (color_hash_table, scm_string_copy(sc->name), answer);
return answer;
}
/* Not as inefficient as it looks - after the first time, this just
amounts to a hash lookup. */
SCWM_PROC(make_color, "make-color", 1, 0, 0,
(SCM cname))
/** Return the color object corresponding to the X color specifier CNAME.
If CNAME is not a valid X color name, or cannot be
allocated, an error results. */
#define FUNC_NAME s_make_color
{
SCM answer;
char *cn;
int error_status;
VALIDATE_ARG_STR_NEWCOPY(1,cname,cn);
answer = scm_hash_ref(color_hash_table, cname, SCM_BOOL_F);
if (answer!=SCM_BOOL_F) {
return answer;
}
answer = ScmMakeColor(cn,&error_status);
switch (error_status) {
case 1:
FREE(cn);
scm_misc_error(FUNC_NAME,"Cannot parse color!",SCM_EOL);
break;
case 2:
/* answer is now BLACK_COLOR, but we could do something
smarter, perhaps */;
break;
}
gh_free(cn);
return answer;
}
#undef FUNC_NAME
SCWM_PROC(clear_color_cache_entry, "clear-color-cache-entry", 1, 0, 0,
(SCM name))
/** Colors are cached by name. It is remotely possible that the
meaning of a particular string as a color will change in your X
server, if you try hard enough. For this unlikely eventuality,
`clear-color-cache-entry' is provided - it removes the color
associated with NAME from the color cache.*/
#define FUNC_NAME s_clear_color_cache_entry
{
scm_hash_remove_x(color_hash_table, name);
return SCM_UNSPECIFIED;
}
#undef FUNC_NAME
/* The highlight/shadow stuff should maybe be in a separate relief.c? */
#define SCALE 65535.0
#define HALF_SCALE (SCALE / 2)
typedef enum {
R_MAX_G_MIN, R_MAX_B_MIN,
G_MAX_B_MIN, G_MAX_R_MIN,
B_MAX_R_MIN, B_MAX_G_MIN
} MinMaxState;
/* Multiply the HLS-space lightness and saturation of the color by the
given multiple, k - based on the way gtk does shading, but independently
coded. Should give better relief colors for many cases than the old
fvwm algorithm. */
/* MS:FIXME:: This can probably be optimized more, examine later. */
void
color_mult (unsigned short *red,
unsigned short *green,
unsigned short *blue, double k)
{
if (*red == *green && *red == *blue) {
double temp;
/* A shade of gray */
temp = k * (double) (*red);
if (temp > SCALE) {
temp = SCALE;
}
*red = (unsigned short)(temp);
*green = *red;
*blue = *red;
} else {
/* Non-zero saturation */
double r, g, b;
double min, max;
double a, l, s;
double delta;
double middle;
MinMaxState min_max_state;
r = (double) *red;
g = (double) *green;
b = (double) *blue;
if (r >= g) {
if (r >= b) {
max = r;
if (g < b) {
min = g;
min_max_state = R_MAX_G_MIN;
a = b - g;
} else {
min = b;
min_max_state = R_MAX_B_MIN;
a = g - b;
}
} else {
max = b;
min = g;
min_max_state = B_MAX_G_MIN;
a = r - g;
}
} else {
if (g >= b) {
max = g;
if (b < r) {
min = b;
min_max_state = G_MAX_R_MIN;
a = r - b;
} else {
min = r;
min_max_state = G_MAX_B_MIN;
a = b - r;
}
} else {
max = b;
min = r;
min_max_state = B_MAX_R_MIN;
a = g - r;
}
}
delta = max - min;
a = a / delta;
l = (max + min) / 2;
if (l <= HALF_SCALE) {
s = max + min;
} else {
s = 2.0 * SCALE - (max + min);
}
s = delta/s;
l *= k;
if (l > SCALE) {
l = SCALE;
}
s *= k;
if (s > 1.0) {
s = 1.0;
}
if (l <= HALF_SCALE) {
max = l * (1 + s);
} else {
max = s * SCALE + l - s * l;
}
min = 2 * l - max;
delta = max - min;
middle = min + delta * a;
switch (min_max_state) {
case R_MAX_G_MIN:
r = max;
g = min;
b = middle;
break;
case R_MAX_B_MIN:
r = max;
g = middle;
b = min;
break;
case G_MAX_B_MIN:
r = middle;
g = max;
b = min;
break;
case G_MAX_R_MIN:
r = min;
g = max;
b = middle;
break;
case B_MAX_G_MIN:
r = middle;
g = min;
b = max;
break;
case B_MAX_R_MIN:
r = min;
g = middle;
b = max;
break;
}
*red = (unsigned short) r;
*green = (unsigned short) g;
*blue = (unsigned short) b;
}
}
SCM
adjust_brightness(SCM color, double factor) {
XColor c;
char cnamebuf[19];
c.pixel = XCOLOR(color);
XQueryColor (dpy, Scr.ScwmRoot.attr.colormap, &c);
color_mult(&c.red, &c.green, &c.blue, factor);
sprintf(cnamebuf, "rgb:%.4hx/%.4hx/%.4hx", c.red, c.green, c.blue);
cnamebuf[19]=0;
return ScmMakeColor(cnamebuf, NULL);
}
Pixel
adjust_pixel_brightness(Pixel pixel, double factor)
{
XColor c;
c.pixel = pixel;
XQueryColor (dpy, Scr.ScwmRoot.attr.colormap, &c);
color_mult(&c.red, &c.green, &c.blue, factor);
XAllocColor (dpy, Scr.ScwmRoot.attr.colormap, &c);
return c.pixel;
}
SCM
invert_color(SCM color) {
XColor c;
char cnamebuf[19];
c.pixel = XCOLOR(color);
XQueryColor (dpy, Scr.ScwmRoot.attr.colormap, &c);
sprintf(cnamebuf, "rgb:%.4hx/%.4hx/%.4hx",
0xffff-c.red, 0xffff-c.green, 0xffff-c.blue);
cnamebuf[19]=0;
return ScmMakeColor(cnamebuf, NULL);
}
SCWM_PROC(make_relief_color, "make-relief-color", 2, 0, 0,
(SCM color, SCM factor))
/** Convert a color into a new color appropriate for a relief.
Multiplies the luminosity and saturation of COLOR by the
positive floating point number FACTOR. Using a FACTOR smaller than 1
will result in a dimmer color, suitable for use as a darker
relief. Using a factor greater than 1 will result in a brighter color
which is suitable for use as a highlight. */
#define FUNC_NAME s_make_relief_color
{
double f;
VALIDATE_ARG_COLOR(1,color);
VALIDATE_ARG_DBL_MIN_COPY(2,factor,0.0,f);
return adjust_brightness(color, f);
}
#undef FUNC_NAME
SCWM_PROC(make_reversed_color, "make-reversed-color", 1, 0, 0,
(SCM color))
/** Return a new color that is opposite COLOR.
Note that the returned color will not necessarily contrast with
COLOR; (make-reversed-color "gray50") is almost indistinguishable
from "gray50". */
#define FUNC_NAME s_make_reversed_color
{
VALIDATE_ARG_COLOR(1,color);
return invert_color(color);
}
#undef FUNC_NAME
/* Shadow and relief computation will now be similar to the way gtk
does it; for now, the highlight and shadow factors may be set
globally so people can experiment, but this is an unsatisfying
solution for the long term, it needs to be settable for everything
that takes a color that it will then use to construct shadows and
highlights, and further, it should recompute these. For now, we'll
trigger a recompute of everything we know about by setting all
colors to themesleves.
Perhaps explictly specifying the relief colors should be allowed
eventually, and there should be a scheme-visible
color brightness adjusting procedure. */
static void reset_decor_relief()
{
ScwmDecor *fl;
ScwmWindow *psw;
fl = cur_decor ? cur_decor : &Scr.DefaultDecor;
if (fl->HiColors.bg != SCM_UNDEFINED) {
set_highlight_background_x(fl->HiColors.bg);
}
for (psw=Scr.ScwmRoot.next; psw != NULL; psw=psw->next) {
if (psw->fl == fl) {
set_window_background_x(psw->BackColor, psw->schwin);
}
}
}
SCWM_PROC(set_highlight_factor_x, "set-highlight-factor!", 1, 0, 0,
(SCM factor))
/** Use FACTOR to generate highlight colors for the current decor.
FACTOR is a positive floating point number. */
#define FUNC_NAME s_set_highlight_factor_x
{
double f;
ScwmDecor *fl;
fl = cur_decor ? cur_decor : &Scr.DefaultDecor;
VALIDATE_ARG_DBL_MIN_COPY(1,factor,0.0,f);
fl->highlight_factor = f;
/* Redraw highlights. */
reset_decor_relief();
return SCM_UNSPECIFIED;
}
#undef FUNC_NAME
SCWM_PROC(highlight_factor, "highlight-factor", 0, 0, 0,
())
/** Return the current highlight factor. */
#define FUNC_NAME s_highlight_factor
{
ScwmDecor *fl;
fl = cur_decor ? cur_decor : &Scr.DefaultDecor;
return (gh_double2scm(fl->highlight_factor));
}
#undef FUNC_NAME
SCWM_PROC(set_shadow_factor_x, "set-shadow-factor!", 1, 0, 0,
(SCM factor))
/** Use FACTOR to generate shadow colors in the current decor.
FACTOR is a positive floating point number */
#define FUNC_NAME s_set_shadow_factor_x
{
double f;
ScwmDecor *fl;
fl = cur_decor ? cur_decor : &Scr.DefaultDecor;
VALIDATE_ARG_DBL_MIN_COPY(1,factor,0.0,f);
fl->shadow_factor = f;
/* Redraw shadows. */
reset_decor_relief();
return SCM_UNSPECIFIED;
}
#undef FUNC_NAME
SCWM_PROC(shadow_factor, "shadow-factor", 0, 0, 0,
())
/** Return the current shadow factor. */
#define FUNC_NAME s_shadow_factor
{
ScwmDecor *fl;
fl = cur_decor ? cur_decor : &Scr.DefaultDecor;
return (gh_double2scm(fl->shadow_factor));
}
#undef FUNC_NAME
/* FIXJTL: these should go away */
SCWM_PROC(set_menu_highlight_factor_x, "set-menu-highlight-factor!", 1, 0, 0,
(SCM factor))
/** Use FACTOR to generate highlight colors for menus.
FACTOR is a positive floating point number */
#define FUNC_NAME s_set_menu_highlight_factor_x
{
double f;
VALIDATE_ARG_DBL_MIN_COPY(1,factor,0.0,f);
menu_highlight_factor_val = f;
return SCM_UNSPECIFIED;
}
#undef FUNC_NAME
SCWM_PROC(menu_highlight_factor, "menu-highlight-factor", 0, 0, 0,
())
/** Return the current menu highlight factor. */
#define FUNC_NAME s_menu_highlight_factor
{
return (gh_double2scm(menu_highlight_factor_val));
}
#undef FUNC_NAME
SCWM_PROC(set_menu_shadow_factor_x, "set-menu-shadow-factor!", 1, 0, 0,
(SCM factor))
/** Use FACTOR to generate shadow colors for menus.
FACTOR is a positive floating point number */
#define FUNC_NAME s_set_menu_shadow_factor_x
{
double f;
VALIDATE_ARG_DBL_MIN_COPY(1,factor,0.0,f);
menu_shadow_factor_val = f;
return SCM_UNSPECIFIED;
}
#undef FUNC_NAME
SCWM_PROC(menu_shadow_factor, "menu-shadow-factor", 0, 0, 0,
())
/** Return the current menu shadow factor. */
#define FUNC_NAME s_menu_shadow_factor
{
return (gh_double2scm(menu_shadow_factor_val));
}
#undef FUNC_NAME
static void
redraw_highlight_window()
{
if (Scr.fWindowsCaptured && (Scr.Hilite != NULL)) {
BroadcastConfig(M_CONFIGURE_WINDOW, Scr.Hilite);
SetBorderX(Scr.Hilite, True, True, True, None, True);
}
}
/* MS:FIXME:: Need to protect color objects in the below! */
SCWM_PROC(set_highlight_foreground_x, "set-highlight-foreground!", 1, 0, 0,
(SCM fg))
/** Use FG for the foreground color of a window with the input focus.
Applies to the current decor. This is used only for windows that don't
have their own foreground color. */
#define FUNC_NAME s_set_highlight_foreground_x
{
ScwmDecor *fl;
VALIDATE_ARG_COLOR(1,fg);
fl = cur_decor ? cur_decor : &Scr.DefaultDecor;
if (Scr.d_depth > 2) {
fl->HiColors.fg = fg;
} else {
fl->HiColors.fg = BLACK_COLOR;
}
redraw_highlight_window();
return SCM_UNSPECIFIED;
}
#undef FUNC_NAME
SCWM_PROC (highlight_foreground, "highlight-foreground", 0, 0, 0,
())
/** Return the default foreground color for windows with the input focus.
Applies to the current decor. This is used only for windows that don't
have their own foreground color. */
#define FUNC_NAME s_highlight_foreground
{
ScwmDecor *fl;
fl = cur_decor ? cur_decor : &Scr.DefaultDecor;
return (fl->HiColors.fg);
}
#undef FUNC_NAME
/* MS:FIXME:: eventually add option to pass background relief, shadow? */
/* MS:FIXME:: the more I do this, the more I wish we had a nice GC
abstraction. */
SCWM_PROC(set_highlight_background_x, "set-highlight-background!", 1, 0, 0,
(SCM bg))
/** Use BG as the background color for a window with the input focus.
Applies to the current decor. This is used only for windows that don't
have their own background color. */
#define FUNC_NAME s_set_highlight_background_x
{
XGCValues gcv;
unsigned long gcm;
ScwmDecor *fl;
VALIDATE_ARG_COLOR(1,bg);
fl = cur_decor ? cur_decor : &Scr.DefaultDecor;
if (Scr.d_depth > 2) {
fl->HiColors.bg = bg;
fl->HiRelief.bg = adjust_brightness(bg,fl->shadow_factor);
fl->HiRelief.fg = adjust_brightness(bg,fl->highlight_factor);
} else {
fl->HiColors.bg = WHITE_COLOR;
fl->HiRelief.bg = BLACK_COLOR;
fl->HiRelief.fg = WHITE_COLOR;
}
/* This gc-setting cruft is from fvwm. Just marking what code still
has questionable license conditions. */
gcm = GCFunction | GCPlaneMask | GCGraphicsExposures | GCLineWidth | GCForeground |
GCBackground;
gcv.foreground = XCOLOR(fl->HiRelief.fg);
gcv.background = XCOLOR(fl->HiRelief.bg);
gcv.fill_style = FillSolid;
gcv.plane_mask = AllPlanes;
gcv.function = GXcopy;
gcv.graphics_exposures = False;
gcv.line_width = 0;
if (fl->HiReliefGC != NULL) {
XFreeGC(dpy, fl->HiReliefGC);
}
fl->HiReliefGC = XCreateGC(dpy, Scr.Root, gcm, &gcv);
gcv.foreground = XCOLOR(fl->HiRelief.bg);
gcv.background = XCOLOR(fl->HiRelief.fg);
if (fl->HiShadowGC != NULL) {
XFreeGC(dpy, fl->HiShadowGC);
}
fl->HiShadowGC = XCreateGC(dpy, Scr.Root, gcm, &gcv);
redraw_highlight_window();
return (SCM_UNSPECIFIED);
}
#undef FUNC_NAME
SCWM_PROC (highlight_background, "highlight-background", 0, 0, 0,
())
/** Return the default background color for windows with the input focus.
Applies to the current decor. This is used only for windows that don't
have their own background color. */
#define FUNC_NAME s_highlight_background
{
ScwmDecor *fl;
fl = cur_decor ? cur_decor : &Scr.DefaultDecor;
return (fl->HiColors.bg);
}
#undef FUNC_NAME
SCWM_PROC(set_not_menu_foreground_x, "set-not-menu-foreground!", 1, 0, 0,
(SCM fg))
/** Use FG as the default foreground color for icons, titlebars, etc. */
#define FUNC_NAME s_set_not_menu_foreground_x
{
VALIDATE_ARG_COLOR(1,fg);
if (Scr.d_depth > 2) {
Scr.NotMenuColors.fg = fg;
} else {
Scr.NotMenuColors.fg = BLACK_COLOR;
}
gh_vector_set_x(protected_colors,SCM_MAKINUM(0),Scr.NotMenuColors.fg);
return (SCM_UNSPECIFIED);
}
#undef FUNC_NAME
SCWM_PROC (not_menu_foreground, "not-menu-foreground", 0, 0, 0,
())
/** Return the default foreground color for icons, titlebars, etc. */
#define FUNC_NAME s_not_menu_foreground
{
return (Scr.NotMenuColors.fg);
}
#undef FUNC_NAME
SCWM_PROC(set_not_menu_background_x, "set-not-menu-background!", 1, 0, 0,
(SCM bg))
/** Use BG as the default background color for icons, window frames, etc. */
#define FUNC_NAME s_set_not_menu_background_x
{
VALIDATE_ARG_COLOR(1,bg);
if (Scr.d_depth > 2) {
Scr.NotMenuColors.bg = bg;
Scr.NotMenuRelief.bg = adjust_brightness (bg, menu_shadow_factor_val);
Scr.NotMenuRelief.fg = adjust_brightness (bg, menu_highlight_factor_val);
} else {
Scr.NotMenuColors.bg = WHITE_COLOR;
Scr.NotMenuRelief.bg = BLACK_COLOR;
Scr.NotMenuRelief.fg = WHITE_COLOR;
}
gh_vector_set_x(protected_colors,SCM_MAKINUM(1),Scr.NotMenuColors.bg);
gh_vector_set_x(protected_colors,SCM_MAKINUM(2),Scr.NotMenuRelief.fg);
gh_vector_set_x(protected_colors,SCM_MAKINUM(3),Scr.NotMenuRelief.bg);
return (SCM_UNSPECIFIED);
}
#undef FUNC_NAME
SCWM_PROC (not_menu_background, "not-menu-background", 0, 0, 0,
())
/** Return the default background color for icons, window frames, etc. */
#define FUNC_NAME s_not_menu_background
{
return (Scr.NotMenuColors.bg);
}
#undef FUNC_NAME
MAKE_SMOBFUNS(color);
void
init_color()
{
REGISTER_SCWMSMOBFUNS(color);
color_hash_table =
scm_make_weak_value_hash_table (gh_int2scm(COLOR_HASH_SIZE));
scm_protect_object(color_hash_table);
protected_colors = gh_make_vector (gh_int2scm(4), SCM_EOL);
scm_protect_object(protected_colors);
scm_protect_object(str_black=gh_str02scm("black"));
scm_protect_object(str_white=gh_str02scm("white"));
/* XXX XXX remaining to fix for the color object migration:
fix all the Scheme code */
#ifndef SCM_MAGIC_SNARFER
#include "color.x"
#endif
}
/* Local Variables: */
/* tab-width: 8 */
/* c-basic-offset: 2 */
/* End: */
/* vim:ts=8:sw=2:sta
*/