summaryrefslogtreecommitdiffstats
path: root/tk8.6/unix/tkUnixButton.c
diff options
context:
space:
mode:
Diffstat (limited to 'tk8.6/unix/tkUnixButton.c')
-rw-r--r--tk8.6/unix/tkUnixButton.c1028
1 files changed, 0 insertions, 1028 deletions
diff --git a/tk8.6/unix/tkUnixButton.c b/tk8.6/unix/tkUnixButton.c
deleted file mode 100644
index 6a99124..0000000
--- a/tk8.6/unix/tkUnixButton.c
+++ /dev/null
@@ -1,1028 +0,0 @@
-/*
- * tkUnixButton.c --
- *
- * This file implements the Unix specific portion of the button widgets.
- *
- * Copyright (c) 1996-1997 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.
- */
-
-#include "tkInt.h"
-#include "tkButton.h"
-#include "tk3d.h"
-
-/*
- * Shared with menu widget.
- */
-
-MODULE_SCOPE void TkpDrawCheckIndicator(Tk_Window tkwin,
- Display *display, Drawable d, int x, int y,
- Tk_3DBorder bgBorder, XColor *indicatorColor,
- XColor *selectColor, XColor *disColor, int on,
- int disabled, int mode);
-
-/*
- * Declaration of Unix specific button structure.
- */
-
-typedef struct UnixButton {
- TkButton info; /* Generic button info. */
-} UnixButton;
-
-/*
- * The class function table for the button widgets.
- */
-
-const Tk_ClassProcs tkpButtonProcs = {
- sizeof(Tk_ClassProcs), /* size */
- TkButtonWorldChanged, /* worldChangedProc */
- NULL, /* createProc */
- NULL /* modalProc */
-};
-
-/*
- * The button image.
- * The header info here is ignored, it's the image that's important. The
- * colors will be applied as follows:
- * A = Background
- * B = Background
- * C = 3D light
- * D = selectColor
- * E = 3D dark
- * F = Background
- * G = Indicator Color
- * H = disabled Indicator Color
- */
-
-/* XPM */
-static const char *const button_images[] = {
- /* width height ncolors chars_per_pixel */
- "52 26 7 1",
- /* colors */
- "A c #808000000000",
- "B c #000080800000",
- "C c #808080800000",
- "D c #000000008080",
- "E c #808000008080",
- "F c #000080808080",
- "G c #000000000000",
- "H c #000080800000",
- /* pixels */
- "AAAAAAAAAAAABAAAAAAAAAAAABAAAAAAAAAAAABAAAAAAAAAAAAB",
- "AEEEEEEEEEECBAEEEEEEEEEECBAEEEEEEEEEECBAEEEEEEEEEECB",
- "AEDDDDDDDDDCBAEDDDDDDDDDCBAEFFFFFFFFFCBAEFFFFFFFFFCB",
- "AEDDDDDDDDDCBAEDDDDDDDGDCBAEFFFFFFFFFCBAEFFFFFFFHFCB",
- "AEDDDDDDDDDCBAEDDDDDDGGDCBAEFFFFFFFFFCBAEFFFFFFHHFCB",
- "AEDDDDDDDDDCBAEDGDDDGGGDCBAEFFFFFFFFFCBAEFHFFFHHHFCB",
- "AEDDDDDDDDDCBAEDGGDGGGDDCBAEFFFFFFFFFCBAEFHHFHHHFFCB",
- "AEDDDDDDDDDCBAEDGGGGGDDDCBAEFFFFFFFFFCBAEFHHHHHFFFCB",
- "AEDDDDDDDDDCBAEDDGGGDDDDCBAEFFFFFFFFFCBAEFFHHHFFFFCB",
- "AEDDDDDDDDDCBAEDDDGDDDDDCBAEFFFFFFFFFCBAEFFFHFFFFFCB",
- "AEDDDDDDDDDCBAEDDDDDDDDDCBAEFFFFFFFFFCBAEFFFFFFFFFCB",
- "ACCCCCCCCCCCBACCCCCCCCCCCBACCCCCCCCCCCBACCCCCCCCCCCB",
- "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
- "FFFFAAAAFFFFFFFFFAAAAFFFFFFFFFAAAAFFFFFFFFFAAAAFFFFF",
- "FFAAEEEEAAFFFFFAAEEEEAAFFFFFAAEEEEAAFFFFFAAEEEEAAFFF",
- "FAEEDDDDEEBFFFAEEDDDDEEBFFFAEEFFFFEEBFFFAEEFFFFEEBFF",
- "FAEDDDDDDCBFFFAEDDDDDDCBFFFAEFFFFFFCBFFFAEFFFFFFCBFF",
- "AEDDDDDDDDCBFAEDDDGGDDDCBFAEFFFFFFFFCBFAEFFFHHFFFCBF",
- "AEDDDDDDDDCBFAEDDGGGGDDCBFAEFFFFFFFFCBFAEFFHHHHFFCBF",
- "AEDDDDDDDDCBFAEDDGGGGDDCBFAEFFFFFFFFCBFAEFFHHHHFFCBF",
- "AEDDDDDDDDCBFAEDDDGGDDDCBFAEFFFFFFFFCBFAEFFFHHFFFCBF",
- "FAEDDDDDDCBFFFAEDDDDDDCBFFFAEFFFFFFCBFFFAEFFFFFFCBFF",
- "FACCDDDDCCBFFFACCDDDDCCBFFFACCFFFFCCBFFFACCFFFFCCBFF",
- "FFBBCCCCBBFFFFFBBCCCCBBFFFFFBBCCCCBBFFFFFBBCCCCBBFFF",
- "FFFFBBBBFFFFFFFFFBBBBFFFFFFFFFBBBBFFFFFFFFFBBBBFFFFF",
- "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
-};
-
-/*
- * Sizes and offsets into above XPM file.
- */
-
-#define CHECK_BUTTON_DIM 13
-#define CHECK_MENU_DIM 9
-#define CHECK_START 9
-#define CHECK_ON_OFFSET 13
-#define CHECK_OFF_OFFSET 0
-#define CHECK_DISON_OFFSET 39
-#define CHECK_DISOFF_OFFSET 26
-#define RADIO_BUTTON_DIM 12
-#define RADIO_MENU_DIM 6
-#define RADIO_WIDTH 13
-#define RADIO_START 22
-#define RADIO_ON_OFFSET 13
-#define RADIO_OFF_OFFSET 0
-#define RADIO_DISON_OFFSET 39
-#define RADIO_DISOFF_OFFSET 26
-
-/*
- * Indicator Draw Modes
- */
-
-#define CHECK_BUTTON 0
-#define CHECK_MENU 1
-#define RADIO_BUTTON 2
-#define RADIO_MENU 3
-
-/*
- *----------------------------------------------------------------------
- *
- * TkpDrawCheckIndicator -
- *
- * Draws the checkbox image in the drawable at the (x,y) location, value,
- * and state given. This routine is use by the button and menu widgets
- *
- * Results:
- * None.
- *
- * Side effects:
- * An image is drawn in the drawable at the location given.
- *
- *----------------------------------------------------------------------
- */
-
-void
-TkpDrawCheckIndicator(
- Tk_Window tkwin, /* handle for resource alloc */
- Display *display,
- Drawable d, /* what to draw on */
- int x, int y, /* where to draw */
- Tk_3DBorder bgBorder, /* colors of the border */
- XColor *indicatorColor, /* color of the indicator */
- XColor *selectColor, /* color when selected */
- XColor *disableColor, /* color when disabled */
- int on, /* are we on? */
- int disabled, /* are we disabled? */
- int mode) /* kind of indicator to draw */
-{
- int ix, iy;
- int dim;
- int imgsel, imgstart;
- TkBorder *bg_brdr = (TkBorder*)bgBorder;
- XGCValues gcValues;
- GC copyGC;
- unsigned long imgColors[8];
- XImage *img;
- Pixmap pixmap;
- int depth;
-
- /*
- * Sanity check.
- */
-
- if (tkwin == NULL || display == None || d == None || bgBorder == NULL
- || indicatorColor == NULL) {
- return;
- }
-
- if (disableColor == NULL) {
- disableColor = bg_brdr->bgColorPtr;
- }
-
- if (selectColor == NULL) {
- selectColor = bg_brdr->bgColorPtr;
- }
-
- depth = Tk_Depth(tkwin);
-
- /*
- * Compute starting point and dimensions of image inside button_images to
- * be used.
- */
-
- switch (mode) {
- default:
- case CHECK_BUTTON:
- imgsel = on == 2 ? CHECK_DISON_OFFSET :
- on == 1 ? CHECK_ON_OFFSET : CHECK_OFF_OFFSET;
- imgsel += disabled && on != 2 ? CHECK_DISOFF_OFFSET : 0;
- imgstart = CHECK_START;
- dim = CHECK_BUTTON_DIM;
- break;
-
- case CHECK_MENU:
- imgsel = on == 2 ? CHECK_DISOFF_OFFSET :
- on == 1 ? CHECK_ON_OFFSET : CHECK_OFF_OFFSET;
- imgsel += disabled && on != 2 ? CHECK_DISOFF_OFFSET : 0;
- imgstart = CHECK_START + 2;
- imgsel += 2;
- dim = CHECK_MENU_DIM;
- break;
-
- case RADIO_BUTTON:
- imgsel = on == 2 ? RADIO_DISON_OFFSET :
- on==1 ? RADIO_ON_OFFSET : RADIO_OFF_OFFSET;
- imgsel += disabled && on != 2 ? RADIO_DISOFF_OFFSET : 0;
- imgstart = RADIO_START;
- dim = RADIO_BUTTON_DIM;
- break;
-
- case RADIO_MENU:
- imgsel = on == 2 ? RADIO_DISOFF_OFFSET :
- on==1 ? RADIO_ON_OFFSET : RADIO_OFF_OFFSET;
- imgsel += disabled && on != 2 ? RADIO_DISOFF_OFFSET : 0;
- imgstart = RADIO_START + 3;
- imgsel += 3;
- dim = RADIO_MENU_DIM;
- break;
- }
-
- /*
- * Allocate the drawing areas to use. Note that we use double-buffering
- * here because not all code paths leading to this function do so.
- */
-
- pixmap = Tk_GetPixmap(display, d, dim, dim, depth);
- if (pixmap == None) {
- return;
- }
-
- x -= dim/2;
- y -= dim/2;
-
- img = XGetImage(display, pixmap, 0, 0,
- (unsigned int)dim, (unsigned int)dim, AllPlanes, ZPixmap);
- if (img == NULL) {
- return;
- }
-
- /*
- * Set up the color mapping table.
- */
-
- TkpGetShadows(bg_brdr, tkwin);
-
- imgColors[0 /*A*/] =
- Tk_GetColorByValue(tkwin, bg_brdr->bgColorPtr)->pixel;
- imgColors[1 /*B*/] =
- Tk_GetColorByValue(tkwin, bg_brdr->bgColorPtr)->pixel;
- imgColors[2 /*C*/] = (bg_brdr->lightColorPtr != NULL) ?
- Tk_GetColorByValue(tkwin, bg_brdr->lightColorPtr)->pixel :
- WhitePixelOfScreen(bg_brdr->screen);
- imgColors[3 /*D*/] =
- Tk_GetColorByValue(tkwin, selectColor)->pixel;
- imgColors[4 /*E*/] = (bg_brdr->darkColorPtr != NULL) ?
- Tk_GetColorByValue(tkwin, bg_brdr->darkColorPtr)->pixel :
- BlackPixelOfScreen(bg_brdr->screen);
- imgColors[5 /*F*/] =
- Tk_GetColorByValue(tkwin, bg_brdr->bgColorPtr)->pixel;
- imgColors[6 /*G*/] =
- Tk_GetColorByValue(tkwin, indicatorColor)->pixel;
- imgColors[7 /*H*/] =
- Tk_GetColorByValue(tkwin, disableColor)->pixel;
-
- /*
- * Create the image, painting it into an XImage one pixel at a time.
- */
-
- for (iy=0 ; iy<dim ; iy++) {
- for (ix=0 ; ix<dim ; ix++) {
- XPutPixel(img, ix, iy,
- imgColors[button_images[imgstart+iy][imgsel+ix] - 'A']);
- }
- }
-
- /*
- * Copy onto our target drawable surface.
- */
-
- memset(&gcValues, 0, sizeof(gcValues));
- gcValues.background = bg_brdr->bgColorPtr->pixel;
- gcValues.graphics_exposures = False;
- copyGC = Tk_GetGC(tkwin, 0, &gcValues);
-
- XPutImage(display, pixmap, copyGC, img, 0, 0, 0, 0,
- (unsigned)dim, (unsigned)dim);
- XCopyArea(display, pixmap, d, copyGC, 0, 0,
- (unsigned)dim, (unsigned)dim, x, y);
-
- /*
- * Tidy up.
- */
-
- Tk_FreeGC(display, copyGC);
- XDestroyImage(img);
- Tk_FreePixmap(display, pixmap);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TkpCreateButton --
- *
- * Allocate a new TkButton structure.
- *
- * Results:
- * Returns a newly allocated TkButton structure.
- *
- * Side effects:
- * Registers an event handler for the widget.
- *
- *----------------------------------------------------------------------
- */
-
-TkButton *
-TkpCreateButton(
- Tk_Window tkwin)
-{
- UnixButton *butPtr = ckalloc(sizeof(UnixButton));
-
- return (TkButton *) butPtr;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TkpDisplayButton --
- *
- * This function is invoked to display a button widget. It is normally
- * invoked as an idle handler.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Commands are output to X to display the button in its current mode.
- * The REDRAW_PENDING flag is cleared.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-ShiftByOffset(
- TkButton *butPtr,
- int relief,
- int *x, /* shift this x coordinate */
- int *y, /* shift this y coordinate */
- int width, /* width of image/text */
- int height) /* height of image/text */
-{
- if (relief != TK_RELIEF_RAISED
- && butPtr->type == TYPE_BUTTON
- && !Tk_StrictMotif(butPtr->tkwin)) {
- int shiftX;
- int shiftY;
-
- /*
- * This is an (unraised) button widget, so we offset the text to make
- * the button appear to move up and down as the relief changes.
- */
-
- shiftX = shiftY = (relief == TK_RELIEF_SUNKEN) ? 2 : 1;
-
- if (relief != TK_RELIEF_RIDGE) {
- /*
- * Take back one pixel if the padding is even, otherwise the
- * content will be displayed too far right/down.
- */
-
- if ((Tk_Width(butPtr->tkwin) - width) % 2 == 0) {
- shiftX -= 1;
- }
- if ((Tk_Height(butPtr->tkwin) - height) % 2 == 0) {
- shiftY -= 1;
- }
- }
-
- *x += shiftX;
- *y += shiftY;
- }
-}
-
-void
-TkpDisplayButton(
- ClientData clientData) /* Information about widget. */
-{
- register TkButton *butPtr = (TkButton *) clientData;
- GC gc;
- Tk_3DBorder border;
- Pixmap pixmap;
- int x = 0; /* Initialization only needed to stop compiler
- * warning. */
- int y, relief;
- Tk_Window tkwin = butPtr->tkwin;
- int width = 0, height = 0, fullWidth, fullHeight;
- int textXOffset, textYOffset;
- int haveImage = 0, haveText = 0;
- int imageWidth, imageHeight;
- int imageXOffset = 0, imageYOffset = 0;
- /* image information that will be used to
- * restrict disabled pixmap as well */
-
- butPtr->flags &= ~REDRAW_PENDING;
- if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
- return;
- }
-
- border = butPtr->normalBorder;
- if ((butPtr->state == STATE_DISABLED) && (butPtr->disabledFg != NULL)) {
- gc = butPtr->disabledGC;
- } 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->selectBorder != NULL)
- && !butPtr->indicatorOn) {
- border = butPtr->selectBorder;
- }
-
- /*
- * Override the relief specified for the button if this is a checkbutton
- * or radiobutton and there's no indicator. The new relief is as follows:
- * If the button is select --> "sunken"
- * If relief==overrelief --> relief
- * Otherwise --> overrelief
- *
- * The effect we are trying to achieve is as follows:
- *
- * value mouse-over? --> relief
- * ------- ------------ --------
- * off no flat
- * off yes raised
- * on no sunken
- * on yes sunken
- *
- * This is accomplished by configuring the checkbutton or radiobutton like
- * this:
- *
- * -indicatoron 0 -overrelief raised -offrelief flat
- *
- * Bindings (see library/button.tcl) will copy the -overrelief into
- * -relief on mouseover. Hence, we can tell if we are in mouse-over by
- * comparing relief against overRelief. This is an aweful kludge, but it
- * gives use the desired behavior while keeping the code backwards
- * compatible.
- */
-
- relief = butPtr->relief;
- if ((butPtr->type >= TYPE_CHECK_BUTTON) && !butPtr->indicatorOn) {
- if (butPtr->flags & SELECTED) {
- relief = TK_RELIEF_SUNKEN;
- } else if (butPtr->overRelief != relief) {
- relief = butPtr->offRelief;
- }
- }
-
- /*
- * In order to avoid screen flashes, this function redraws the button in a
- * pixmap, then copies the pixmap to the screen in a single operation.
- * This means that there's no point in time where the on-screen image has
- * been cleared.
- */
-
- pixmap = Tk_GetPixmap(butPtr->display, Tk_WindowId(tkwin),
- Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin));
- Tk_Fill3DRectangle(tkwin, pixmap, border, 0, 0, Tk_Width(tkwin),
- Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
-
- /*
- * Display image or bitmap or text for button.
- */
-
- if (butPtr->image != NULL) {
- Tk_SizeOfImage(butPtr->image, &width, &height);
- haveImage = 1;
- } else if (butPtr->bitmap != None) {
- Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
- haveImage = 1;
- }
- imageWidth = width;
- imageHeight = height;
-
- haveText = (butPtr->textWidth != 0 && butPtr->textHeight != 0);
-
- if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) {
- textXOffset = 0;
- textYOffset = 0;
- fullWidth = 0;
- fullHeight = 0;
-
- switch ((enum compound) butPtr->compound) {
- case COMPOUND_TOP:
- case COMPOUND_BOTTOM:
- /*
- * Image is above or below text.
- */
-
- if (butPtr->compound == COMPOUND_TOP) {
- textYOffset = height + butPtr->padY;
- } else {
- imageYOffset = butPtr->textHeight + butPtr->padY;
- }
- fullHeight = height + butPtr->textHeight + butPtr->padY;
- fullWidth = (width > butPtr->textWidth ? width :
- butPtr->textWidth);
- textXOffset = (fullWidth - butPtr->textWidth)/2;
- imageXOffset = (fullWidth - width)/2;
- break;
- case COMPOUND_LEFT:
- case COMPOUND_RIGHT:
- /*
- * Image is left or right of text.
- */
-
- if (butPtr->compound == COMPOUND_LEFT) {
- textXOffset = width + butPtr->padX;
- } else {
- imageXOffset = butPtr->textWidth + butPtr->padX;
- }
- fullWidth = butPtr->textWidth + butPtr->padX + width;
- fullHeight = (height > butPtr->textHeight ? height :
- butPtr->textHeight);
- textYOffset = (fullHeight - butPtr->textHeight)/2;
- imageYOffset = (fullHeight - height)/2;
- break;
- case COMPOUND_CENTER:
- /*
- * Image and text are superimposed.
- */
-
- fullWidth = (width > butPtr->textWidth ? width :
- butPtr->textWidth);
- fullHeight = (height > butPtr->textHeight ? height :
- butPtr->textHeight);
- textXOffset = (fullWidth - butPtr->textWidth)/2;
- imageXOffset = (fullWidth - width)/2;
- textYOffset = (fullHeight - butPtr->textHeight)/2;
- imageYOffset = (fullHeight - height)/2;
- break;
- case COMPOUND_NONE:
- break;
- }
-
- TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY,
- butPtr->indicatorSpace + fullWidth, fullHeight, &x, &y);
-
- x += butPtr->indicatorSpace;
- ShiftByOffset(butPtr, relief, &x, &y, width, height);
- imageXOffset += x;
- imageYOffset += y;
-
- if (butPtr->image != NULL) {
- /*
- * Do boundary clipping, so that Tk_RedrawImage is passed valid
- * coordinates. [Bug 979239]
- */
-
- if (imageXOffset < 0) {
- imageXOffset = 0;
- }
- if (imageYOffset < 0) {
- imageYOffset = 0;
- }
- if (width > Tk_Width(tkwin)) {
- width = Tk_Width(tkwin);
- }
- if (height > Tk_Height(tkwin)) {
- height = Tk_Height(tkwin);
- }
- if ((width + imageXOffset) > Tk_Width(tkwin)) {
- imageXOffset = Tk_Width(tkwin) - width;
- }
- if ((height + imageYOffset) > Tk_Height(tkwin)) {
- imageYOffset = Tk_Height(tkwin) - height;
- }
-
- if ((butPtr->selectImage != NULL) && (butPtr->flags & SELECTED)) {
- Tk_RedrawImage(butPtr->selectImage, 0, 0,
- width, height, pixmap, imageXOffset, imageYOffset);
- } else if ((butPtr->tristateImage != NULL) && (butPtr->flags & TRISTATED)) {
- Tk_RedrawImage(butPtr->tristateImage, 0, 0,
- width, height, pixmap, imageXOffset, imageYOffset);
- } else {
- Tk_RedrawImage(butPtr->image, 0, 0, width,
- height, pixmap, imageXOffset, imageYOffset);
- }
- } else {
- XSetClipOrigin(butPtr->display, gc, imageXOffset, imageYOffset);
- XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, gc,
- 0, 0, (unsigned int) width, (unsigned int) height,
- imageXOffset, imageYOffset, 1);
- XSetClipOrigin(butPtr->display, gc, 0, 0);
- }
-
- Tk_DrawTextLayout(butPtr->display, pixmap, gc,
- butPtr->textLayout, x + textXOffset, y + textYOffset, 0, -1);
- Tk_UnderlineTextLayout(butPtr->display, pixmap, gc,
- butPtr->textLayout, x + textXOffset, y + textYOffset,
- butPtr->underline);
- y += fullHeight/2;
- } else {
- if (haveImage) {
- TkComputeAnchor(butPtr->anchor, tkwin, 0, 0,
- butPtr->indicatorSpace + width, height, &x, &y);
- x += butPtr->indicatorSpace;
- ShiftByOffset(butPtr, relief, &x, &y, width, height);
- imageXOffset += x;
- imageYOffset += y;
- if (butPtr->image != NULL) {
- /*
- * Do boundary clipping, so that Tk_RedrawImage is passed
- * valid coordinates. [Bug 979239]
- */
-
- if (imageXOffset < 0) {
- imageXOffset = 0;
- }
- if (imageYOffset < 0) {
- imageYOffset = 0;
- }
- if (width > Tk_Width(tkwin)) {
- width = Tk_Width(tkwin);
- }
- if (height > Tk_Height(tkwin)) {
- height = Tk_Height(tkwin);
- }
- if ((width + imageXOffset) > Tk_Width(tkwin)) {
- imageXOffset = Tk_Width(tkwin) - width;
- }
- if ((height + imageYOffset) > Tk_Height(tkwin)) {
- imageYOffset = Tk_Height(tkwin) - height;
- }
-
- if ((butPtr->selectImage != NULL) &&
- (butPtr->flags & SELECTED)) {
- Tk_RedrawImage(butPtr->selectImage, 0, 0, width,
- height, pixmap, imageXOffset, imageYOffset);
- } else if ((butPtr->tristateImage != NULL) &&
- (butPtr->flags & TRISTATED)) {
- Tk_RedrawImage(butPtr->tristateImage, 0, 0, width,
- height, pixmap, imageXOffset, imageYOffset);
- } else {
- Tk_RedrawImage(butPtr->image, 0, 0, width, height, pixmap,
- imageXOffset, imageYOffset);
- }
- } else {
- XSetClipOrigin(butPtr->display, gc, x, y);
- XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, gc, 0, 0,
- (unsigned int) width, (unsigned int) height, x, y, 1);
- XSetClipOrigin(butPtr->display, gc, 0, 0);
- }
- y += height/2;
- } else {
- TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY,
- butPtr->indicatorSpace + butPtr->textWidth,
- butPtr->textHeight, &x, &y);
-
- x += butPtr->indicatorSpace;
- ShiftByOffset(butPtr, relief, &x, &y, width, height);
- Tk_DrawTextLayout(butPtr->display, pixmap, gc, butPtr->textLayout,
- x, y, 0, -1);
- Tk_UnderlineTextLayout(butPtr->display, pixmap, gc,
- butPtr->textLayout, x, y, butPtr->underline);
- y += butPtr->textHeight/2;
- }
- }
-
- /*
- * Draw the indicator for check buttons and radio buttons. At this point,
- * x and y refer to the top-left corner of the text or image or bitmap.
- */
-
- if ((butPtr->type == TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
- if (butPtr->indicatorDiameter > 2*butPtr->borderWidth) {
- TkBorder *selBorder = (TkBorder *) butPtr->selectBorder;
- XColor *selColor = NULL;
-
- if (selBorder != NULL) {
- selColor = selBorder->bgColorPtr;
- }
- x -= butPtr->indicatorSpace/2;
- y = Tk_Height(tkwin)/2;
- TkpDrawCheckIndicator(tkwin, butPtr->display, pixmap, x, y,
- border, butPtr->normalFg, selColor, butPtr->disabledFg,
- ((butPtr->flags & SELECTED) ? 1 :
- (butPtr->flags & TRISTATED) ? 2 : 0),
- (butPtr->state == STATE_DISABLED), CHECK_BUTTON);
- }
- } else if ((butPtr->type == TYPE_RADIO_BUTTON) && butPtr->indicatorOn) {
- if (butPtr->indicatorDiameter > 2*butPtr->borderWidth) {
- TkBorder *selBorder = (TkBorder *) butPtr->selectBorder;
- XColor *selColor = NULL;
-
- if (selBorder != NULL) {
- selColor = selBorder->bgColorPtr;
- }
- x -= butPtr->indicatorSpace/2;
- y = Tk_Height(tkwin)/2;
- TkpDrawCheckIndicator(tkwin, butPtr->display, pixmap, x, y,
- border, butPtr->normalFg, selColor, butPtr->disabledFg,
- ((butPtr->flags & SELECTED) ? 1 :
- (butPtr->flags & TRISTATED) ? 2 : 0),
- (butPtr->state == STATE_DISABLED), RADIO_BUTTON);
- }
- }
-
- /*
- * If the button is disabled with a stipple rather than a special
- * foreground color, generate the stippled effect. If the widget is
- * selected and we use a different background color when selected, must
- * temporarily modify the GC so the stippling is the right color.
- */
-
- if ((butPtr->state == STATE_DISABLED)
- && ((butPtr->disabledFg == NULL) || (butPtr->image != NULL))) {
- if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn
- && (butPtr->selectBorder != NULL)) {
- XSetForeground(butPtr->display, butPtr->stippleGC,
- Tk_3DBorderColor(butPtr->selectBorder)->pixel);
- }
-
- /*
- * Stipple the whole button if no disabledFg was specified, otherwise
- * restrict stippling only to displayed image
- */
-
- if (butPtr->disabledFg == NULL) {
- XFillRectangle(butPtr->display, pixmap, butPtr->stippleGC, 0, 0,
- (unsigned) Tk_Width(tkwin), (unsigned) Tk_Height(tkwin));
- } else {
- XFillRectangle(butPtr->display, pixmap, butPtr->stippleGC,
- imageXOffset, imageYOffset,
- (unsigned) imageWidth, (unsigned) imageHeight);
- }
- if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn
- && (butPtr->selectBorder != NULL)) {
- XSetForeground(butPtr->display, butPtr->stippleGC,
- Tk_3DBorderColor(butPtr->normalBorder)->pixel);
- }
- }
-
- /*
- * Draw the border and traversal highlight last. This way, if the button's
- * contents overflow they'll be covered up by the border. This code is
- * complicated by the possible combinations of focus highlight and default
- * rings. We draw the focus and highlight rings using the highlight border
- * and highlight foreground color.
- */
-
- if (relief != TK_RELIEF_FLAT) {
- int inset = butPtr->highlightWidth;
-
- if (butPtr->defaultState == DEFAULT_ACTIVE) {
- /*
- * Draw the default ring with 2 pixels of space between the
- * default ring and the button and the default ring and the focus
- * ring. Note that we need to explicitly draw the space in the
- * highlightBorder color to ensure that we overwrite any overflow
- * text and/or a different button background color.
- */
-
- Tk_Draw3DRectangle(tkwin, pixmap, butPtr->highlightBorder, inset,
- inset, Tk_Width(tkwin) - 2*inset,
- Tk_Height(tkwin) - 2*inset, 2, TK_RELIEF_FLAT);
- inset += 2;
- Tk_Draw3DRectangle(tkwin, pixmap, butPtr->highlightBorder, inset,
- inset, Tk_Width(tkwin) - 2*inset,
- Tk_Height(tkwin) - 2*inset, 1, TK_RELIEF_SUNKEN);
- inset++;
- Tk_Draw3DRectangle(tkwin, pixmap, butPtr->highlightBorder, inset,
- inset, Tk_Width(tkwin) - 2*inset,
- Tk_Height(tkwin) - 2*inset, 2, TK_RELIEF_FLAT);
-
- inset += 2;
- } else if (butPtr->defaultState == DEFAULT_NORMAL) {
- /*
- * Leave room for the default ring and write over any text or
- * background color.
- */
-
- Tk_Draw3DRectangle(tkwin, pixmap, butPtr->highlightBorder, 0,
- 0, Tk_Width(tkwin), Tk_Height(tkwin), 5, TK_RELIEF_FLAT);
- inset += 5;
- }
-
- /*
- * Draw the button border.
- */
-
- Tk_Draw3DRectangle(tkwin, pixmap, border, inset, inset,
- Tk_Width(tkwin) - 2*inset, Tk_Height(tkwin) - 2*inset,
- butPtr->borderWidth, relief);
- }
- if (butPtr->highlightWidth > 0) {
- GC gc;
-
- if (butPtr->flags & GOT_FOCUS) {
- gc = Tk_GCForColor(butPtr->highlightColorPtr, pixmap);
- } else {
- gc = Tk_GCForColor(Tk_3DBorderColor(butPtr->highlightBorder),
- pixmap);
- }
-
- /*
- * Make sure the focus ring shrink-wraps the actual button, not the
- * padding space left for a default ring.
- */
-
- if (butPtr->defaultState == DEFAULT_NORMAL) {
- TkDrawInsetFocusHighlight(tkwin, gc, butPtr->highlightWidth,
- pixmap, 5);
- } else {
- Tk_DrawFocusHighlight(tkwin, gc, butPtr->highlightWidth, pixmap);
- }
- }
-
- /*
- * Copy the information from the off-screen pixmap onto the screen, then
- * delete the pixmap.
- */
-
- XCopyArea(butPtr->display, pixmap, Tk_WindowId(tkwin),
- butPtr->copyGC, 0, 0, (unsigned) Tk_Width(tkwin),
- (unsigned) Tk_Height(tkwin), 0, 0);
- Tk_FreePixmap(butPtr->display, pixmap);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TkpComputeButtonGeometry --
- *
- * After changes in a button's text or bitmap, this function recomputes
- * the button's geometry and passes this information along to the
- * geometry manager for the window.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The button's window may change size.
- *
- *----------------------------------------------------------------------
- */
-
-void
-TkpComputeButtonGeometry(
- register TkButton *butPtr) /* Button whose geometry may have changed. */
-{
- int width, height, avgWidth, txtWidth, txtHeight;
- int haveImage = 0, haveText = 0;
- Tk_FontMetrics fm;
-
- butPtr->inset = butPtr->highlightWidth + butPtr->borderWidth;
-
- /*
- * Leave room for the default ring if needed.
- */
-
- if (butPtr->defaultState != DEFAULT_DISABLED) {
- butPtr->inset += 5;
- }
- butPtr->indicatorSpace = 0;
-
- width = 0;
- height = 0;
- txtWidth = 0;
- txtHeight = 0;
- avgWidth = 0;
-
- if (butPtr->image != NULL) {
- Tk_SizeOfImage(butPtr->image, &width, &height);
- haveImage = 1;
- } else if (butPtr->bitmap != None) {
- Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
- haveImage = 1;
- }
-
- if (haveImage == 0 || butPtr->compound != COMPOUND_NONE) {
- Tk_FreeTextLayout(butPtr->textLayout);
-
- butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
- Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength,
- butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);
-
- txtWidth = butPtr->textWidth;
- txtHeight = butPtr->textHeight;
- avgWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);
- Tk_GetFontMetrics(butPtr->tkfont, &fm);
- haveText = (txtWidth != 0 && txtHeight != 0);
- }
-
- /*
- * If the button is compound (i.e., it shows both an image and text), the
- * new geometry is a combination of the image and text geometry. We only
- * honor the compound bit if the button has both text and an image,
- * because otherwise it is not really a compound button.
- */
-
- if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) {
- switch ((enum compound) butPtr->compound) {
- case COMPOUND_TOP:
- case COMPOUND_BOTTOM:
- /*
- * Image is above or below text.
- */
-
- height += txtHeight + butPtr->padY;
- width = (width > txtWidth ? width : txtWidth);
- break;
- case COMPOUND_LEFT:
- case COMPOUND_RIGHT:
- /*
- * Image is left or right of text.
- */
-
- width += txtWidth + butPtr->padX;
- height = (height > txtHeight ? height : txtHeight);
- break;
- case COMPOUND_CENTER:
- /*
- * Image and text are superimposed.
- */
-
- width = (width > txtWidth ? width : txtWidth);
- height = (height > txtHeight ? height : txtHeight);
- break;
- case COMPOUND_NONE:
- break;
- }
- if (butPtr->width > 0) {
- width = butPtr->width;
- }
- if (butPtr->height > 0) {
- height = butPtr->height;
- }
-
- if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
- butPtr->indicatorSpace = height;
- if (butPtr->type == TYPE_CHECK_BUTTON) {
- butPtr->indicatorDiameter = (65*height)/100;
- } else {
- butPtr->indicatorDiameter = (75*height)/100;
- }
- }
-
- width += 2*butPtr->padX;
- height += 2*butPtr->padY;
- } else {
- if (haveImage) {
- if (butPtr->width > 0) {
- width = butPtr->width;
- }
- if (butPtr->height > 0) {
- height = butPtr->height;
- }
-
- if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
- butPtr->indicatorSpace = height;
- if (butPtr->type == TYPE_CHECK_BUTTON) {
- butPtr->indicatorDiameter = (65*height)/100;
- } else {
- butPtr->indicatorDiameter = (75*height)/100;
- }
- }
- } else {
- width = txtWidth;
- height = txtHeight;
-
- if (butPtr->width > 0) {
- width = butPtr->width * avgWidth;
- }
- if (butPtr->height > 0) {
- height = butPtr->height * fm.linespace;
- }
- if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
- butPtr->indicatorDiameter = fm.linespace;
- if (butPtr->type == TYPE_CHECK_BUTTON) {
- butPtr->indicatorDiameter =
- (80*butPtr->indicatorDiameter)/100;
- }
- butPtr->indicatorSpace = butPtr->indicatorDiameter + avgWidth;
- }
- }
- }
-
- /*
- * When issuing the geometry request, add extra space for the indicator,
- * if any, and for the border and padding, plus two extra pixels so the
- * display can be offset by 1 pixel in either direction for the raised or
- * lowered effect.
- */
-
- if ((butPtr->image == NULL) && (butPtr->bitmap == None)) {
- width += 2*butPtr->padX;
- height += 2*butPtr->padY;
- }
- if ((butPtr->type == TYPE_BUTTON) && !Tk_StrictMotif(butPtr->tkwin)) {
- width += 2;
- height += 2;
- }
- Tk_GeometryRequest(butPtr->tkwin, (int) (width + butPtr->indicatorSpace
- + 2*butPtr->inset), (int) (height + 2*butPtr->inset));
- Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset);
-}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */