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