1 |
dashley |
71 |
/* $Header$ */ |
2 |
|
|
|
3 |
|
|
/* |
4 |
|
|
* tkWin3d.c -- |
5 |
|
|
* |
6 |
|
|
* This file contains the platform specific routines for |
7 |
|
|
* drawing 3d borders in the Windows 95 style. |
8 |
|
|
* |
9 |
|
|
* Copyright (c) 1996 by Sun Microsystems, Inc. |
10 |
|
|
* |
11 |
|
|
* See the file "license.terms" for information on usage and redistribution |
12 |
|
|
* of this file, and for a DISCLAIMER OF ALL WARRANTIES. |
13 |
|
|
* |
14 |
|
|
* RCS: @(#) $Id: tkwin3d.c,v 1.1.1.1 2001/06/13 05:11:49 dtashley Exp $ |
15 |
|
|
*/ |
16 |
|
|
|
17 |
|
|
#include "tkWinInt.h" |
18 |
|
|
#include "tk3d.h" |
19 |
|
|
|
20 |
|
|
/* |
21 |
|
|
* This structure is used to keep track of the extra colors used by |
22 |
|
|
* Windows 3d borders. |
23 |
|
|
*/ |
24 |
|
|
|
25 |
|
|
typedef struct { |
26 |
|
|
TkBorder info; |
27 |
|
|
XColor *light2ColorPtr; /* System3dLight */ |
28 |
|
|
XColor *dark2ColorPtr; /* System3dDarkShadow */ |
29 |
|
|
} WinBorder; |
30 |
|
|
|
31 |
|
|
|
32 |
|
|
/* |
33 |
|
|
*---------------------------------------------------------------------- |
34 |
|
|
* |
35 |
|
|
* TkpGetBorder -- |
36 |
|
|
* |
37 |
|
|
* This function allocates a new TkBorder structure. |
38 |
|
|
* |
39 |
|
|
* Results: |
40 |
|
|
* Returns a newly allocated TkBorder. |
41 |
|
|
* |
42 |
|
|
* Side effects: |
43 |
|
|
* None. |
44 |
|
|
* |
45 |
|
|
*---------------------------------------------------------------------- |
46 |
|
|
*/ |
47 |
|
|
|
48 |
|
|
TkBorder * |
49 |
|
|
TkpGetBorder() |
50 |
|
|
{ |
51 |
|
|
WinBorder *borderPtr = (WinBorder *) ckalloc(sizeof(WinBorder)); |
52 |
|
|
borderPtr->light2ColorPtr = NULL; |
53 |
|
|
borderPtr->dark2ColorPtr = NULL; |
54 |
|
|
return (TkBorder *) borderPtr; |
55 |
|
|
} |
56 |
|
|
|
57 |
|
|
/* |
58 |
|
|
*---------------------------------------------------------------------- |
59 |
|
|
* |
60 |
|
|
* TkpFreeBorder -- |
61 |
|
|
* |
62 |
|
|
* This function frees any colors allocated by the platform |
63 |
|
|
* specific part of this module. |
64 |
|
|
* |
65 |
|
|
* Results: |
66 |
|
|
* None. |
67 |
|
|
* |
68 |
|
|
* Side effects: |
69 |
|
|
* May deallocate some colors. |
70 |
|
|
* |
71 |
|
|
*---------------------------------------------------------------------- |
72 |
|
|
*/ |
73 |
|
|
|
74 |
|
|
void |
75 |
|
|
TkpFreeBorder(borderPtr) |
76 |
|
|
TkBorder *borderPtr; |
77 |
|
|
{ |
78 |
|
|
WinBorder *winBorderPtr = (WinBorder *) borderPtr; |
79 |
|
|
if (winBorderPtr->light2ColorPtr) { |
80 |
|
|
Tk_FreeColor(winBorderPtr->light2ColorPtr); |
81 |
|
|
} |
82 |
|
|
if (winBorderPtr->dark2ColorPtr) { |
83 |
|
|
Tk_FreeColor(winBorderPtr->dark2ColorPtr); |
84 |
|
|
} |
85 |
|
|
} |
86 |
|
|
|
87 |
|
|
/* |
88 |
|
|
*-------------------------------------------------------------- |
89 |
|
|
* |
90 |
|
|
* Tk_3DVerticalBevel -- |
91 |
|
|
* |
92 |
|
|
* This procedure draws a vertical bevel along one side of |
93 |
|
|
* an object. The bevel is always rectangular in shape: |
94 |
|
|
* ||| |
95 |
|
|
* ||| |
96 |
|
|
* ||| |
97 |
|
|
* ||| |
98 |
|
|
* ||| |
99 |
|
|
* ||| |
100 |
|
|
* An appropriate shadow color is chosen for the bevel based |
101 |
|
|
* on the leftBevel and relief arguments. Normally this |
102 |
|
|
* procedure is called first, then Tk_3DHorizontalBevel is |
103 |
|
|
* called next to draw neat corners. |
104 |
|
|
* |
105 |
|
|
* Results: |
106 |
|
|
* None. |
107 |
|
|
* |
108 |
|
|
* Side effects: |
109 |
|
|
* Graphics are drawn in drawable. |
110 |
|
|
* |
111 |
|
|
*-------------------------------------------------------------- |
112 |
|
|
*/ |
113 |
|
|
|
114 |
|
|
void |
115 |
|
|
Tk_3DVerticalBevel(tkwin, drawable, border, x, y, width, height, |
116 |
|
|
leftBevel, relief) |
117 |
|
|
Tk_Window tkwin; /* Window for which border was allocated. */ |
118 |
|
|
Drawable drawable; /* X window or pixmap in which to draw. */ |
119 |
|
|
Tk_3DBorder border; /* Token for border to draw. */ |
120 |
|
|
int x, y, width, height; /* Area of vertical bevel. */ |
121 |
|
|
int leftBevel; /* Non-zero means this bevel forms the |
122 |
|
|
* left side of the object; 0 means it |
123 |
|
|
* forms the right side. */ |
124 |
|
|
int relief; /* Kind of bevel to draw. For example, |
125 |
|
|
* TK_RELIEF_RAISED means interior of |
126 |
|
|
* object should appear higher than |
127 |
|
|
* exterior. */ |
128 |
|
|
{ |
129 |
|
|
TkBorder *borderPtr = (TkBorder *) border; |
130 |
|
|
int left, right; |
131 |
|
|
Display *display = Tk_Display(tkwin); |
132 |
|
|
TkWinDCState state; |
133 |
|
|
HDC dc = TkWinGetDrawableDC(display, drawable, &state); |
134 |
|
|
int half; |
135 |
|
|
|
136 |
|
|
if ((borderPtr->lightGC == None) && (relief != TK_RELIEF_FLAT)) { |
137 |
|
|
TkpGetShadows(borderPtr, tkwin); |
138 |
|
|
} |
139 |
|
|
|
140 |
|
|
switch (relief) { |
141 |
|
|
case TK_RELIEF_RAISED: |
142 |
|
|
left = (leftBevel) |
143 |
|
|
? borderPtr->lightGC->foreground |
144 |
|
|
: borderPtr->darkGC->foreground; |
145 |
|
|
right = (leftBevel) |
146 |
|
|
? ((WinBorder *)borderPtr)->light2ColorPtr->pixel |
147 |
|
|
: ((WinBorder *)borderPtr)->dark2ColorPtr->pixel; |
148 |
|
|
break; |
149 |
|
|
case TK_RELIEF_SUNKEN: |
150 |
|
|
left = (leftBevel) |
151 |
|
|
? ((WinBorder *)borderPtr)->dark2ColorPtr->pixel |
152 |
|
|
: ((WinBorder *)borderPtr)->light2ColorPtr->pixel; |
153 |
|
|
right = (leftBevel) |
154 |
|
|
? borderPtr->darkGC->foreground |
155 |
|
|
: borderPtr->lightGC->foreground; |
156 |
|
|
break; |
157 |
|
|
case TK_RELIEF_RIDGE: |
158 |
|
|
left = borderPtr->lightGC->foreground; |
159 |
|
|
right = borderPtr->darkGC->foreground; |
160 |
|
|
break; |
161 |
|
|
case TK_RELIEF_GROOVE: |
162 |
|
|
left = borderPtr->darkGC->foreground; |
163 |
|
|
right = borderPtr->lightGC->foreground; |
164 |
|
|
break; |
165 |
|
|
case TK_RELIEF_FLAT: |
166 |
|
|
left = right = borderPtr->bgGC->foreground; |
167 |
|
|
break; |
168 |
|
|
case TK_RELIEF_SOLID: |
169 |
|
|
left = right = RGB(0,0,0); |
170 |
|
|
break; |
171 |
|
|
} |
172 |
|
|
half = width/2; |
173 |
|
|
if (leftBevel && (width & 1)) { |
174 |
|
|
half++; |
175 |
|
|
} |
176 |
|
|
TkWinFillRect(dc, x, y, half, height, left); |
177 |
|
|
TkWinFillRect(dc, x+half, y, width-half, height, right); |
178 |
|
|
TkWinReleaseDrawableDC(drawable, dc, &state); |
179 |
|
|
} |
180 |
|
|
|
181 |
|
|
/* |
182 |
|
|
*-------------------------------------------------------------- |
183 |
|
|
* |
184 |
|
|
* Tk_3DHorizontalBevel -- |
185 |
|
|
* |
186 |
|
|
* This procedure draws a horizontal bevel along one side of |
187 |
|
|
* an object. The bevel has mitered corners (depending on |
188 |
|
|
* leftIn and rightIn arguments). |
189 |
|
|
* |
190 |
|
|
* Results: |
191 |
|
|
* None. |
192 |
|
|
* |
193 |
|
|
* Side effects: |
194 |
|
|
* None. |
195 |
|
|
* |
196 |
|
|
*-------------------------------------------------------------- |
197 |
|
|
*/ |
198 |
|
|
|
199 |
|
|
void |
200 |
|
|
Tk_3DHorizontalBevel(tkwin, drawable, border, x, y, width, height, |
201 |
|
|
leftIn, rightIn, topBevel, relief) |
202 |
|
|
Tk_Window tkwin; /* Window for which border was allocated. */ |
203 |
|
|
Drawable drawable; /* X window or pixmap in which to draw. */ |
204 |
|
|
Tk_3DBorder border; /* Token for border to draw. */ |
205 |
|
|
int x, y, width, height; /* Bounding box of area of bevel. Height |
206 |
|
|
* gives width of border. */ |
207 |
|
|
int leftIn, rightIn; /* Describes whether the left and right |
208 |
|
|
* edges of the bevel angle in or out as |
209 |
|
|
* they go down. For example, if "leftIn" |
210 |
|
|
* is true, the left side of the bevel |
211 |
|
|
* looks like this: |
212 |
|
|
* ___________ |
213 |
|
|
* __________ |
214 |
|
|
* _________ |
215 |
|
|
* ________ |
216 |
|
|
*/ |
217 |
|
|
int topBevel; /* Non-zero means this bevel forms the |
218 |
|
|
* top side of the object; 0 means it |
219 |
|
|
* forms the bottom side. */ |
220 |
|
|
int relief; /* Kind of bevel to draw. For example, |
221 |
|
|
* TK_RELIEF_RAISED means interior of |
222 |
|
|
* object should appear higher than |
223 |
|
|
* exterior. */ |
224 |
|
|
{ |
225 |
|
|
TkBorder *borderPtr = (TkBorder *) border; |
226 |
|
|
Display *display = Tk_Display(tkwin); |
227 |
|
|
int bottom, halfway, x1, x2, x1Delta, x2Delta; |
228 |
|
|
TkWinDCState state; |
229 |
|
|
HDC dc = TkWinGetDrawableDC(display, drawable, &state); |
230 |
|
|
int topColor, bottomColor; |
231 |
|
|
|
232 |
|
|
if ((borderPtr->lightGC == None) && (relief != TK_RELIEF_FLAT)) { |
233 |
|
|
TkpGetShadows(borderPtr, tkwin); |
234 |
|
|
} |
235 |
|
|
|
236 |
|
|
/* |
237 |
|
|
* Compute a GC for the top half of the bevel and a GC for the |
238 |
|
|
* bottom half (they're the same in many cases). |
239 |
|
|
*/ |
240 |
|
|
|
241 |
|
|
switch (relief) { |
242 |
|
|
case TK_RELIEF_RAISED: |
243 |
|
|
topColor = (topBevel) |
244 |
|
|
? borderPtr->lightGC->foreground |
245 |
|
|
: borderPtr->darkGC->foreground; |
246 |
|
|
bottomColor = (topBevel) |
247 |
|
|
? ((WinBorder *)borderPtr)->light2ColorPtr->pixel |
248 |
|
|
: ((WinBorder *)borderPtr)->dark2ColorPtr->pixel; |
249 |
|
|
break; |
250 |
|
|
case TK_RELIEF_SUNKEN: |
251 |
|
|
topColor = (topBevel) |
252 |
|
|
? ((WinBorder *)borderPtr)->dark2ColorPtr->pixel |
253 |
|
|
: ((WinBorder *)borderPtr)->light2ColorPtr->pixel; |
254 |
|
|
bottomColor = (topBevel) |
255 |
|
|
? borderPtr->darkGC->foreground |
256 |
|
|
: borderPtr->lightGC->foreground; |
257 |
|
|
break; |
258 |
|
|
case TK_RELIEF_RIDGE: |
259 |
|
|
topColor = borderPtr->lightGC->foreground; |
260 |
|
|
bottomColor = borderPtr->darkGC->foreground; |
261 |
|
|
break; |
262 |
|
|
case TK_RELIEF_GROOVE: |
263 |
|
|
topColor = borderPtr->darkGC->foreground; |
264 |
|
|
bottomColor = borderPtr->lightGC->foreground; |
265 |
|
|
break; |
266 |
|
|
case TK_RELIEF_FLAT: |
267 |
|
|
topColor = bottomColor = borderPtr->bgGC->foreground; |
268 |
|
|
break; |
269 |
|
|
case TK_RELIEF_SOLID: |
270 |
|
|
topColor = bottomColor = RGB(0,0,0); |
271 |
|
|
} |
272 |
|
|
|
273 |
|
|
/* |
274 |
|
|
* Compute various other geometry-related stuff. |
275 |
|
|
*/ |
276 |
|
|
|
277 |
|
|
if (leftIn) { |
278 |
|
|
x1 = x+1; |
279 |
|
|
} else { |
280 |
|
|
x1 = x+height-1; |
281 |
|
|
} |
282 |
|
|
x2 = x+width; |
283 |
|
|
if (rightIn) { |
284 |
|
|
x2--; |
285 |
|
|
} else { |
286 |
|
|
x2 -= height; |
287 |
|
|
} |
288 |
|
|
x1Delta = (leftIn) ? 1 : -1; |
289 |
|
|
x2Delta = (rightIn) ? -1 : 1; |
290 |
|
|
halfway = y + height/2; |
291 |
|
|
if (topBevel && (height & 1)) { |
292 |
|
|
halfway++; |
293 |
|
|
} |
294 |
|
|
bottom = y + height; |
295 |
|
|
|
296 |
|
|
/* |
297 |
|
|
* Draw one line for each y-coordinate covered by the bevel. |
298 |
|
|
*/ |
299 |
|
|
|
300 |
|
|
for ( ; y < bottom; y++) { |
301 |
|
|
/* |
302 |
|
|
* In some weird cases (such as large border widths for skinny |
303 |
|
|
* rectangles) x1 can be >= x2. Don't draw the lines |
304 |
|
|
* in these cases. |
305 |
|
|
*/ |
306 |
|
|
|
307 |
|
|
if (x1 < x2) { |
308 |
|
|
TkWinFillRect(dc, x1, y, x2-x1, 1, |
309 |
|
|
(y < halfway) ? topColor : bottomColor); |
310 |
|
|
} |
311 |
|
|
x1 += x1Delta; |
312 |
|
|
x2 += x2Delta; |
313 |
|
|
} |
314 |
|
|
TkWinReleaseDrawableDC(drawable, dc, &state); |
315 |
|
|
} |
316 |
|
|
|
317 |
|
|
/* |
318 |
|
|
*---------------------------------------------------------------------- |
319 |
|
|
* |
320 |
|
|
* TkpGetShadows -- |
321 |
|
|
* |
322 |
|
|
* This procedure computes the shadow colors for a 3-D border |
323 |
|
|
* and fills in the corresponding fields of the Border structure. |
324 |
|
|
* It's called lazily, so that the colors aren't allocated until |
325 |
|
|
* something is actually drawn with them. That way, if a border |
326 |
|
|
* is only used for flat backgrounds the shadow colors will |
327 |
|
|
* never be allocated. |
328 |
|
|
* |
329 |
|
|
* Results: |
330 |
|
|
* None. |
331 |
|
|
* |
332 |
|
|
* Side effects: |
333 |
|
|
* The lightGC and darkGC fields in borderPtr get filled in, |
334 |
|
|
* if they weren't already. |
335 |
|
|
* |
336 |
|
|
*---------------------------------------------------------------------- |
337 |
|
|
*/ |
338 |
|
|
|
339 |
|
|
void |
340 |
|
|
TkpGetShadows(borderPtr, tkwin) |
341 |
|
|
TkBorder *borderPtr; /* Information about border. */ |
342 |
|
|
Tk_Window tkwin; /* Window where border will be used for |
343 |
|
|
* drawing. */ |
344 |
|
|
{ |
345 |
|
|
XColor lightColor, darkColor; |
346 |
|
|
int tmp1, tmp2; |
347 |
|
|
int r, g, b; |
348 |
|
|
XGCValues gcValues; |
349 |
|
|
|
350 |
|
|
if (borderPtr->lightGC != None) { |
351 |
|
|
return; |
352 |
|
|
} |
353 |
|
|
|
354 |
|
|
/* |
355 |
|
|
* Handle the special case of the default system colors. |
356 |
|
|
*/ |
357 |
|
|
|
358 |
|
|
if ((TkWinIndexOfColor(borderPtr->bgColorPtr) == COLOR_3DFACE) |
359 |
|
|
|| (TkWinIndexOfColor(borderPtr->bgColorPtr) == COLOR_WINDOW)) { |
360 |
|
|
borderPtr->darkColorPtr = Tk_GetColor(NULL, tkwin, |
361 |
|
|
Tk_GetUid("SystemButtonShadow")); |
362 |
|
|
gcValues.foreground = borderPtr->darkColorPtr->pixel; |
363 |
|
|
borderPtr->darkGC = Tk_GetGC(tkwin, GCForeground, &gcValues); |
364 |
|
|
borderPtr->lightColorPtr = Tk_GetColor(NULL, tkwin, |
365 |
|
|
Tk_GetUid("SystemButtonHighlight")); |
366 |
|
|
gcValues.foreground = borderPtr->lightColorPtr->pixel; |
367 |
|
|
borderPtr->lightGC = Tk_GetGC(tkwin, GCForeground, &gcValues); |
368 |
|
|
((WinBorder*)borderPtr)->dark2ColorPtr = Tk_GetColor(NULL, tkwin, |
369 |
|
|
Tk_GetUid("System3dDarkShadow")); |
370 |
|
|
((WinBorder*)borderPtr)->light2ColorPtr = Tk_GetColor(NULL, tkwin, |
371 |
|
|
Tk_GetUid("System3dLight")); |
372 |
|
|
return; |
373 |
|
|
} else { |
374 |
|
|
darkColor.red = 0; |
375 |
|
|
darkColor.green = 0; |
376 |
|
|
darkColor.blue = 0; |
377 |
|
|
((WinBorder*)borderPtr)->dark2ColorPtr = Tk_GetColorByValue(tkwin, |
378 |
|
|
&darkColor); |
379 |
|
|
lightColor = *(borderPtr->bgColorPtr); |
380 |
|
|
((WinBorder*)borderPtr)->light2ColorPtr = Tk_GetColorByValue(tkwin, |
381 |
|
|
&lightColor); |
382 |
|
|
} |
383 |
|
|
|
384 |
|
|
/* |
385 |
|
|
* First, handle the case of a color display with lots of colors. |
386 |
|
|
* The shadow colors get computed using whichever formula results |
387 |
|
|
* in the greatest change in color: |
388 |
|
|
* 1. Lighter shadow is half-way to white, darker shadow is half |
389 |
|
|
* way to dark. |
390 |
|
|
* 2. Lighter shadow is 40% brighter than background, darker shadow |
391 |
|
|
* is 40% darker than background. |
392 |
|
|
*/ |
393 |
|
|
|
394 |
|
|
if (Tk_Depth(tkwin) >= 6) { |
395 |
|
|
/* |
396 |
|
|
* This is a color display with lots of colors. For the dark |
397 |
|
|
* shadow, cut 40% from each of the background color components. |
398 |
|
|
* But if the background is already very dark, make the |
399 |
|
|
* dark color a little lighter than the background by increasing |
400 |
|
|
* each color component 1/4th of the way to MAX_INTENSITY. |
401 |
|
|
* |
402 |
|
|
* For the light shadow, boost each component by 40% or half-way |
403 |
|
|
* to white, whichever is greater (the first approach works |
404 |
|
|
* better for unsaturated colors, the second for saturated ones). |
405 |
|
|
* But if the background is already very bright, instead choose a |
406 |
|
|
* slightly darker color for the light shadow by reducing each |
407 |
|
|
* color component by 10%. |
408 |
|
|
* |
409 |
|
|
* Compute the colors using integers, not using lightColor.red |
410 |
|
|
* etc.: these are shorts and may have problems with integer |
411 |
|
|
* overflow. |
412 |
|
|
*/ |
413 |
|
|
|
414 |
|
|
/* |
415 |
|
|
* Compute the dark shadow color |
416 |
|
|
*/ |
417 |
|
|
|
418 |
|
|
r = (int) borderPtr->bgColorPtr->red; |
419 |
|
|
g = (int) borderPtr->bgColorPtr->green; |
420 |
|
|
b = (int) borderPtr->bgColorPtr->blue; |
421 |
|
|
|
422 |
|
|
if (r*0.5*r + g*1.0*g + b*0.28*b < MAX_INTENSITY*0.05*MAX_INTENSITY) { |
423 |
|
|
darkColor.red = (MAX_INTENSITY + 3*r)/4; |
424 |
|
|
darkColor.green = (MAX_INTENSITY + 3*g)/4; |
425 |
|
|
darkColor.blue = (MAX_INTENSITY + 3*b)/4; |
426 |
|
|
} else { |
427 |
|
|
darkColor.red = (60 * r)/100; |
428 |
|
|
darkColor.green = (60 * g)/100; |
429 |
|
|
darkColor.blue = (60 * b)/100; |
430 |
|
|
} |
431 |
|
|
|
432 |
|
|
/* |
433 |
|
|
* Allocate the dark shadow color and its GC |
434 |
|
|
*/ |
435 |
|
|
|
436 |
|
|
borderPtr->darkColorPtr = Tk_GetColorByValue(tkwin, &darkColor); |
437 |
|
|
gcValues.foreground = borderPtr->darkColorPtr->pixel; |
438 |
|
|
borderPtr->darkGC = Tk_GetGC(tkwin, GCForeground, &gcValues); |
439 |
|
|
|
440 |
|
|
/* |
441 |
|
|
* Compute the light shadow color |
442 |
|
|
*/ |
443 |
|
|
|
444 |
|
|
if (g > MAX_INTENSITY*0.95) { |
445 |
|
|
lightColor.red = (90 * r)/100; |
446 |
|
|
lightColor.green = (90 * g)/100; |
447 |
|
|
lightColor.blue = (90 * b)/100; |
448 |
|
|
} else { |
449 |
|
|
tmp1 = (14 * r)/10; |
450 |
|
|
if (tmp1 > MAX_INTENSITY) { |
451 |
|
|
tmp1 = MAX_INTENSITY; |
452 |
|
|
} |
453 |
|
|
tmp2 = (MAX_INTENSITY + r)/2; |
454 |
|
|
lightColor.red = (tmp1 > tmp2) ? tmp1 : tmp2; |
455 |
|
|
tmp1 = (14 * g)/10; |
456 |
|
|
if (tmp1 > MAX_INTENSITY) { |
457 |
|
|
tmp1 = MAX_INTENSITY; |
458 |
|
|
} |
459 |
|
|
tmp2 = (MAX_INTENSITY + g)/2; |
460 |
|
|
lightColor.green = (tmp1 > tmp2) ? tmp1 : tmp2; |
461 |
|
|
tmp1 = (14 * b)/10; |
462 |
|
|
if (tmp1 > MAX_INTENSITY) { |
463 |
|
|
tmp1 = MAX_INTENSITY; |
464 |
|
|
} |
465 |
|
|
tmp2 = (MAX_INTENSITY + b)/2; |
466 |
|
|
lightColor.blue = (tmp1 > tmp2) ? tmp1 : tmp2; |
467 |
|
|
} |
468 |
|
|
|
469 |
|
|
/* |
470 |
|
|
* Allocate the light shadow color and its GC |
471 |
|
|
*/ |
472 |
|
|
|
473 |
|
|
borderPtr->lightColorPtr = Tk_GetColorByValue(tkwin, &lightColor); |
474 |
|
|
gcValues.foreground = borderPtr->lightColorPtr->pixel; |
475 |
|
|
borderPtr->lightGC = Tk_GetGC(tkwin, GCForeground, &gcValues); |
476 |
|
|
return; |
477 |
|
|
} |
478 |
|
|
|
479 |
|
|
if (borderPtr->shadow == None) { |
480 |
|
|
borderPtr->shadow = Tk_GetBitmap((Tcl_Interp *) NULL, tkwin, |
481 |
|
|
Tk_GetUid("gray50")); |
482 |
|
|
if (borderPtr->shadow == None) { |
483 |
|
|
panic("TkpGetShadows couldn't allocate bitmap for border"); |
484 |
|
|
} |
485 |
|
|
} |
486 |
|
|
if (borderPtr->visual->map_entries > 2) { |
487 |
|
|
/* |
488 |
|
|
* This isn't a monochrome display, but the colormap either |
489 |
|
|
* ran out of entries or didn't have very many to begin with. |
490 |
|
|
* Generate the light shadows with a white stipple and the |
491 |
|
|
* dark shadows with a black stipple. |
492 |
|
|
*/ |
493 |
|
|
|
494 |
|
|
gcValues.foreground = borderPtr->bgColorPtr->pixel; |
495 |
|
|
gcValues.background = BlackPixelOfScreen(borderPtr->screen); |
496 |
|
|
gcValues.stipple = borderPtr->shadow; |
497 |
|
|
gcValues.fill_style = FillOpaqueStippled; |
498 |
|
|
borderPtr->darkGC = Tk_GetGC(tkwin, |
499 |
|
|
GCForeground|GCBackground|GCStipple|GCFillStyle, &gcValues); |
500 |
|
|
gcValues.foreground = WhitePixelOfScreen(borderPtr->screen); |
501 |
|
|
gcValues.background = borderPtr->bgColorPtr->pixel; |
502 |
|
|
borderPtr->lightGC = Tk_GetGC(tkwin, |
503 |
|
|
GCForeground|GCBackground|GCStipple|GCFillStyle, &gcValues); |
504 |
|
|
return; |
505 |
|
|
} |
506 |
|
|
|
507 |
|
|
/* |
508 |
|
|
* This is just a measly monochrome display, hardly even worth its |
509 |
|
|
* existence on this earth. Make one shadow a 50% stipple and the |
510 |
|
|
* other the opposite of the background. |
511 |
|
|
*/ |
512 |
|
|
|
513 |
|
|
gcValues.foreground = WhitePixelOfScreen(borderPtr->screen); |
514 |
|
|
gcValues.background = BlackPixelOfScreen(borderPtr->screen); |
515 |
|
|
gcValues.stipple = borderPtr->shadow; |
516 |
|
|
gcValues.fill_style = FillOpaqueStippled; |
517 |
|
|
borderPtr->lightGC = Tk_GetGC(tkwin, |
518 |
|
|
GCForeground|GCBackground|GCStipple|GCFillStyle, &gcValues); |
519 |
|
|
if (borderPtr->bgColorPtr->pixel |
520 |
|
|
== WhitePixelOfScreen(borderPtr->screen)) { |
521 |
|
|
gcValues.foreground = BlackPixelOfScreen(borderPtr->screen); |
522 |
|
|
borderPtr->darkGC = Tk_GetGC(tkwin, GCForeground, &gcValues); |
523 |
|
|
} else { |
524 |
|
|
borderPtr->darkGC = borderPtr->lightGC; |
525 |
|
|
borderPtr->lightGC = Tk_GetGC(tkwin, GCForeground, &gcValues); |
526 |
|
|
} |
527 |
|
|
} |
528 |
|
|
|
529 |
|
|
/* |
530 |
|
|
*---------------------------------------------------------------------- |
531 |
|
|
* |
532 |
|
|
* TkWinGetBorderPixels -- |
533 |
|
|
* |
534 |
|
|
* This routine returns the 5 COLORREFs used to draw a given |
535 |
|
|
* 3d border. |
536 |
|
|
* |
537 |
|
|
* Results: |
538 |
|
|
* Returns the colors in the specified array. |
539 |
|
|
* |
540 |
|
|
* Side effects: |
541 |
|
|
* May cause the remaining colors to be allocated. |
542 |
|
|
* |
543 |
|
|
*---------------------------------------------------------------------- |
544 |
|
|
*/ |
545 |
|
|
|
546 |
|
|
COLORREF |
547 |
|
|
TkWinGetBorderPixels(tkwin, border, which) |
548 |
|
|
Tk_Window tkwin; |
549 |
|
|
Tk_3DBorder border; |
550 |
|
|
int which; /* One of TK_3D_FLAT_GC, TK_3D_LIGHT_GC, |
551 |
|
|
* TK_3D_DARK_GC, TK_3D_LIGHT2, TK_3D_DARK2 */ |
552 |
|
|
{ |
553 |
|
|
WinBorder *borderPtr = (WinBorder *) border; |
554 |
|
|
|
555 |
|
|
if (borderPtr->info.lightGC == None) { |
556 |
|
|
TkpGetShadows(&borderPtr->info, tkwin); |
557 |
|
|
} |
558 |
|
|
switch (which) { |
559 |
|
|
case TK_3D_FLAT_GC: |
560 |
|
|
return borderPtr->info.bgColorPtr->pixel; |
561 |
|
|
case TK_3D_LIGHT_GC: |
562 |
|
|
if (borderPtr->info.lightColorPtr == NULL) { |
563 |
|
|
return WhitePixelOfScreen(borderPtr->info.screen); |
564 |
|
|
} |
565 |
|
|
return borderPtr->info.lightColorPtr->pixel; |
566 |
|
|
case TK_3D_DARK_GC: |
567 |
|
|
if (borderPtr->info.darkColorPtr == NULL) { |
568 |
|
|
return BlackPixelOfScreen(borderPtr->info.screen); |
569 |
|
|
} |
570 |
|
|
return borderPtr->info.darkColorPtr->pixel; |
571 |
|
|
case TK_3D_LIGHT2: |
572 |
|
|
return borderPtr->light2ColorPtr->pixel; |
573 |
|
|
case TK_3D_DARK2: |
574 |
|
|
return borderPtr->dark2ColorPtr->pixel; |
575 |
|
|
} |
576 |
|
|
return 0; |
577 |
|
|
} |
578 |
|
|
|
579 |
|
|
/* End of tkwin3d.c */ |