1 #ifndef __global_h
2 # include "global.H"
3 #endif
4 #ifndef __color_h
5 # include "color.H"
6 #endif
7 #ifndef __port_h
8 # include "port.H"
9 #endif
10
11 #include <stdio.h>
12 #include <stdlib.h>
13
brighten(XColor * chg,XColor * org,double percent)14 void Color::brighten( XColor *chg, XColor *org, double percent )
15 {
16 if (percent<0) {
17 percent = 100+percent;
18 chg->red = (unsigned short)(org->red*percent/100);
19 chg->green = (unsigned short)(org->green*percent/100);
20 chg->blue = (unsigned short)(org->blue*percent/100);
21 }
22 else {
23 chg->red = (unsigned short)((65536-org->red)*percent/100 + org->red);
24 chg->green = (unsigned short)((65536-org->green)*percent/100 + org->green);
25 chg->blue = (unsigned short)((65536-org->blue)*percent/100 + org->blue);
26 }
27 }
28
Color(Port * p_in,int color_id,char * color_name)29 Color::Color( Port *p_in, int color_id, char *color_name ) :
30 p(p_in)
31 {
32 unsigned long plane_mask[2];
33 XColor def;
34 XColor chg[4];
35 int i;
36
37 this->color_id = color_id;
38
39 //
40 // query the display for the given rgb-values and
41 // brighten/darken them to get a 3D-effect.
42 //
43 for (i=0;i<4;i++) {
44 char colnam[40];
45 sprintf(colnam,"%s%d",color_name,i+1);
46 if (XLookupColor( p->display, DefaultColormapOfScreen(p->screen),
47 colnam, &chg[i], &chg[i] ) ) break;
48 }
49 if (i<4) {
50 XLookupColor( p->display, DefaultColormapOfScreen(p->screen), color_name,
51 &def, &def );
52 brighten(&chg[0],&def, 60.);
53 brighten(&chg[1],&def, 20.);
54 brighten(&chg[2],&def,-40.);
55 brighten(&chg[3],&def,-60.);
56 }
57
58 if (p->stipple_pmap) {
59 XColor layer;
60 brighten(&layer,&def,-20.);
61 //
62 // when there are no planes available, gc_n is created as an tiled
63 // overlay with only the main color alloacted.
64 //
65 pixel=p->alloc_color(&layer);
66
67 gc_n = XCreateGC( p->display, RootWindowOfScreen(p->screen), 0L, NULL );
68 XSetForeground( p->display, gc_n, pixel );
69 XSetStipple( p->display, gc_n, p->stipple_pmap );
70 XSetFillStyle( p->display, gc_n, FillStippled );
71 }
72 else {
73 //
74 // Unfortuately the program is constructed to use planes 1 & 2 for drawing
75 // shadows. These are the *usual* planes returned from XAllocColorCells,
76 // when 2 planes are to be allocated. Nevertheless it is not defined that these
77 // 2 planes are returned, but it would mean a big rearrangement (own color
78 // management) to handle this correctly.
79 //
80
81 for (int retry=1;retry<=5;retry++) {
82 if (!XAllocColorCells( p->display, DefaultColormapOfScreen(p->screen),
83 True, // contiguous
84 plane_mask, // plane-mask
85 2, // number of planes
86 &pixel, // field of pixels
87 1 // number of colors
88 )) {
89 fprintf( stderr, "\n" );
90 fprintf( stderr, "*** not enough colors or planes on '%s'\n", DisplayString(p->display) );
91 fprintf( stderr, "\n" );
92 exit(0);
93 }
94
95 if ( (plane_mask[0]|plane_mask[1])==0x03 ) break;
96 fprintf( stderr, "problem: planes 0x%02lx + 0x%02lx, retrying (%d) ...\n",
97 plane_mask[0], plane_mask[1], retry );
98 }
99
100 if ( (plane_mask[0]|plane_mask[1])!=0x3 ) {
101 fprintf( stderr, "WARNING: unexpected results in XAllocColorCells(...)\n" );
102 fprintf( stderr, " planes: 0x%02lx + 0x%02lx\n",
103 plane_mask[0], plane_mask[1] );
104 fprintf( stderr, "Unfortunately the program won't run correct under these condition, since\n" );
105 fprintf( stderr, "the I actually hoped, that XAllocColorCells(...) would always\n" );
106 fprintf( stderr, "allocate planes 1 & 2 for my purpose.\n" );
107 fprintf( stderr, "You should probably send me a mail, so I know about these problem, but it\n" );
108 fprintf( stderr, "would be a major change to solve it ...\n" );
109 }
110
111 for (i=0;i<4;i++) {
112 chg[i].pixel = pixel+((i&1)?plane_mask[0]:0)+((i&2)?plane_mask[1]:0);
113 chg[i].flags = DoRed | DoGreen | DoBlue;
114 }
115
116
117 XStoreColors( p->display, DefaultColormapOfScreen(p->screen), chg, 4 );
118
119 gc_n = XCreateGC( p->display, RootWindowOfScreen(p->screen), 0L, NULL );
120 XSetPlaneMask( p->display, gc_n, ~(plane_mask[0]|plane_mask[1]) );
121 XSetForeground( p->display, gc_n, pixel );
122 }
123 next=0;
124 }
125
~Color()126 Color::~Color() {
127 XFreeGC( p->display, gc_n );
128 if (next) delete next;
129 }
130
131