#include "tk3d.h"
#if !(defined(__WIN32__) || defined(MAC_TCL) || defined(MAC_OSX_TK))
#include "tkUnixInt.h"
#endif
typedef
struct
{
TkBorder info;
GC solidGC;
} UnixBorder;
TkBorder *
TkpGetBorder()
{
UnixBorder *borderPtr = (UnixBorder *) ckalloc(
sizeof
(UnixBorder));
borderPtr->solidGC = None;
return
(TkBorder *) borderPtr;
}
void
TkpFreeBorder(borderPtr)
TkBorder *borderPtr;
{
UnixBorder *unixBorderPtr = (UnixBorder *) borderPtr;
Display *display = DisplayOfScreen(borderPtr->screen);
if
(unixBorderPtr->solidGC != None) {
Tk_FreeGC(display, unixBorderPtr->solidGC);
}
}
void
Tk_3DVerticalBevel(tkwin, drawable, border, x, y, width, height,
leftBevel, relief)
Tk_Window tkwin;
Drawable drawable;
Tk_3DBorder border;
int
x, y, width, height;
int
leftBevel;
int
relief;
{
TkBorder *borderPtr = (TkBorder *) border;
GC left, right;
Display *display = Tk_Display(tkwin);
if
((borderPtr->lightGC == None) && (relief != TK_RELIEF_FLAT)) {
TkpGetShadows(borderPtr, tkwin);
}
if
(relief == TK_RELIEF_RAISED) {
XFillRectangle(display, drawable,
(leftBevel) ? borderPtr->lightGC : borderPtr->darkGC,
x, y, (unsigned) width, (unsigned) height);
}
else
if
(relief == TK_RELIEF_SUNKEN) {
XFillRectangle(display, drawable,
(leftBevel) ? borderPtr->darkGC : borderPtr->lightGC,
x, y, (unsigned) width, (unsigned) height);
}
else
if
(relief == TK_RELIEF_RIDGE) {
int
half;
left = borderPtr->lightGC;
right = borderPtr->darkGC;
ridgeGroove:
half = width/2;
if
(!leftBevel && (width & 1)) {
half++;
}
XFillRectangle(display, drawable, left, x, y, (unsigned) half,
(unsigned) height);
XFillRectangle(display, drawable, right, x+half, y,
(unsigned) (width-half), (unsigned) height);
}
else
if
(relief == TK_RELIEF_GROOVE) {
left = borderPtr->darkGC;
right = borderPtr->lightGC;
goto
ridgeGroove;
}
else
if
(relief == TK_RELIEF_FLAT) {
XFillRectangle(display, drawable, borderPtr->bgGC, x, y,
(unsigned) width, (unsigned) height);
}
else
if
(relief == TK_RELIEF_SOLID) {
UnixBorder *unixBorderPtr = (UnixBorder *) borderPtr;
if
(unixBorderPtr->solidGC == None) {
XGCValues gcValues;
gcValues.foreground = BlackPixelOfScreen(borderPtr->screen);
unixBorderPtr->solidGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
}
XFillRectangle(display, drawable, unixBorderPtr->solidGC, x, y,
(unsigned) width, (unsigned) height);
}
}
void
Tk_3DHorizontalBevel(tkwin, drawable, border, x, y, width, height,
leftIn, rightIn, topBevel, relief)
Tk_Window tkwin;
Drawable drawable;
Tk_3DBorder border;
int
x, y, width, height;
int
leftIn, rightIn;
int
topBevel;
int
relief;
{
TkBorder *borderPtr = (TkBorder *) border;
Display *display = Tk_Display(tkwin);
int
bottom, halfway, x1, x2, x1Delta, x2Delta;
UnixBorder *unixBorderPtr = (UnixBorder *) borderPtr;
GC topGC = None, bottomGC = None;
if
((borderPtr->lightGC == None) && (relief != TK_RELIEF_FLAT) &&
(relief != TK_RELIEF_SOLID)) {
TkpGetShadows(borderPtr, tkwin);
}
switch
(relief) {
case
TK_RELIEF_FLAT:
topGC = bottomGC = borderPtr->bgGC;
break
;
case
TK_RELIEF_GROOVE:
topGC = borderPtr->darkGC;
bottomGC = borderPtr->lightGC;
break
;
case
TK_RELIEF_RAISED:
topGC = bottomGC =
(topBevel) ? borderPtr->lightGC : borderPtr->darkGC;
break
;
case
TK_RELIEF_RIDGE:
topGC = borderPtr->lightGC;
bottomGC = borderPtr->darkGC;
break
;
case
TK_RELIEF_SOLID:
if
(unixBorderPtr->solidGC == None) {
XGCValues gcValues;
gcValues.foreground = BlackPixelOfScreen(borderPtr->screen);
unixBorderPtr->solidGC = Tk_GetGC(tkwin, GCForeground,
&gcValues);
}
XFillRectangle(display, drawable, unixBorderPtr->solidGC, x, y,
(unsigned) width, (unsigned) height);
return
;
case
TK_RELIEF_SUNKEN:
topGC = bottomGC =
(topBevel) ? borderPtr->darkGC : borderPtr->lightGC;
break
;
}
x1 = x;
if
(!leftIn) {
x1 += height;
}
x2 = x+width;
if
(!rightIn) {
x2 -= height;
}
x1Delta = (leftIn) ? 1 : -1;
x2Delta = (rightIn) ? -1 : 1;
halfway = y + height/2;
if
(!topBevel && (height & 1)) {
halfway++;
}
bottom = y + height;
for
( ; y < bottom; y++) {
if
(x1 < -32767)
x1 = -32767;
if
(x2 > 32767)
x2 = 32767;
if
(x1 < x2) {
XFillRectangle(display, drawable,
(y < halfway) ? topGC : bottomGC, x1, y,
(unsigned) (x2-x1), (unsigned) 1);
}
x1 += x1Delta;
x2 += x2Delta;
}
}
void
TkpGetShadows(borderPtr, tkwin)
TkBorder *borderPtr;
Tk_Window tkwin;
{
XColor lightColor, darkColor;
int
stressed, tmp1, tmp2;
int
r, g, b;
XGCValues gcValues;
if
(borderPtr->lightGC != None) {
return
;
}
stressed = TkpCmapStressed(tkwin, borderPtr->colormap);
if
(!stressed && (Tk_Depth(tkwin) >= 6)) {
r = (
int
) borderPtr->bgColorPtr->red;
g = (
int
) borderPtr->bgColorPtr->green;
b = (
int
) borderPtr->bgColorPtr->blue;
if
(r*0.5*r + g*1.0*g + b*0.28*b < MAX_INTENSITY*0.05*MAX_INTENSITY) {
darkColor.red = (MAX_INTENSITY + 3*r)/4;
darkColor.green = (MAX_INTENSITY + 3*g)/4;
darkColor.blue = (MAX_INTENSITY + 3*b)/4;
}
else
{
darkColor.red = (60 * r)/100;
darkColor.green = (60 * g)/100;
darkColor.blue = (60 * b)/100;
}
borderPtr->darkColorPtr = Tk_GetColorByValue(tkwin, &darkColor);
gcValues.foreground = borderPtr->darkColorPtr->pixel;
borderPtr->darkGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
if
(g > MAX_INTENSITY*0.95) {
lightColor.red = (90 * r)/100;
lightColor.green = (90 * g)/100;
lightColor.blue = (90 * b)/100;
}
else
{
tmp1 = (14 * r)/10;
if
(tmp1 > MAX_INTENSITY) {
tmp1 = MAX_INTENSITY;
}
tmp2 = (MAX_INTENSITY + r)/2;
lightColor.red = (tmp1 > tmp2) ? tmp1 : tmp2;
tmp1 = (14 * g)/10;
if
(tmp1 > MAX_INTENSITY) {
tmp1 = MAX_INTENSITY;
}
tmp2 = (MAX_INTENSITY + g)/2;
lightColor.green = (tmp1 > tmp2) ? tmp1 : tmp2;
tmp1 = (14 * b)/10;
if
(tmp1 > MAX_INTENSITY) {
tmp1 = MAX_INTENSITY;
}
tmp2 = (MAX_INTENSITY + b)/2;
lightColor.blue = (tmp1 > tmp2) ? tmp1 : tmp2;
}
borderPtr->lightColorPtr = Tk_GetColorByValue(tkwin, &lightColor);
gcValues.foreground = borderPtr->lightColorPtr->pixel;
borderPtr->lightGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
return
;
}
if
(borderPtr->shadow == None) {
borderPtr->shadow = Tk_GetBitmap((Tcl_Interp *) NULL, tkwin,
Tk_GetUid(
"gray50"
));
if
(borderPtr->shadow == None) {
panic(
"TkpGetShadows couldn't allocate bitmap for border"
);
}
}
if
(borderPtr->visual->map_entries > 2) {
gcValues.foreground = borderPtr->bgColorPtr->pixel;
gcValues.background = BlackPixelOfScreen(borderPtr->screen);
gcValues.stipple = borderPtr->shadow;
gcValues.fill_style = FillOpaqueStippled;
borderPtr->darkGC = Tk_GetGC(tkwin,
GCForeground|GCBackground|GCStipple|GCFillStyle, &gcValues);
gcValues.background = WhitePixelOfScreen(borderPtr->screen);
borderPtr->lightGC = Tk_GetGC(tkwin,
GCForeground|GCBackground|GCStipple|GCFillStyle, &gcValues);
return
;
}
gcValues.foreground = WhitePixelOfScreen(borderPtr->screen);
gcValues.background = BlackPixelOfScreen(borderPtr->screen);
gcValues.stipple = borderPtr->shadow;
gcValues.fill_style = FillOpaqueStippled;
borderPtr->lightGC = Tk_GetGC(tkwin,
GCForeground|GCBackground|GCStipple|GCFillStyle, &gcValues);
if
(borderPtr->bgColorPtr->pixel
== WhitePixelOfScreen(borderPtr->screen)) {
gcValues.foreground = BlackPixelOfScreen(borderPtr->screen);
borderPtr->darkGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
}
else
{
borderPtr->darkGC = borderPtr->lightGC;
borderPtr->lightGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
}
}