Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / lib / DtTerm / Term / TermColor.c
1 #ifndef lint
2 #ifdef  VERBOSE_REV_INFO
3 static char rcs_id[] = "$XConsortium: TermColor.c /main/2 1996/05/08 13:31:00 ageorge $";
4 #endif  /* VERBOSE_REV_INFO */
5 #endif  /* lint */
6
7 /*                                                                      *
8  * (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company               *
9  * (c) Copyright 1993, 1994, 1996 International Business Machines Corp. *
10  * (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc.                *
11  * (c) Copyright 1993, 1994, 1996 Novell, Inc.                          *
12  * (c) Copyright 1996 Digital Equipment Corporation.                    *
13  * (c) Copyright 1996 FUJITSU LIMITED.                                  *
14  * (c) Copyright 1996 Hitachi.                                          *
15  */
16
17 #include "TermHeader.h"
18 #include <X11/X.h>
19 #include "TermP.h"
20 #include "TermColor.h"
21 #include "TermPrimDebug.h"
22
23 #ifndef BBA
24 #define InitColor(p, r, g, b)   (p)->red = r ? 0xffff : 0; \
25                                 (p)->green = g ? 0xffff : 0; \
26                                 (p)->blue = b ? 0xffff : 0
27 #else   /* BBA */
28 static void
29 InitColor
30 (
31     XColor       *p,
32     int           r,
33     int           g,
34     int           b
35 )
36 {
37     p->red = r ? 0xffff : 0;
38     p->green = g ? 0xffff : 0;
39     p->blue = b ? 0xffff : 0;
40 }
41
42 #endif  /* BBA */
43
44 static Boolean debugColors = False;
45 static int debugColorsAvailable = 0;
46
47 #define DebugIsColorAvailable() (!debugColors || (debugColors && (debugColorsAvailable > 0)))
48
49 void
50 _DtTermColorInit(Widget w)
51 {
52     DtTermWidget tw = (DtTermWidget) w;
53     DtTermData td = tw->vt.td;
54     int i;
55
56     if (isDebugFSet('C', 0)) {
57 #ifdef  BBA
58 #pragma BBA_IGNORE
59 #endif  /*BBA*/
60         _DtTermProcessLock();
61         debugColors = True;
62         if (isDebugFSet('C', 1)) {
63             debugColorsAvailable = 5;
64         } else if (isDebugFSet('C', 2)) {
65             debugColorsAvailable = 6;
66         } else if (isDebugFSet('C', 3)) {
67             debugColorsAvailable = 7;
68         } else if (isDebugFSet('C', 4)) {
69             debugColorsAvailable = 8;
70         }
71         _DtTermProcessUnlock();
72     }
73
74     /* set up color pairs... */
75     td->colorPairs[0].fg.pixel = tw->primitive.foreground;
76     td->colorPairs[0].bg.pixel = tw->core.background_pixel;
77
78     /* Assume that we can't free the foreground and background colors.
79      * this will keep us from messing up any hidden widget stuff that
80      * either depends on them (since the toolkit allocated them for us
81      * to begin with), or mucks with and/or owns them (like the VUE
82      * color object)...
83      */
84     td->colorPairs[0].fgCommon = True;
85     td->colorPairs[0].bgCommon = True;
86     /* initialize the color... */
87     (void) _DtTermColorInitializeColorPair(w, &td->colorPairs[0]);
88
89     /* set the default colors for colorpairs 1-7...
90      */
91     InitColor(&td->colorPairs[1].fg, 0, 0, 0);  /* 1: fg=black*/
92     InitColor(&td->colorPairs[2].fg, 1, 0, 0);  /* 2: fg=red            */
93     InitColor(&td->colorPairs[3].fg, 0, 1, 0);  /* 2: fg=green          */
94     InitColor(&td->colorPairs[4].fg, 1, 1, 0);  /* 3: fg=yellow         */
95     InitColor(&td->colorPairs[5].fg, 0, 0, 1);  /* 4: fg=blue           */
96     InitColor(&td->colorPairs[6].fg, 1, 0, 1);  /* 5: fg=magenta        */
97     InitColor(&td->colorPairs[7].fg, 0, 1, 1);  /* 6: fg=cyan           */
98     InitColor(&td->colorPairs[8].fg, 1, 1, 1);  /* 7: fg=white          */
99     InitColor(&td->colorPairs[1].bg, 0, 0, 0);  /* 1: bg=black          */
100     InitColor(&td->colorPairs[2].bg, 1, 0, 0);  /* 2: bg=red            */
101     InitColor(&td->colorPairs[3].bg, 0, 1, 0);  /* 3: bg=green          */
102     InitColor(&td->colorPairs[4].bg, 1, 1, 0);  /* 4: bg=yellow         */
103     InitColor(&td->colorPairs[5].bg, 0, 0, 1);  /* 5: bg=blue           */
104     InitColor(&td->colorPairs[6].bg, 1, 0, 1);  /* 6: bg=magenta        */
105     InitColor(&td->colorPairs[7].bg, 0, 1, 1);  /* 7: bg=cyan           */
106     InitColor(&td->colorPairs[8].bg, 1, 1, 1);  /* 8: bg=white          */
107     return;
108 }
109
110 void
111 _DtTermColorDestroy(Widget w)
112 {
113     DtTermWidget tw = (DtTermWidget) w;
114     DtTermData td = tw->vt.td;
115     int i;
116     int j;
117     Pixel pixels[3];
118
119     /* run through the color pairs and free up all the pixels that
120      * we allocated.  This function will mark things as invalid/
121      * uninitialized so that it will not kill things if it is
122      * called more than once on destroy...
123      */
124     for (i = 0; i < 8; i++) {
125         if (td->colorPairs[i].initialized) {
126             j = 0;
127             if (!td->colorPairs[i].fgCommon) {
128                 pixels[j++] = td->colorPairs[i].fg.pixel;
129             }
130             if (!td->colorPairs[i].bgCommon) {
131                 pixels[j++] = td->colorPairs[i].bg.pixel;
132             }
133             if (td->colorPairs[i].hbValid) {
134                 pixels[j++] = td->colorPairs[i].hb.pixel;
135                 td->colorPairs[i].hbValid = False;
136             }
137             if (j > 0) {
138                 (void) XFreeColors(XtDisplay(w), w->core.colormap, pixels, j,
139                         0);
140                 _DtTermProcessLock();
141                 debugColorsAvailable += j;
142                 _DtTermProcessUnlock();
143             }
144             td->colorPairs[i].initialized = False;
145         }
146     }
147     return;
148 }
149
150 void
151 _DtTermColorInitializeColorPair(Widget w, VtColorPair colorPair)
152 {
153     DtTermWidget tw = (DtTermWidget) w;
154     DtTermData td = tw->vt.td;
155     Boolean fgValid = colorPair->fgCommon;
156     Boolean bgValid = colorPair->bgCommon;
157     Pixel pixels[2];
158     int i;
159
160     if (colorPair->initialized) {
161         /* already initialized... */
162         return;
163     }
164
165     _DtTermProcessLock();
166     /* initialize foreground... */
167     if (!colorPair->fgCommon) {
168         if (DebugIsColorAvailable() &&
169                 XAllocColor(XtDisplay(w), w->core.colormap, &colorPair->fg)) {
170             fgValid = True;
171             (void) debugColorsAvailable--;
172         }
173     }
174     /* initialize background... */
175     if (!colorPair->bgCommon) {
176         if (DebugIsColorAvailable() &&
177                 XAllocColor(XtDisplay(w), w->core.colormap, &colorPair->bg)) {
178             bgValid = True;
179             (void) debugColorsAvailable--;
180         }
181     }
182
183     /* did we have a failure?... */
184     if (!fgValid || !bgValid) {
185         /* we were unable to allocate a foreground/background pair.  Let's
186          * use the base colorpair pair[0]...
187          */
188         i = 0;
189
190         /* free up any allocated color cells... */
191         if (fgValid && !colorPair->fgCommon) {
192             pixels[i++] = colorPair->fg.pixel;
193         }
194         if (bgValid && !colorPair->bgCommon) {
195             pixels[i++] = colorPair->bg.pixel;
196         }
197         if (i > 0) {
198             (void) XFreeColors(XtDisplay(w), w->core.colormap, pixels, i, 0);
199             debugColorsAvailable += i;
200         }
201
202         /* use the base color (colorPair 0)... */
203         (void) memcpy(&colorPair->fg, &td->colorPairs[0].fg,
204                 sizeof(td->colorPairs[0].fg));
205         colorPair->fgCommon = td->colorPairs[0].fgCommon;
206
207         (void) memcpy(&colorPair->bg, &td->colorPairs[0].bg,
208                 sizeof(td->colorPairs[0].bg));
209         colorPair->bgCommon = td->colorPairs[0].bgCommon;
210
211         /* since this is the base pair which is always common (since it is
212          * owned either by Motif or CDE), we don't need to re-alloc the pixels
213          * to maintain the correct usage count...
214          */
215     }
216
217     /* for common colors, query the server to get the current values before
218      * we generate the half bright...
219      */
220     if (colorPair->fgCommon) {
221         (void) XQueryColor(XtDisplay(w), w->core.colormap, &colorPair->fg);
222     }
223     if (colorPair->bgCommon) {
224         (void) XQueryColor(XtDisplay(w), w->core.colormap, &colorPair->bg);
225     }
226     /* make the "half bright" 3/4 the intensity of the foreground color... */
227     colorPair->hb.red = ((int) colorPair->fg.red) * 3 / 4;
228     colorPair->hb.green = ((int) colorPair->fg.green) * 3 / 4;
229     colorPair->hb.blue = ((int) colorPair->fg.blue) * 3 / 4;
230
231     /* special case out black -- make it 1/4 brighter...
232      */
233     if ((0 == colorPair->hb.red) &&
234             (0 == colorPair->hb.green) &&
235             (0 == colorPair->hb.blue)) {
236         colorPair->hb.red = 0xffff / 4;
237         colorPair->hb.green = 0xffff / 4;
238         colorPair->hb.blue = 0xffff / 4;
239     }
240     colorPair->hb.flags = colorPair->fg.flags;
241
242     /* allocate the halfbright color... */
243     if (DebugIsColorAvailable() &&
244             XAllocColor(XtDisplay(w), w->core.colormap, &colorPair->hb)) {
245         /* success... */
246         colorPair->hbValid = True;
247         (void) debugColorsAvailable--;
248     } else {
249         colorPair->hbValid = False;
250     }
251     _DtTermProcessUnlock();
252
253     colorPair->initialized = True;
254 }