summaryrefslogtreecommitdiffstats
path: root/win/tkWinButton.c
diff options
context:
space:
mode:
Diffstat (limited to 'win/tkWinButton.c')
-rw-r--r--win/tkWinButton.c158
1 files changed, 82 insertions, 76 deletions
diff --git a/win/tkWinButton.c b/win/tkWinButton.c
index ee9b29e..16fcf9e 100644
--- a/win/tkWinButton.c
+++ b/win/tkWinButton.c
@@ -4,12 +4,12 @@
* This file implements the Windows specific portion of the button
* widgets.
*
- * Copyright (c) 1996 by Sun Microsystems, Inc.
+ * Copyright (c) 1996-1998 by Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkWinButton.c,v 1.2 1998/09/14 18:23:59 stanton Exp $
+ * RCS: @(#) $Id: tkWinButton.c,v 1.3 1999/04/16 01:51:49 stanton Exp $
*/
#define OEMRESOURCE
@@ -65,26 +65,20 @@ enum {
};
/*
- * Set to non-zero if this module is initialized.
+ * Cached information about the boxes bitmap, and the default border
+ * width for a button in string form for use in Tk_OptionSpecs for
+ * the various button widget classes.
*/
-static int initialized = 0;
-
-/*
- * Variables for the cached information about the boxes bitmap.
- */
-
-static BITMAPINFOHEADER *boxesPtr = NULL; /* Information about the bitmap. */
-static DWORD *boxesPalette = NULL; /* Pointer to color palette. */
-static LPSTR boxesBits = NULL; /* Pointer to bitmap data. */
-static DWORD boxHeight = 0, boxWidth = 0; /* Size of each sub-image. */
-
-/*
- * This variable holds the default border width for a button in string
- * form for use in a Tk_ConfigSpec.
- */
-
-static char defWidth[8];
+typedef struct ThreadSpecificData {
+ BITMAPINFOHEADER *boxesPtr; /* Information about the bitmap. */
+ DWORD *boxesPalette; /* Pointer to color palette. */
+ LPSTR boxesBits; /* Pointer to bitmap data. */
+ DWORD boxHeight; /* Height of each sub-image. */
+ DWORD boxWidth ; /* Width of each sub-image. */
+ char defWidth[TCL_INTEGER_SPACE];
+} ThreadSpecificData;
+static Tcl_ThreadDataKey dataKey;
/*
* Declarations for functions defined in this file.
@@ -99,7 +93,6 @@ static DWORD ComputeStyle _ANSI_ARGS_((WinButton* butPtr));
static Window CreateProc _ANSI_ARGS_((Tk_Window tkwin,
Window parent, ClientData instanceData));
static void InitBoxes _ANSI_ARGS_((void));
-static void UpdateButtonDefaults _ANSI_ARGS_((void));
/*
* The class procedure table for the button widgets.
@@ -146,65 +139,75 @@ InitBoxes()
HGLOBAL hblk;
LPBITMAPINFOHEADER newBitmap;
DWORD size;
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
hrsrc = FindResource(module, "buttons", RT_BITMAP);
if (hrsrc) {
hblk = LoadResource(module, hrsrc);
- boxesPtr = (LPBITMAPINFOHEADER)LockResource(hblk);
+ tsdPtr->boxesPtr = (LPBITMAPINFOHEADER)LockResource(hblk);
}
/*
* Copy the DIBitmap into writable memory.
*/
- if (boxesPtr != NULL && !(boxesPtr->biWidth % 4)
- && !(boxesPtr->biHeight % 2)) {
- size = boxesPtr->biSize + (1 << boxesPtr->biBitCount) * sizeof(RGBQUAD)
- + boxesPtr->biSizeImage;
+ if (tsdPtr->boxesPtr != NULL && !(tsdPtr->boxesPtr->biWidth % 4)
+ && !(tsdPtr->boxesPtr->biHeight % 2)) {
+ size = tsdPtr->boxesPtr->biSize + (1 << tsdPtr->boxesPtr->biBitCount)
+ * sizeof(RGBQUAD) + tsdPtr->boxesPtr->biSizeImage;
newBitmap = (LPBITMAPINFOHEADER) ckalloc(size);
- memcpy(newBitmap, boxesPtr, size);
- boxesPtr = newBitmap;
- boxWidth = boxesPtr->biWidth / 4;
- boxHeight = boxesPtr->biHeight / 2;
- boxesPalette = (DWORD*) (((LPSTR)boxesPtr) + boxesPtr->biSize);
- boxesBits = ((LPSTR)boxesPalette)
- + ((1 << boxesPtr->biBitCount) * sizeof(RGBQUAD));
+ memcpy(newBitmap, tsdPtr->boxesPtr, size);
+ tsdPtr->boxesPtr = newBitmap;
+ tsdPtr->boxWidth = tsdPtr->boxesPtr->biWidth / 4;
+ tsdPtr->boxHeight = tsdPtr->boxesPtr->biHeight / 2;
+ tsdPtr->boxesPalette = (DWORD*) (((LPSTR) tsdPtr->boxesPtr)
+ + tsdPtr->boxesPtr->biSize);
+ tsdPtr->boxesBits = ((LPSTR) tsdPtr->boxesPalette)
+ + ((1 << tsdPtr->boxesPtr->biBitCount) * sizeof(RGBQUAD));
} else {
- boxesPtr = NULL;
+ tsdPtr->boxesPtr = NULL;
}
}
/*
*----------------------------------------------------------------------
*
- * UpdateButtonDefaults --
+ * TkpButtonSetDefaults --
*
- * This function retrieves the current system defaults for
- * the button widgets.
+ * This procedure is invoked before option tables are created for
+ * buttons. It modifies some of the default values to match the
+ * current values defined for this platform.
*
* Results:
- * None.
+ * Some of the default values in *specPtr are modified.
*
* Side effects:
- * Updates the configuration defaults for buttons.
+ * Updates some of.
*
*----------------------------------------------------------------------
*/
void
-UpdateButtonDefaults()
+TkpButtonSetDefaults(specPtr)
+ Tk_OptionSpec *specPtr; /* Points to an array of option specs,
+ * terminated by one with type
+ * TK_OPTION_END. */
{
- Tk_ConfigSpec *specPtr;
- int width = GetSystemMetrics(SM_CXEDGE);
-
- if (width == 0) {
- width = 1;
+ int width;
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+
+ if (tsdPtr->defWidth[0] == 0) {
+ width = GetSystemMetrics(SM_CXEDGE);
+ if (width == 0) {
+ width = 1;
+ }
+ sprintf(tsdPtr->defWidth, "%d", width);
}
- sprintf(defWidth, "%d", width);
- for (specPtr = tkpButtonConfigSpecs; specPtr->type != TK_CONFIG_END;
- specPtr++) {
- if (specPtr->offset == Tk_Offset(TkButton, borderWidth)) {
- specPtr->defValue = defWidth;
+ for ( ; specPtr->type != TK_OPTION_END; specPtr++) {
+ if (specPtr->internalOffset == Tk_Offset(TkButton, borderWidth)) {
+ specPtr->defValue = tsdPtr->defWidth;
}
}
}
@@ -231,11 +234,6 @@ TkpCreateButton(tkwin)
{
WinButton *butPtr;
- if (!initialized) {
- UpdateButtonDefaults();
- initialized = 1;
- }
-
butPtr = (WinButton *)ckalloc(sizeof(WinButton));
butPtr->hwnd = NULL;
return (TkButton *) butPtr;
@@ -354,23 +352,28 @@ TkpDisplayButton(clientData)
* it is a flavor of button, so we offset
* the text to make the button appear to
* move up and down as the relief changes. */
+ DWORD *boxesPalette;
+
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ boxesPalette= tsdPtr->boxesPalette;
butPtr->flags &= ~REDRAW_PENDING;
if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
return;
}
border = butPtr->normalBorder;
- if ((butPtr->state == tkDisabledUid) && (butPtr->disabledFg != NULL)) {
+ if ((butPtr->state == STATE_DISABLED) && (butPtr->disabledFg != NULL)) {
gc = butPtr->disabledGC;
- } else if ((butPtr->state == tkActiveUid)
+ } else if ((butPtr->state == STATE_ACTIVE)
&& !Tk_StrictMotif(butPtr->tkwin)) {
gc = butPtr->activeTextGC;
border = butPtr->activeBorder;
} else {
gc = butPtr->normalTextGC;
}
- if ((butPtr->flags & SELECTED) && (butPtr->state != tkActiveUid)
+ if ((butPtr->flags & SELECTED) && (butPtr->state != STATE_ACTIVE)
&& (butPtr->selectBorder != NULL) && !butPtr->indicatorOn) {
border = butPtr->selectBorder;
}
@@ -391,7 +394,7 @@ TkpDisplayButton(clientData)
*/
if (butPtr->type == TYPE_BUTTON) {
- defaultWidth = ((butPtr->defaultState == tkActiveUid)
+ defaultWidth = ((butPtr->defaultState == DEFAULT_ACTIVE)
? butPtr->highlightWidth : 0);
offset = 1;
} else {
@@ -500,17 +503,17 @@ TkpDisplayButton(clientData)
*/
if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn
- && boxesPtr) {
+ && tsdPtr->boxesPtr) {
int xSrc, ySrc;
x -= butPtr->indicatorSpace;
y -= butPtr->indicatorDiameter / 2;
- xSrc = (butPtr->flags & SELECTED) ? boxWidth : 0;
- if (butPtr->state == tkActiveUid) {
- xSrc += boxWidth*2;
+ xSrc = (butPtr->flags & SELECTED) ? tsdPtr->boxWidth : 0;
+ if (butPtr->state == STATE_ACTIVE) {
+ xSrc += tsdPtr->boxWidth*2;
}
- ySrc = (butPtr->type == TYPE_RADIO_BUTTON) ? 0 : boxHeight;
+ ySrc = (butPtr->type == TYPE_RADIO_BUTTON) ? 0 : tsdPtr->boxHeight;
/*
* Update the palette in the boxes bitmap to reflect the current
@@ -530,7 +533,7 @@ TkpDisplayButton(clientData)
border, TK_3D_LIGHT2));
boxesPalette[PAL_BOTTOM_OUTER] = FlipColor(TkWinGetBorderPixels(tkwin,
border, TK_3D_LIGHT_GC));
- if (butPtr->state == tkDisabledUid) {
+ if (butPtr->state == STATE_DISABLED) {
boxesPalette[PAL_INTERIOR] = FlipColor(TkWinGetBorderPixels(tkwin,
border, TK_3D_LIGHT2));
} else if (butPtr->selectBorder != NULL) {
@@ -543,9 +546,10 @@ TkpDisplayButton(clientData)
border, TK_3D_FLAT_GC));
dc = TkWinGetDrawableDC(butPtr->display, pixmap, &state);
- StretchDIBits(dc, x, y, boxWidth, boxHeight, xSrc, ySrc,
- boxWidth, boxHeight, boxesBits, (LPBITMAPINFO)boxesPtr,
- DIB_RGB_COLORS, SRCCOPY);
+ StretchDIBits(dc, x, y, tsdPtr->boxWidth, tsdPtr->boxHeight,
+ xSrc, ySrc, tsdPtr->boxWidth, tsdPtr->boxHeight,
+ tsdPtr->boxesBits, (LPBITMAPINFO) tsdPtr->boxesPtr,
+ DIB_RGB_COLORS, SRCCOPY);
TkWinReleaseDrawableDC(pixmap, dc, &state);
}
@@ -556,7 +560,7 @@ TkpDisplayButton(clientData)
* must temporarily modify the GC.
*/
- if ((butPtr->state == tkDisabledUid)
+ if ((butPtr->state == STATE_DISABLED)
&& ((butPtr->disabledFg == NULL) || (butPtr->image != NULL))) {
if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn
&& (butPtr->selectBorder != NULL)) {
@@ -636,6 +640,8 @@ TkpComputeButtonGeometry(butPtr)
{
int width, height, avgWidth;
Tk_FontMetrics fm;
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (butPtr->highlightWidth < 0) {
butPtr->highlightWidth = 0;
@@ -643,7 +649,7 @@ TkpComputeButtonGeometry(butPtr)
butPtr->inset = butPtr->highlightWidth + butPtr->borderWidth;
butPtr->indicatorSpace = 0;
- if (!boxesPtr) {
+ if (!tsdPtr->boxesPtr) {
InitBoxes();
}
@@ -657,8 +663,8 @@ TkpComputeButtonGeometry(butPtr)
height = butPtr->height;
}
if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
- butPtr->indicatorSpace = boxWidth * 2;
- butPtr->indicatorDiameter = boxHeight;
+ butPtr->indicatorSpace = tsdPtr->boxWidth * 2;
+ butPtr->indicatorDiameter = tsdPtr->boxHeight;
}
} else if (butPtr->bitmap != None) {
Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
@@ -666,8 +672,8 @@ TkpComputeButtonGeometry(butPtr)
} else {
Tk_FreeTextLayout(butPtr->textLayout);
butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
- butPtr->text, -1, butPtr->wrapLength, butPtr->justify, 0,
- &butPtr->textWidth, &butPtr->textHeight);
+ Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength,
+ butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);
width = butPtr->textWidth;
height = butPtr->textHeight;
@@ -682,7 +688,7 @@ TkpComputeButtonGeometry(butPtr)
}
if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
- butPtr->indicatorDiameter = boxHeight;
+ butPtr->indicatorDiameter = tsdPtr->boxHeight;
butPtr->indicatorSpace = butPtr->indicatorDiameter + avgWidth;
}
@@ -788,7 +794,7 @@ ButtonProc(hwnd, message, wParam, lParam)
case BN_CLICKED: {
int code;
Tcl_Interp *interp = butPtr->info.interp;
- if (butPtr->info.state != tkDisabledUid) {
+ if (butPtr->info.state != STATE_DISABLED) {
Tcl_Preserve((ClientData)interp);
code = TkInvokeButton((TkButton*)butPtr);
if (code != TCL_OK && code != TCL_CONTINUE