head	1.37;
access;
symbols
	core-8-5-9:1.32.2.1
	core-8-5-8:1.32.2.1
	macosx-cocoa-merge:1.34
	macosx-cocoa-premerge:1.33
	macosx-carbon-freeze:1.33
	core-8-5-7:1.32.2.1
	core-8-5-6:1.32.2.1
	core-8-6-b1:1.33
	core-8-6-a3:1.32
	core-8-5-5:1.32
	core-8-6-a2:1.32
	core-8-5-4:1.32
	core-8-5-3:1.32
	core-8-6-a1:1.32
	core-8-4-19:1.2.2.20
	core-8-5-branch:1.32.0.2
	core-8-5-2:1.32
	core-8-4-18:1.2.2.20
	core-8-5-1:1.32
	core-8-4-17:1.2.2.20
	core-8-5-0:1.32
	core-8-5-b3:1.31
	core-8-5-b2:1.29
	core-8-4-16:1.2.2.18
	core-8-5-b1:1.27
	core-stablilizer-merge:1.27
	core-stabilizer-branch:1.25.0.2
	core-stabilizer-merge:1.32
	core-8-4-15:1.2.2.16
	core-8-5-a6:1.24
	core-8-5-a5:1.20
	core-8-4-14:1.2.2.14
	core-8-5-a4:1.18
	core-8-4-13:1.2.2.13
	core-8-4-12:1.2.2.12
	core-8-4-11:1.2.2.9
	core-8-5-a3:1.12
	core-8-4-10:1.2.2.9
	core-8-4-9-branch:1.2.2.7.0.2
	core-8-5-a2:1.10
	core-8-4-9:1.2.2.7
	core-8-4-8:1.2.2.7
	core-8-4-7:1.2.2.5
	core-8-5-a1:1.9
	core-8-4-6:1.2.2.5
	core-8-4-5:1.2.2.4
	mistachkin-dev-branch:1.6.0.2
	core-8-4-4:1.2.2.2
	core-8-4-3:1.2.2.2
	core-8-4-branch:1.2.0.2
	core-8-4-2:1.2
	core-8-4-1:1.2
	core-8-4-0:1.2
	macosx-8-4-merge-2002-08-31-trunk:1.2
	macosx-8-4-premerge-2002-08-31-branch:1.1.2.5
	macosx-8-4-merge-2002-08-30-branch:1.1.2.4
	macosx-8-4-merge-2002-08-20-branch:1.1.2.3
	macosx-premerge-6-9-02:1.1.2.1
	macosx-8-4-branch:1.1.0.2;
locks; strict;
comment	@ * @;


1.37
date	2010.02.18.22.31.31;	author nijtmans;	state Exp;
branches;
next	1.36;

1.36
date	2010.01.13.23.08.12;	author nijtmans;	state Exp;
branches;
next	1.35;

1.35
date	2009.07.06.20.29.21;	author dkf;	state Exp;
branches;
next	1.34;

1.34
date	2009.06.29.14.35.01;	author das;	state Exp;
branches;
next	1.33;

1.33
date	2008.12.07.16.30.59;	author das;	state Exp;
branches;
next	1.32;

1.32
date	2007.12.13.15.27.08;	author dgp;	state Exp;
branches
	1.32.2.1;
next	1.31;

1.31
date	2007.11.09.06.23.29;	author das;	state Exp;
branches;
next	1.30;

1.30
date	2007.11.08.14.25.59;	author das;	state Exp;
branches;
next	1.29;

1.29
date	2007.10.15.20.52.47;	author hobbs;	state Exp;
branches;
next	1.28;

1.28
date	2007.10.12.03.06.37;	author das;	state Exp;
branches;
next	1.27;

1.27
date	2007.06.29.03.20.00;	author das;	state Exp;
branches;
next	1.26;

1.26
date	2007.05.31.13.38.13;	author das;	state Exp;
branches;
next	1.25;

1.25
date	2007.05.09.12.55.15;	author das;	state Exp;
branches
	1.25.2.1;
next	1.24;

1.24
date	2007.04.25.15.06.13;	author das;	state Exp;
branches;
next	1.23;

1.23
date	2007.04.23.21.24.33;	author das;	state Exp;
branches;
next	1.22;

1.22
date	2007.04.21.19.06.37;	author hobbs;	state Exp;
branches;
next	1.21;

1.21
date	2007.04.13.14.51.17;	author dkf;	state Exp;
branches;
next	1.20;

1.20
date	2006.08.18.07.30.54;	author das;	state Exp;
branches;
next	1.19;

1.19
date	2006.05.26.21.42.37;	author hobbs;	state Exp;
branches;
next	1.18;

1.18
date	2006.03.24.14.58.01;	author das;	state Exp;
branches;
next	1.17;

1.17
date	2006.03.22.00.21.17;	author das;	state Exp;
branches;
next	1.16;

1.16
date	2005.11.27.02.36.14;	author das;	state Exp;
branches;
next	1.15;

1.15
date	2005.09.10.14.53.20;	author das;	state Exp;
branches;
next	1.14;

1.14
date	2005.08.22.11.54.20;	author das;	state Exp;
branches;
next	1.13;

1.13
date	2005.08.09.07.39.19;	author das;	state Exp;
branches;
next	1.12;

1.12
date	2005.05.14.20.48.14;	author das;	state Exp;
branches;
next	1.11;

1.11
date	2005.03.12.00.27.15;	author wolfsuit;	state Exp;
branches;
next	1.10;

1.10
date	2004.11.09.12.46.10;	author vincentdarley;	state Exp;
branches;
next	1.9;

1.9
date	2004.02.18.00.40.24;	author hobbs;	state Exp;
branches;
next	1.8;

1.8
date	2004.02.16.00.19.41;	author wolfsuit;	state Exp;
branches;
next	1.7;

1.7
date	2003.10.10.20.19.51;	author hobbs;	state Exp;
branches;
next	1.6;

1.6
date	2003.09.30.23.26.09;	author wolfsuit;	state Exp;
branches;
next	1.5;

1.5
date	2003.09.25.05.37.00;	author das;	state Exp;
branches;
next	1.4;

1.4
date	2003.04.30.16.16.39;	author hobbs;	state Exp;
branches;
next	1.3;

1.3
date	2003.04.26.02.59.20;	author hobbs;	state Exp;
branches;
next	1.2;

1.2
date	2002.08.31.06.12.29;	author das;	state Exp;
branches
	1.2.2.1;
next	1.1;

1.1
date	2001.10.15.09.22.00;	author wolfsuit;	state dead;
branches
	1.1.2.1;
next	;

1.1.2.1
date	2001.10.15.09.22.00;	author wolfsuit;	state Exp;
branches;
next	1.1.2.2;

1.1.2.2
date	2002.07.16.14.32.57;	author vincentdarley;	state Exp;
branches;
next	1.1.2.3;

1.1.2.3
date	2002.07.21.20.40.34;	author vincentdarley;	state Exp;
branches;
next	1.1.2.4;

1.1.2.4
date	2002.08.21.12.28.56;	author das;	state Exp;
branches;
next	1.1.2.5;

1.1.2.5
date	2002.08.30.18.18.16;	author das;	state Exp;
branches;
next	;

1.2.2.1
date	2003.04.26.02.53.47;	author hobbs;	state Exp;
branches;
next	1.2.2.2;

1.2.2.2
date	2003.04.30.16.19.07;	author hobbs;	state Exp;
branches;
next	1.2.2.3;

1.2.2.3
date	2003.09.25.05.37.48;	author das;	state Exp;
branches;
next	1.2.2.4;

1.2.2.4
date	2003.10.10.20.20.47;	author hobbs;	state Exp;
branches;
next	1.2.2.5;

1.2.2.5
date	2004.02.16.00.42.34;	author wolfsuit;	state Exp;
branches;
next	1.2.2.6;

1.2.2.6
date	2004.11.10.17.29.45;	author wolfsuit;	state Exp;
branches;
next	1.2.2.7;

1.2.2.7
date	2004.11.11.01.26.42;	author das;	state Exp;
branches;
next	1.2.2.8;

1.2.2.8
date	2005.03.12.00.49.28;	author wolfsuit;	state Exp;
branches;
next	1.2.2.9;

1.2.2.9
date	2005.05.14.20.53.31;	author das;	state Exp;
branches;
next	1.2.2.10;

1.2.2.10
date	2005.08.22.11.55.15;	author das;	state Exp;
branches;
next	1.2.2.11;

1.2.2.11
date	2005.09.10.14.54.17;	author das;	state Exp;
branches;
next	1.2.2.12;

1.2.2.12
date	2005.11.27.02.36.46;	author das;	state Exp;
branches;
next	1.2.2.13;

1.2.2.13
date	2006.03.28.02.44.12;	author das;	state Exp;
branches;
next	1.2.2.14;

1.2.2.14
date	2006.05.26.21.43.05;	author hobbs;	state Exp;
branches;
next	1.2.2.15;

1.2.2.15
date	2007.04.29.02.26.47;	author das;	state Exp;
branches;
next	1.2.2.16;

1.2.2.16
date	2007.05.09.12.57.45;	author das;	state Exp;
branches;
next	1.2.2.17;

1.2.2.17
date	2007.05.31.13.42.11;	author das;	state Exp;
branches;
next	1.2.2.18;

1.2.2.18
date	2007.06.29.03.22.00;	author das;	state Exp;
branches;
next	1.2.2.19;

1.2.2.19
date	2007.11.09.06.26.54;	author das;	state Exp;
branches;
next	1.2.2.20;

1.2.2.20
date	2007.11.09.07.36.45;	author das;	state Exp;
branches;
next	1.2.2.21;

1.2.2.21
date	2008.12.07.16.45.44;	author das;	state Exp;
branches;
next	;

1.25.2.1
date	2007.06.01.04.01.32;	author dgp;	state Exp;
branches;
next	1.25.2.2;

1.25.2.2
date	2007.07.01.17.31.31;	author dgp;	state Exp;
branches;
next	1.25.2.3;

1.25.2.3
date	2007.10.15.18.38.34;	author dgp;	state Exp;
branches;
next	1.25.2.4;

1.25.2.4
date	2007.10.16.04.03.54;	author dgp;	state Exp;
branches;
next	1.25.2.5;

1.25.2.5
date	2007.11.12.19.22.38;	author dgp;	state Exp;
branches;
next	;

1.32.2.1
date	2008.12.07.16.45.59;	author das;	state Exp;
branches;
next	;


desc
@@


1.37
log
@Put all Tk_OptionSpec for buttons and labels
in const memory. With some changes to win32
and macosx, preventing direct writes to
read-only memory.
@
text
@/*
 * tkMacOSXButton.c --
 *
 *	This file implements the Macintosh specific portion of the
 *	button widgets.
 *
 * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@@users.sourceforge.net>
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.36 2010/01/13 23:08:12 nijtmans Exp $
 */

#include "tkMacOSXPrivate.h"
#include "tkButton.h"
#include "tkMacOSXFont.h"
#include "tkMacOSXDebug.h"

/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_BUTTON
#endif
*/

typedef struct MacButton {
    TkButton info;
    NSButton *button;
    NSImage *image, *selectImage, *tristateImage;
#if TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS
    int fix;
#endif
} MacButton;

#if TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS

int tkMacOSXUseCompatibilityMetrics = 1;

/*
 * Use the following heuristic conversion constants to make NSButton-based
 * widget metrics match up with the old Carbon control buttons (for the
 * default Lucida Grande 13 font).
 */

#define NATIVE_BUTTON_INSET 2
#define NATIVE_BUTTON_EXTRA_H 2

typedef struct {
    int trimW, trimH, inset, shrinkH, offsetX, offsetY;
} BoundsFix;

#define fixForTypeStyle(type, style) ( \
	type == NSSwitchButton ? 0 : \
	type == NSRadioButton ? 1 : \
	style == NSRoundedBezelStyle ? 2 : \
	style == NSRegularSquareBezelStyle ? 3 : \
	style == NSShadowlessSquareBezelStyle ? 4 : \
	INT_MIN)

static const BoundsFix boundsFixes[] = {
    [fixForTypeStyle(NSSwitchButton,0)] =		{  2,  2, -1,  0, 2, 1 },
    [fixForTypeStyle(NSRadioButton,0)] =		{  0,  2, -1,  0, 1, 1 },
    [fixForTypeStyle(0,NSRoundedBezelStyle)] =		{ 28, 16, -6,  0, 0, 3 },
    [fixForTypeStyle(0,NSRegularSquareBezelStyle)] =	{ 28, 15, -2, -1 },
    [fixForTypeStyle(0,NSShadowlessSquareBezelStyle)] =	{  2,  2 },
};

#endif

static void DisplayNativeButton(TkButton *butPtr);
static void ComputeNativeButtonGeometry(TkButton *butPtr);
static void DisplayUnixButton(TkButton *butPtr);
static void ComputeUnixButtonGeometry(TkButton *butPtr);

/*
 * The class procedure table for the button widgets.
 */

const Tk_ClassProcs tkpButtonProcs = {
    sizeof(Tk_ClassProcs),	/* size */
    TkButtonWorldChanged,	/* worldChangedProc */
    NULL,					/* createProc */
    NULL					/* modalProc */
};


/*
 *----------------------------------------------------------------------
 *
 * 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)
{
    MacButton *macButtonPtr = (MacButton *) ckalloc(sizeof(MacButton));

    macButtonPtr->button = nil;
    macButtonPtr->image = nil;
    macButtonPtr->selectImage = nil;
    macButtonPtr->tristateImage = nil;

    return (TkButton *) macButtonPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDestroyButton --
 *
 *	Free data structures associated with the button control.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Restores the default control state.
 *
 *----------------------------------------------------------------------
 */

void
TkpDestroyButton(
    TkButton *butPtr)
{
    MacButton *macButtonPtr = (MacButton *) butPtr;

    TkMacOSXMakeCollectableAndRelease(macButtonPtr->button);
    TkMacOSXMakeCollectableAndRelease(macButtonPtr->selectImage);
    TkMacOSXMakeCollectableAndRelease(macButtonPtr->selectImage);
    TkMacOSXMakeCollectableAndRelease(macButtonPtr->tristateImage);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayButton --
 *
 *	This procedure 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.
 *
 *----------------------------------------------------------------------
 */

void
TkpDisplayButton(
    ClientData clientData)	/* Information about widget. */
{
    TkButton *butPtr = (TkButton *) clientData;

    butPtr->flags &= ~REDRAW_PENDING;
    if (!butPtr->tkwin || !Tk_IsMapped(butPtr->tkwin)) {
	return;
    }

    switch (butPtr->type) {
    case TYPE_LABEL:
	DisplayUnixButton(butPtr);
	break;
    case TYPE_BUTTON:
    case TYPE_CHECK_BUTTON:
    case TYPE_RADIO_BUTTON:
	DisplayNativeButton(butPtr);
	break;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpComputeButtonGeometry --
 *
 *	After changes in a button's text or bitmap, this procedure
 *	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. */
{
    MacButton *macButtonPtr = (MacButton *) butPtr;

    switch (butPtr->type) {
    case TYPE_LABEL:
	if (macButtonPtr->button && [macButtonPtr->button superview]) {
	    [macButtonPtr->button removeFromSuperviewWithoutNeedingDisplay];
	}
	ComputeUnixButtonGeometry(butPtr);
	break;
    case TYPE_BUTTON:
    case TYPE_CHECK_BUTTON:
    case TYPE_RADIO_BUTTON:
	if (!macButtonPtr->button) {
	    NSButton *button = [[NSButton alloc] initWithFrame:NSZeroRect];
	    macButtonPtr->button = TkMacOSXMakeUncollectable(button);
	}
	ComputeNativeButtonGeometry(butPtr);
	break;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpButtonSetDefaults --
 *
 *	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:
 *	Some of the default values in *specPtr are modified.
 *
 * Side effects:
 *	Updates some of.
 *
 *----------------------------------------------------------------------
 */

void
TkpButtonSetDefaults()
{
#if TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS
    if (!tkMacOSXUseCompatibilityMetrics) {
    	strcpy(tkDefButtonHighlightWidth, DEF_BUTTON_HIGHLIGHT_WIDTH_NOCM);
    	strcpy(tkDefLabelHighlightWidth, DEF_BUTTON_HIGHLIGHT_WIDTH_NOCM);
    	strcpy(tkDefButtonPadx, DEF_BUTTON_PADX_NOCM);
    	strcpy(tkDefLabelPadx, DEF_BUTTON_PADX_NOCM);
    	strcpy(tkDefButtonPady, DEF_BUTTON_PADY_NOCM);
    	strcpy(tkDefLabelPady, DEF_BUTTON_PADY_NOCM);
    }
#endif
}

#pragma mark -
#pragma mark Native Buttons:


/*
 *----------------------------------------------------------------------
 *
 * DisplayNativeButton --
 *
 *	This procedure 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
DisplayNativeButton(
    TkButton *butPtr)
{
    MacButton *macButtonPtr = (MacButton *) butPtr;
    NSButton *button = macButtonPtr->button;
    Tk_Window tkwin = butPtr->tkwin;
    TkWindow *winPtr = (TkWindow *) tkwin;
    MacDrawable *macWin =  (MacDrawable *) winPtr->window;
    TkMacOSXDrawingContext dc;
    NSView *view = TkMacOSXDrawableView(macWin);
    CGFloat viewHeight = [view bounds].size.height;
    CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
	    .ty = viewHeight};
    NSRect frame;
    int enabled;
    NSCellStateValue state;

    if (!view ||
	    !TkMacOSXSetupDrawingContext((Drawable) macWin, NULL, 1, &dc)) {
	return;
    }
    CGContextConcatCTM(dc.context, t);

    /*
     * We cannot change the background color of the button itself, only the
     * color of the background of its container.
     * This will be the color that peeks around the rounded corners of the
     * button. We make this the highlightbackground rather than the background,
     * because if you color the background of a frame containing a
     * button, you usually also color the highlightbackground as well,
     * or you will get a thin grey ring around the button.
     */

    Tk_Fill3DRectangle(tkwin, (Pixmap) macWin, butPtr->type == TYPE_BUTTON ?
	    butPtr->highlightBorder : butPtr->normalBorder, 0, 0,
	    Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
    if ([button superview] != view) {
	[view addSubview:button];
    }
    if (macButtonPtr->tristateImage) {
	NSImage *selectImage = macButtonPtr->selectImage ?
		macButtonPtr->selectImage : macButtonPtr->image;
	[button setImage:(butPtr->flags & TRISTATED ?
		selectImage : macButtonPtr->image)];
	[button setAlternateImage:(butPtr->flags & TRISTATED ?
		macButtonPtr->tristateImage : selectImage)];
    }
    if (butPtr->flags & SELECTED) {
	state = NSOnState;
    } else if (butPtr->flags & TRISTATED) {
	state = NSMixedState;
    } else {
	state = NSOffState;
    }
    [button setState:state];
    enabled = !(butPtr->state == STATE_DISABLED);
    [button setEnabled:enabled];
    if (enabled) {
	//[button highlight:(butPtr->state == STATE_ACTIVE)];
	//[cell setHighlighted:(butPtr->state == STATE_ACTIVE)];
    }
    if (butPtr->type == TYPE_BUTTON && butPtr->defaultState == STATE_ACTIVE) {
	//[[view window] setDefaultButtonCell:cell];
	[button setKeyEquivalent:@@"\r"];
    } else {
	[button setKeyEquivalent:@@""];
    }
    frame = NSMakeRect(macWin->xOff, macWin->yOff, Tk_Width(tkwin),
	    Tk_Height(tkwin));
#if TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS
    if (tkMacOSXUseCompatibilityMetrics) {
	BoundsFix boundsFix = boundsFixes[macButtonPtr->fix];
	frame = NSOffsetRect(frame, boundsFix.offsetX, boundsFix.offsetY);
	frame.size.height -= boundsFix.shrinkH + NATIVE_BUTTON_EXTRA_H;
	frame = NSInsetRect(frame, boundsFix.inset + NATIVE_BUTTON_INSET,
		boundsFix.inset + NATIVE_BUTTON_INSET);
    }
#endif
    frame.origin.y = viewHeight - (frame.origin.y + frame.size.height);
    if (!NSEqualRects(frame, [button frame])) {
	[button setFrame:frame];
    }
    [button displayRectIgnoringOpacity:[button bounds]];
    TkMacOSXRestoreDrawingContext(&dc);
#ifdef TK_MAC_DEBUG_BUTTON
    TKLog(@@"button %s frame %@@ width %d height %d",
	    ((TkWindow *)butPtr->tkwin)->pathName, NSStringFromRect(frame),
	    Tk_Width(tkwin), Tk_Height(tkwin));
#endif
}

/*
 *----------------------------------------------------------------------
 *
 * ComputeNativeButtonGeometry --
 *
 *	After changes in a button's text or bitmap, this procedure
 *	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.
 *
 *----------------------------------------------------------------------
 */

static void
ComputeNativeButtonGeometry(
    TkButton *butPtr)		/* Button whose geometry may have changed. */
{
    MacButton *macButtonPtr = (MacButton *) butPtr;
    NSButton *button = macButtonPtr->button;
    NSButtonCell *cell = [button cell];
    NSButtonType type = -1;
    NSBezelStyle style = 0;
    NSInteger highlightsBy = 0, showsStateBy = 0;
    NSFont *font;
    NSRect bounds = NSZeroRect, titleRect = NSZeroRect;
    int haveImage = (butPtr->image || butPtr->bitmap != None), haveText = 0;
    int haveCompound = (butPtr->compound != COMPOUND_NONE);
    int width, height, border = 0;

    butPtr->indicatorSpace = 0;
    butPtr->inset = 0;
    if (butPtr->highlightWidth < 0) {
	butPtr->highlightWidth = 0;
    }
    switch (butPtr->type) {
    case TYPE_BUTTON:
	type = NSMomentaryPushInButton;
	if (!haveImage) {
	    style = NSRoundedBezelStyle;
	    butPtr->inset = butPtr->defaultState != STATE_DISABLED ?
		    butPtr->highlightWidth : 0;
	    [button setImage:nil];
	    [button setImagePosition:NSNoImage];
	} else {
	    style = NSShadowlessSquareBezelStyle;
	    highlightsBy = butPtr->selectImage || butPtr->bitmap ?
		    NSContentsCellMask : 0;
	    border = butPtr->borderWidth;
	}
	break;
    case TYPE_RADIO_BUTTON:
    case TYPE_CHECK_BUTTON:
	if (!haveImage /*|| butPtr->indicatorOn*/) { // TODO: indicatorOn
	    type = butPtr->type == TYPE_RADIO_BUTTON ?
		    NSRadioButton : NSSwitchButton;
	    butPtr->inset = /*butPtr->indicatorOn ? 0 :*/ butPtr->borderWidth;
	} else {
	    type = NSPushOnPushOffButton;
	    style = NSShadowlessSquareBezelStyle;
	    highlightsBy = butPtr->selectImage || butPtr->bitmap ?
		    NSContentsCellMask : 0;
	    showsStateBy = butPtr->selectImage || butPtr->tristateImage ?
		    NSContentsCellMask : 0;
#if TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS
	    if (tkMacOSXUseCompatibilityMetrics) {
		border = butPtr->borderWidth > 1 ? butPtr->borderWidth - 1 : 1;
	    } else
#endif
	    {
		border = butPtr->borderWidth;
	    }
	}
	break;
    }
    [button setButtonType:type];
    if (style) {
	[button setBezelStyle:style];
    }
    if (highlightsBy) {
	[cell setHighlightsBy:highlightsBy|[cell highlightsBy]];
    }
    if (showsStateBy) {
	[cell setShowsStateBy:showsStateBy|[cell showsStateBy]];
    }
#if 0
    if (style == NSShadowlessSquareBezelStyle) {
	NSControlSize controlSize = NSRegularControlSize;

	if (butPtr->borderWidth <= 2) {
	    controlSize = NSMiniControlSize;
	} else if (butPtr->borderWidth == 3) {
	    controlSize = NSSmallControlSize;
	}
	[cell setControlSize:controlSize];
    }
#endif
    [button setAllowsMixedState:YES];

    if (!haveImage || haveCompound) {
	int len;
	char *text = Tcl_GetStringFromObj(butPtr->textPtr, &len);

	if (len) {
	    NSString *title = [[NSString alloc] initWithBytes:text length:len
		    encoding:NSUTF8StringEncoding];
	    [button setTitle:title];
	    [title release];
	    haveText = 1;
	}
    }
    haveCompound = (haveCompound && haveImage && haveText);
    if (haveText) {
	NSTextAlignment alignment = NSNaturalTextAlignment;

	switch (butPtr->justify) {
	case TK_JUSTIFY_LEFT:
	    alignment = NSLeftTextAlignment;
	    break;
	case TK_JUSTIFY_RIGHT:
	    alignment = NSRightTextAlignment;
	    break;
	case TK_JUSTIFY_CENTER:
	    alignment = NSCenterTextAlignment;
	    break;
	}
	[button setAlignment:alignment];
    } else {
	[button setTitle:@@""];
    }
    font = TkMacOSXNSFontForFont(butPtr->tkfont);
    if (font) {
	[button setFont:font];
    }
    TkMacOSXMakeCollectableAndRelease(macButtonPtr->image);
    TkMacOSXMakeCollectableAndRelease(macButtonPtr->selectImage);
    TkMacOSXMakeCollectableAndRelease(macButtonPtr->tristateImage);
    if (haveImage) {
	int width, height;
	NSImage *image, *selectImage = nil, *tristateImage = nil;
	NSCellImagePosition pos = NSImageOnly;

	if (butPtr->image) {
	    Tk_SizeOfImage(butPtr->image, &width, &height);
	    image = TkMacOSXGetNSImageWithTkImage(butPtr->display,
		    butPtr->image, width, height);
	    if (butPtr->selectImage) {
		selectImage = TkMacOSXGetNSImageWithTkImage(butPtr->display,
			butPtr->selectImage, width, height);
	    }
	    if (butPtr->tristateImage) {
		tristateImage = TkMacOSXGetNSImageWithTkImage(butPtr->display,
			butPtr->tristateImage, width, height);
	    }
	} else {
	    Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
	    image = TkMacOSXGetNSImageWithBitmap(butPtr->display,
		    butPtr->bitmap, butPtr->normalTextGC, width, height);
	    selectImage = TkMacOSXGetNSImageWithBitmap(butPtr->display,
		    butPtr->bitmap, butPtr->activeTextGC, width, height);
	}
	[button setImage:image];
	if (selectImage) {
	    [button setAlternateImage:selectImage];
	}
	if (tristateImage) {
	    macButtonPtr->image = TkMacOSXMakeUncollectableAndRetain(image);
	    if (selectImage) {
		macButtonPtr->selectImage =
			TkMacOSXMakeUncollectableAndRetain(selectImage);
	    }
	    macButtonPtr->tristateImage =
		    TkMacOSXMakeUncollectableAndRetain(tristateImage);
	}
	if (haveCompound) {
	    switch ((enum compound) butPtr->compound) {
		case COMPOUND_TOP:
		    pos = NSImageAbove;
		    break;
		case COMPOUND_BOTTOM:
		    pos = NSImageBelow;
		    break;
		case COMPOUND_LEFT:
		    pos = NSImageLeft;
		    break;
		case COMPOUND_RIGHT:
		    pos = NSImageRight;
		    break;
		case COMPOUND_CENTER:
		    pos = NSImageOverlaps;
		    break;
		case COMPOUND_NONE:
		    pos = NSImageOnly;
		    break;
	    }
	}
	[button setImagePosition:pos];
    }

    bounds.size = [cell cellSize];
    if (haveText) {
	titleRect = [cell titleRectForBounds:bounds];
	if (butPtr->wrapLength > 0 &&
		titleRect.size.width > butPtr->wrapLength) {
	    if (style == NSRoundedBezelStyle) {
		[button setBezelStyle:(style = NSRegularSquareBezelStyle)];
		bounds.size = [cell cellSize];
		titleRect = [cell titleRectForBounds:bounds];
	    }
	    bounds.size.width -= titleRect.size.width - butPtr->wrapLength;
	    bounds.size.height = 40000.0;
	    [cell setWraps:YES];
	    bounds.size = [cell cellSizeForBounds:bounds];
#ifdef TK_MAC_DEBUG_BUTTON
	    titleRect = [cell titleRectForBounds:bounds];
#endif
#if TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS
	    if (tkMacOSXUseCompatibilityMetrics) {
		bounds.size.height += 3;
	    }
#endif
	}
    }
    width = lround(bounds.size.width);
    height = lround(bounds.size.height);
#if TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS
    if (tkMacOSXUseCompatibilityMetrics) {
	macButtonPtr->fix = fixForTypeStyle(type, style);
	width -= boundsFixes[macButtonPtr->fix].trimW;
	height -= boundsFixes[macButtonPtr->fix].trimH;
    }
#endif

    if (haveImage || haveCompound) {
	if (butPtr->width > 0) {
	    width = butPtr->width;
	}
	if (butPtr->height > 0) {
	    height = butPtr->height;
	}
    } else {
	if (butPtr->width > 0) {
	    int avgWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);
	    width = butPtr->width * avgWidth;
	}
	if (butPtr->height > 0) {
	    Tk_FontMetrics fm;

	    Tk_GetFontMetrics(butPtr->tkfont, &fm);
	    height = butPtr->height * fm.linespace;
	}
    }
    if (!haveImage || haveCompound) {
	width += 2*butPtr->padX;
	height += 2*butPtr->padY;
    }
    if (haveImage) {
	width += 2*border;
	height += 2*border;
    }
#if TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS
    if (tkMacOSXUseCompatibilityMetrics) {
	width += 2*NATIVE_BUTTON_INSET;
	height += 2*NATIVE_BUTTON_INSET + NATIVE_BUTTON_EXTRA_H;
    }
#endif
    Tk_GeometryRequest(butPtr->tkwin, width, height);
    Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset);
#ifdef TK_MAC_DEBUG_BUTTON
    TKLog(@@"button %s bounds %@@ titleRect %@@ width %d height %d inset %d borderWidth %d",
	    ((TkWindow *)butPtr->tkwin)->pathName, NSStringFromRect(bounds),
	    NSStringFromRect(titleRect), width, height, butPtr->inset,
	    butPtr->borderWidth);
#endif
}

#pragma mark -
#pragma mark Unix Buttons:


/*
 *----------------------------------------------------------------------
 *
 * DisplayUnixButton --
 *
 *	This procedure 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.
 *
 *----------------------------------------------------------------------
 */

void
DisplayUnixButton(
    TkButton *butPtr)
{
    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 */

    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->state != STATE_ACTIVE)
	    && (butPtr->selectBorder != NULL) && !butPtr->indicatorOn) {
	border = butPtr->selectBorder;
    }

    relief = butPtr->relief;

    pixmap = (Pixmap) Tk_WindowId(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,
		fullWidth, fullHeight, &x, &y);

	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,
		    width, height, &x, &y);
	    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->textWidth, butPtr->textHeight, &x, &y);

	    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;
	}
    }

    /*
     * 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);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ComputeUnixButtonGeometry --
 *
 *	After changes in a button's text or bitmap, this procedure
 *	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
ComputeUnixButtonGeometry(
    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;
	}

	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;
	    }
	} else {
	    width = txtWidth;
	    height = txtHeight;

	    if (butPtr->width > 0) {
		width = butPtr->width * avgWidth;
	    }
	    if (butPtr->height > 0) {
		height = butPtr->height * fm.linespace;
	    }
	}
    }

    if (!haveImage) {
	width += 2*butPtr->padX;
	height += 2*butPtr->padY;
    }
    Tk_GeometryRequest(butPtr->tkwin, (int) (width
	    + 2*butPtr->inset), (int) (height + 2*butPtr->inset));
    Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset);
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */
@


1.36
log
@Eliminate tkpMenubuttonClass
make tkpButtonProcs CONST
fix gcc warnings: missing initializer
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.35 2009/07/06 20:29:21 dkf Exp $
d250 1
a250 4
TkpButtonSetDefaults(
    Tk_OptionSpec *specPtr)	/* Points to an array of option specs,
				 * terminated by one with type
				 * TK_OPTION_END. */
d254 6
a259 14
	while (specPtr->type != TK_CONFIG_END) {
	    switch (specPtr->internalOffset) {
	    case Tk_Offset(TkButton, highlightWidth):
		specPtr->defValue = DEF_BUTTON_HIGHLIGHT_WIDTH_NOCM;
		break;
	    case Tk_Offset(TkButton, padX):
		specPtr->defValue = DEF_BUTTON_PADX_NOCM;
		break;
	    case Tk_Offset(TkButton, padY):
		specPtr->defValue = DEF_BUTTON_PADY_NOCM;
		break;
	    }
	    specPtr++;
	}
@


1.35
log
@More marking of files as Objective-C.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.34 2009/06/29 14:35:01 das Exp $
d81 1
a81 1
Tk_ClassProcs tkpButtonProcs = {
d84 2
@


1.34
log
@Merge of TkAqua Cocoa port
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.33 2008/12/07 16:30:59 das Exp $
d1176 1
a1176 1
 * mode: c
@


1.33
log
@TkpDisplayButton: use computed borderWidth
@
text
@d8 2
a9 2
 * Copyright 2001, Apple Computer, Inc.
 * Copyright (c) 2006-2007 Daniel A. Steffen <das@@users.sourceforge.net>
d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.32 2007/12/13 15:27:08 dgp Exp $
a21 8
#define DEFAULT_USE_TK_TEXT 0

#define CONTROL_INITIALIZED 1
#define FIRST_DRAW	    2
#define ACTIVE		    4

#define MAX_VALUE	    2

d23 4
a26 2
 * Default insets for controls
 */
d28 8
a35 4
#define DEF_INSET_LEFT 2
#define DEF_INSET_RIGHT 2
#define DEF_INSET_TOP 2
#define DEF_INSET_BOTTOM 4
d37 1
a37 3
/*
 * Some defines used to control what type of control is drawn.
 */
d39 1
a39 4
#define DRAW_LABEL	0	/* Labels are treated genericly. */
#define DRAW_CONTROL	1	/* Draw using the Native control. */
#define DRAW_CUSTOM	2	/* Make our own button drawing. */
#define DRAW_BEVEL	3
d42 3
a44 1
 * Declaration of Mac specific button structure.
d47 2
a48 7
typedef struct {
    SInt16 initialValue;
    SInt16 minValue;
    SInt16 maxValue;
    SInt16 procID;
    int isBevel;
} MacControlParams;
d51 2
a52 10
    int drawType;
    Tk_3DBorder border;
    int relief;
    int offset;			/* 0 means this is a normal widget. 1 means
				 * it is an image button, so we offset the
				 * image to make the button appear to move
				 * up and down as the relief changes. */
    GC gc;
    int hasImageOrBitmap;
} DrawParams;
d54 15
a68 20
typedef struct {
    TkButton info;		/* Generic button info */
    int id;
    int usingControl;
    int useTkText;
    int flags;			/* Initialisation status */
    MacControlParams params;
    WindowRef windowRef;
    unsigned long userPaneBackground;
    ControlRef userPane;	/* Carbon control */
    ControlRef control;		/* Carbon control */
    Str255 controlTitle;
    ControlFontStyleRec fontStyle;
    /*
     * The following are used to store the image content for
     * beveled buttons, i.e. buttons with images.
     */
    ControlButtonContentInfo bevelButtonContent;
    OpenCPicParams picParams;
} MacButton;
d70 1
a70 3
/*
 * Forward declarations for procedures defined later in this file:
 */
d72 4
a75 17
static OSStatus SetUserPaneDrawProc(ControlRef control,
	ControlUserPaneDrawProcPtr upp);
static OSStatus SetUserPaneSetUpSpecialBackgroundProc(ControlRef control,
	ControlUserPaneBackgroundProcPtr upp);
static void UserPaneDraw(ControlRef control, ControlPartCode cpc);
static void UserPaneBackgroundProc(ControlHandle,
	ControlBackgroundPtr info);

static void ButtonEventProc(ClientData clientData, XEvent *eventPtr);
static int UpdateControlColors(MacButton *mbPtr);
static void TkMacOSXComputeControlParams(TkButton *butPtr,
	MacControlParams *paramsPtr);
static int TkMacOSXComputeDrawParams(TkButton *butPtr, DrawParams *dpPtr);
static void TkMacOSXDrawControl(MacButton *butPtr, GWorldPtr destPort, GC gc,
	Pixmap pixmap);
static void SetupBevelButton(MacButton *butPtr, ControlRef controlHandle,
	GWorldPtr destPort, GC gc, Pixmap pixmap);
a85 2
static int bCount;

d109 29
a137 12
    Tk_CreateEventHandler(tkwin, ActivateMask,
	    ButtonEventProc, (ClientData) macButtonPtr);
    macButtonPtr->id = bCount++;
    macButtonPtr->usingControl = 0;
    macButtonPtr->flags = 0;
    macButtonPtr->userPaneBackground = PIXEL_MAGIC << 24;
    macButtonPtr->userPane = NULL;
    macButtonPtr->control = NULL;
    macButtonPtr->controlTitle[0] = 0;
    macButtonPtr->controlTitle[1] = 0;
    bzero(&macButtonPtr->params, sizeof(macButtonPtr->params));
    bzero(&macButtonPtr->fontStyle, sizeof(macButtonPtr->fontStyle));
d139 4
a142 1
    return (TkButton *)macButtonPtr;
a166 1
    MacButton *macButtonPtr = (MacButton *) clientData;
a167 11
    Tk_Window tkwin = butPtr->tkwin;
    CGrafPtr destPort, savePort;
    Boolean portChanged;
    Pixmap pixmap;
    int width, height, fullWidth, fullHeight, textXOffset, textYOffset;
    int borderWidth, wasUsingControl;
    int haveImage = 0, haveText = 0, imageWidth = 0, imageHeight = 0;
    int imageXOffset = 0, imageYOffset = 0; /* image information that will
					     * be used to restrict disabled
					     * pixmap as well */
    DrawParams drawParams, *dpPtr = &drawParams;
d170 1
a170 1
    if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
a172 2
    pixmap = (Pixmap) Tk_WindowId(tkwin);
    wasUsingControl = macButtonPtr->usingControl;
d174 9
a182 10
    if (TkMacOSXComputeDrawParams(butPtr, &drawParams) ) {
	macButtonPtr->usingControl = 1;
	if (butPtr->type == TYPE_BUTTON) {
	    macButtonPtr->useTkText = 0;
	} else {
	    macButtonPtr->useTkText = 1;
	}
    } else {
	macButtonPtr->usingControl = 0;
	macButtonPtr->useTkText = 1;
d184 19
d204 5
a208 4
    /*
     * See the comment in UpdateControlColors as to why we use the
     * highlightbackground for the border of Macintosh buttons.
     */
d210 13
a222 7
    if (macButtonPtr->useTkText) {
	if (butPtr->type == TYPE_BUTTON) {
	    Tk_Fill3DRectangle(tkwin, pixmap, butPtr->highlightBorder, 0, 0,
		    Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
	} else {
	    Tk_Fill3DRectangle(tkwin, pixmap, butPtr->normalBorder, 0, 0,
		    Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
d224 2
d227 19
d247 12
a258 92
    /*
     * Set up clipping region. Make sure the we are using the port
     * for this button, or we will set the wrong window's clip.
     */

    destPort = TkMacOSXGetDrawablePort(pixmap);
    portChanged = QDSwapPort(destPort, &savePort);
    TkMacOSXSetUpClippingRgn(pixmap);

    /*
     * Draw the native portion of the buttons. Start by creating the control
     * if it doesn't already exist. Then configure the Macintosh control from
     * the Tk info. Finally, we call Draw1Control to draw to the screen.
     */

    if (macButtonPtr->usingControl) {
	borderWidth = 0;
	TkMacOSXDrawControl(macButtonPtr, destPort, dpPtr->gc, pixmap);
    } else if (wasUsingControl && macButtonPtr->userPane) {
	DisposeControl(macButtonPtr->userPane);
	macButtonPtr->userPane = NULL;
	macButtonPtr->control = NULL;
	macButtonPtr->flags = 0;
    }

    if ((dpPtr->drawType == DRAW_CUSTOM) || (dpPtr->drawType == DRAW_LABEL)) {
	borderWidth = butPtr->borderWidth;
    }

    /*
     * Display image or bitmap or text for button. This has
     * already been done under Appearance with the Bevel
     * button types.
     */

    if (dpPtr->drawType == DRAW_BEVEL) {
	goto applyStipple;
    }

    if (butPtr->image != None) {
	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) {
	int x, y;

	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;
d260 2
a261 14

	    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;
d263 2
a264 2

	    case COMPOUND_NONE:
d266 2
d269 3
d273 2
a274 2
	TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY,
		butPtr->indicatorSpace + fullWidth, fullHeight, &x, &y);
d276 18
a293 1
	x += butPtr->indicatorSpace;
d295 17
a311 30
	x += dpPtr->offset;
	y += dpPtr->offset;
	if (dpPtr->relief == TK_RELIEF_RAISED) {
	    x -= dpPtr->offset;
	    y -= dpPtr->offset;
	} else if (dpPtr->relief == TK_RELIEF_SUNKEN) {
	    x += dpPtr->offset;
	    y += dpPtr->offset;
	}
	imageXOffset += x;
	imageYOffset += y;
	if (butPtr->image != NULL) {
	    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, dpPtr->gc, imageXOffset,
		    imageYOffset);
	    XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, dpPtr->gc,
		    0, 0, width, height, imageXOffset, imageYOffset, 1);
	    XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0);
	}
d313 3
a315 55
	if (macButtonPtr->useTkText) {
	    Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc,
		    butPtr->textLayout, x + textXOffset, y + textYOffset, 0,
		    -1);
	    Tk_UnderlineTextLayout(butPtr->display, pixmap, dpPtr->gc,
		    butPtr->textLayout, x + textXOffset, y + textYOffset,
		    butPtr->underline);
	}
	y += fullHeight/2;
    } else if (haveImage) {
	int x = 0, y;

	TkComputeAnchor(butPtr->anchor, tkwin, 0, 0,
		butPtr->indicatorSpace + width, height, &x, &y);
	x += butPtr->indicatorSpace;

	x += dpPtr->offset;
	y += dpPtr->offset;
	if (dpPtr->relief == TK_RELIEF_RAISED) {
	    x -= dpPtr->offset;
	    y -= dpPtr->offset;
	} else if (dpPtr->relief == TK_RELIEF_SUNKEN) {
	    x += dpPtr->offset;
	    y += dpPtr->offset;
	}
	imageXOffset += x;
	imageYOffset += y;
	if (butPtr->image != NULL) {
	    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, dpPtr->gc, x, y);
	    XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, dpPtr->gc,
		    0, 0, width, height, x, y, 1);
	    XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0);
	}
	y += height/2;
    } else if (macButtonPtr->useTkText) {
	int x = 0, y;

	TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY,
		butPtr->indicatorSpace + butPtr->textWidth,
		butPtr->textHeight, &x, &y);
	x += butPtr->indicatorSpace;
	Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc,
		butPtr->textLayout, x, y, 0, -1);
d317 1
d320 7
a326 4
     * 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.
d329 33
a361 43
  applyStipple:
    if (macButtonPtr->useTkText) {
	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.
	 */

	if (dpPtr->relief != TK_RELIEF_FLAT) {
	    int inset = butPtr->highlightWidth;

	    Tk_Draw3DRectangle(tkwin, pixmap, dpPtr->border, inset, inset,
		    Tk_Width(tkwin) - 2*inset, Tk_Height(tkwin) - 2*inset,
		    borderWidth, dpPtr->relief);
	}
d363 9
a371 2
    if (portChanged) {
	QDSwapPort(savePort, NULL);
d373 12
d390 1
a390 1
 * TkpComputeButtonGeometry --
d405 2
a406 2
void
TkpComputeButtonGeometry(
d409 11
a419 4
    int width, height, avgWidth, haveImage = 0, haveText = 0;
    int xInset, yInset, txtWidth, txtHeight;
    Tk_FontMetrics fm;
    DrawParams drawParams;
d421 58
a478 3
    /*
     * First figure out the size of the contents of the button.
     */
d480 6
a485 13
    width = 0;
    height = 0;
    txtWidth = 0;
    txtHeight = 0;
    avgWidth = 0;

    butPtr->indicatorSpace = 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;
d487 2
d490 3
a492 5
    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);
d494 7
a500 5
	txtWidth = butPtr->textWidth;
	txtHeight = butPtr->textHeight;
	avgWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);
	Tk_GetFontMetrics(butPtr->tkfont, &fm);
	haveText = (txtWidth != 0 && txtHeight != 0);
d502 14
a515 38

    /*
     * If the button is compound (ie, 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;
d517 47
a563 2
	if (butPtr->width > 0) {
	    width = butPtr->width;
d565 21
a585 2
	if (butPtr->height > 0) {
	    height = butPtr->height;
d587 2
d590 20
a609 6
	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;
d611 1
d613 10
d624 1
a624 3
	width += 2 * butPtr->padX;
	height += 2 * butPtr->padY;
    } else if (haveImage) {
a630 8
	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;
	    }
	}
a631 2
	width = txtWidth;
	height = txtHeight;
d633 1
d637 3
a641 8
	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;
	}
d643 1
a643 30

    /*
     * Now figure out the size of the border decorations for the button.
     */

    if (butPtr->highlightWidth < 0) {
	butPtr->highlightWidth = 0;
    }

    /*
     * The width and height calculation for Appearance buttons with images &
     * non-Appearance buttons with images is different. In the latter case,
     * we add the borderwidth to the inset, since we are going to stamp a
     * 3-D border over the image. In the former, we add it to the height,
     * directly, since Appearance will draw the border as part of our control.
     *
     * When issuing the geometry request, add extra space for the indicator,
     * if any, and for the border and padding, plus if this is an image two
     * extra pixels so the display can be offset by 1 pixel in either
     * direction for the raised or lowered effect.
     *
     * The highlight width corresponds to the default ring on the Macintosh.
     * As such, the highlight width is only added if the button is the default
     * button. The actual width of the default ring is one less than the
     * highlight width as there is also one pixel of spacing.
     * Appearance buttons with images do not have a highlight ring, because the
     * Bevel button type does not support one.
     */

    if ((butPtr->image == None) && (butPtr->bitmap == None)) {
d647 8
a654 38

    if ((butPtr->type == TYPE_BUTTON)) {
	if ((butPtr->image == None) && (butPtr->bitmap == None)) {
	    butPtr->inset = 0;
	    if (butPtr->defaultState != STATE_DISABLED) {
		butPtr->inset += butPtr->highlightWidth;
	    }
	} else {
	    butPtr->inset = 0;
	    width += (2 * butPtr->borderWidth + 4);
	    height += (2 * butPtr->borderWidth + 4);
	}
    } else if (butPtr->type == TYPE_LABEL) {
	butPtr->inset = butPtr->borderWidth;
    } else if (butPtr->indicatorOn) {
	butPtr->inset = 0;
    } else {
	/*
	 * Under Appearance, the Checkbutton or radiobutton with an image
	 * is represented by a BevelButton with the Sticky defProc...
	 * So we must set its height in the same way as the Button
	 * with an image or bitmap.
	 */

	if (butPtr->image != None || butPtr->bitmap != None) {
	    int border;

	    butPtr->inset = 0;
	    if (butPtr->borderWidth <= 2) {
		border = 6;
	    } else {
		border = 2 * butPtr->borderWidth + 2;
	    }
	    width += border;
	    height += border;
	} else {
	    butPtr->inset = butPtr->borderWidth;
	}
d656 2
a657 9

    if (TkMacOSXComputeDrawParams(butPtr, &drawParams)) {
	xInset = butPtr->indicatorSpace + DEF_INSET_LEFT + DEF_INSET_RIGHT;
	yInset = DEF_INSET_TOP + DEF_INSET_BOTTOM;
    } else {
	xInset = butPtr->indicatorSpace+butPtr->inset*2;
	yInset = butPtr->inset*2;
    }
    Tk_GeometryRequest(butPtr->tkwin, width + xInset, height + yInset);
d659 6
d666 4
d674 1
a674 1
 * TkpDestroyButton --
d676 2
a677 1
 *	Free data structures associated with the button control.
d683 2
a684 1
 *	Restores the default control state.
d690 1
a690 1
TkpDestroyButton(
d693 14
a706 1
    MacButton *mbPtr = (MacButton *) butPtr; /* Mac button. */
d708 13
a720 3
    if (mbPtr->userPane) {
	DisposeControl(mbPtr->userPane);
	mbPtr->userPane = NULL;
a721 21
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXInitControl --
 *
 *	This procedure initialises a Carbon control.
 *
 * Results:
 *	0 on success, 1 on failure.
 *
 * Side effects:
 *	A background pane control and the control itself is created
 *	The contol is embedded in the background control
 *	The background control is embedded in the root control
 *	of the containing window
 *	The creation parameters for the control are also computed
 *
 *----------------------------------------------------------------------
 */
d723 1
a723 14
static int
TkMacOSXInitControl(
    MacButton *mbPtr,		/* Mac button. */
    GWorldPtr destPort,
    GC gc,
    Pixmap pixmap,
    Rect *paneRect,
    Rect *cntrRect)
{
    TkButton *butPtr = (TkButton *) mbPtr;
    ControlRef rootControl;
    SInt16 procID, initialValue, minValue, maxValue;
    Boolean initiallyVisible;
    SInt32 controlReference;
d725 3
a727 2
    rootControl = TkMacOSXGetRootControl(Tk_WindowId(butPtr->tkwin));
    mbPtr->windowRef = TkMacOSXDrawableWindow(Tk_WindowId(butPtr->tkwin));
d730 1
a730 1
     * Set up the user pane.
d733 6
a738 39
    initiallyVisible = false;
    initialValue = kControlSupportsEmbedding|kControlHasSpecialBackground;
    minValue = 0;
    maxValue = 1;
    procID = kControlUserPaneProc;
    controlReference = (SInt32)mbPtr;
    mbPtr->userPane = NewControl(mbPtr->windowRef, paneRect, "\p",
	    initiallyVisible, initialValue, minValue, maxValue, procID,
	    controlReference);

    if (!mbPtr->userPane) {
	TkMacOSXDbgMsg("Failed to create user pane control");
	return 1;
    }
    if (ChkErr(EmbedControl, mbPtr->userPane,rootControl) != noErr) {
	return 1;
    }

    SetUserPaneSetUpSpecialBackgroundProc(mbPtr->userPane,
	    UserPaneBackgroundProc);
    SetUserPaneDrawProc(mbPtr->userPane,UserPaneDraw);
    initiallyVisible = false;
    TkMacOSXComputeControlParams(butPtr,&mbPtr->params);
    mbPtr->control = NewControl(mbPtr->windowRef, cntrRect, "\p",
	    initiallyVisible, mbPtr->params.initialValue,
	    mbPtr->params.minValue, mbPtr->params.maxValue,
	    mbPtr->params.procID, controlReference);

    if (!mbPtr->control) {
	TkMacOSXDbgMsg("Failed to create control of type %d\n", procID);
	return 1;
    }
    if (ChkErr(EmbedControl, mbPtr->control,mbPtr->userPane) != noErr ) {
	return 1;
    }

    mbPtr->flags |= (CONTROL_INITIALIZED | FIRST_DRAW);
    if (IsWindowActive(mbPtr->windowRef)) {
	mbPtr->flags |= ACTIVE;
d740 2
a741 20
    return 0;
}

/*
 *--------------------------------------------------------------
 *
 * TkMacOSXDrawControl --
 *
 *	This function draws the tk button using Mac controls
 *	In addition, this code may apply custom colors passed
 *	in the TkButton.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The control is created, or reinitialised as needed.
 *
 *--------------------------------------------------------------
 */
d743 1
a743 21
static void
TkMacOSXDrawControl(
    MacButton *mbPtr,		/* Mac button. */
    GWorldPtr destPort,		/* Off screen GWorld. */
    GC gc,			/* The GC we are drawing into - needed for the
				 * bevel button */
    Pixmap pixmap)		/* The pixmap we are drawing into - needed for
				 * the bevel button */
{
    TkButton *butPtr = (TkButton *) mbPtr;
    TkWindow *winPtr;
    Rect paneRect, cntrRect;
    int active, enabled;
    int rebuild;

    winPtr = (TkWindow *) butPtr->tkwin;

    paneRect.left = winPtr->privatePtr->xOff;
    paneRect.top = winPtr->privatePtr->yOff;
    paneRect.right = paneRect.left + Tk_Width(butPtr->tkwin);
    paneRect.bottom = paneRect.top + Tk_Height(butPtr->tkwin);
d745 5
a749 1
    cntrRect = paneRect;
d751 6
a756 10
/*
    cntrRect.left += butPtr->inset;
    cntrRect.top += butPtr->inset;
    cntrRect.right -= butPtr->inset;
    cntrRect.bottom -= butPtr->inset;
*/
    cntrRect.left += DEF_INSET_LEFT;
    cntrRect.top += DEF_INSET_TOP;
    cntrRect.right -= DEF_INSET_RIGHT;
    cntrRect.bottom -= DEF_INSET_BOTTOM;
d758 16
a773 12
    /*
     * The control has been previously initialised.
     * It may need to be re-initialised
     */
#ifdef TK_REBUILD_TOPLEVEL
    rebuild = (winPtr->flags & TK_REBUILD_TOPLEVEL);
    winPtr->flags &= ~TK_REBUILD_TOPLEVEL;
#else
    rebuild = 0;
#endif
    if (mbPtr->flags) {
	MacControlParams params;
d775 12
a786 2
	TkMacOSXComputeControlParams(butPtr, &params);
	if (rebuild || bcmp(&params, &mbPtr->params, sizeof(params))) {
d788 1
a788 2
	     * The type of control has changed.
	     * Clean it up and clear the flag.
d791 11
a801 6
	    if (mbPtr->userPane) {
		DisposeControl(mbPtr->userPane);
		mbPtr->userPane = NULL;
		mbPtr->control = NULL;
	    }
	    mbPtr->flags = 0;
a802 9
    }
    if (!(mbPtr->flags & CONTROL_INITIALIZED)) {
	if (TkMacOSXInitControl(mbPtr, destPort, gc, pixmap, &paneRect,
		&cntrRect)) {
	    return;
	}
    }
    SetControlBounds(mbPtr->userPane, &paneRect);
    SetControlBounds(mbPtr->control, &cntrRect);
d804 11
a814 5
    if (!mbPtr->useTkText) {
	Str255 controlTitle;
	ControlFontStyleRec fontStyle;
	Tk_Font font;
	int len;
d816 14
a829 16
	if (((mbPtr->info.image == NULL) && (mbPtr->info.bitmap == None))
		|| (mbPtr->info.compound != COMPOUND_NONE)) {
	    len = TkFontGetFirstTextLayout(butPtr->textLayout,
		    &font, (char*) controlTitle);
	    controlTitle[len] = 0;
	} else {
	    len = 0;
	    controlTitle[0] = 0;
	}
	if (rebuild || bcmp(mbPtr->controlTitle, controlTitle, len+1)) {
	    CFStringRef cf = CFStringCreateWithCString(NULL,
		    (char*) controlTitle, kCFStringEncodingUTF8);

	    if (cf != NULL) {
		SetControlTitleWithCFString(mbPtr->control, cf);
		CFRelease(cf);
d831 2
a832 7
	    bcopy(controlTitle, mbPtr->controlTitle, len+1);
	}
	if (len) {
	    TkMacOSXInitControlFontStyle(font, &fontStyle);
	    if (bcmp(&mbPtr->fontStyle, &fontStyle, sizeof(fontStyle)) ) {
		ChkErr(SetControlFontStyle, mbPtr->control, &fontStyle);
		bcopy(&fontStyle, &mbPtr->fontStyle, sizeof(fontStyle));
a833 6
	}
    }
    if (mbPtr->params.isBevel) {
	/*
	 * Initialiase the image/button parameters.
	 */
d835 6
a840 31
	SetupBevelButton(mbPtr, mbPtr->control, destPort, gc, pixmap);
    }

    if (butPtr->flags & SELECTED) {
	SetControlValue(mbPtr->control, 1);
    } else if (butPtr->flags & TRISTATED) {
	SetControlValue(mbPtr->control, 2);
    } else {
	SetControlValue(mbPtr->control, 0);
    }

    active = ((mbPtr->flags & ACTIVE) != 0);
    if (active != IsControlActive(mbPtr->control)) {
	if (active) {
	    ChkErr(ActivateControl, mbPtr->control);
	} else {
	    ChkErr(DeactivateControl, mbPtr->control);
	}
    }
    enabled = !(butPtr->state == STATE_DISABLED);
    if (enabled != IsControlEnabled(mbPtr->control)) {
	if (enabled) {
	    ChkErr(EnableControl, mbPtr->control);
	} else {
	    ChkErr(DisableControl, mbPtr->control);
	}
    }
    if (active && enabled) {
	if (butPtr->state == STATE_ACTIVE) {
	    if (mbPtr->params.isBevel) {
		HiliteControl(mbPtr->control, kControlButtonPart);
d842 2
a843 11
		switch (butPtr->type) {
		    case TYPE_BUTTON:
			HiliteControl(mbPtr->control, kControlButtonPart);
			break;
		    case TYPE_RADIO_BUTTON:
			HiliteControl(mbPtr->control, kControlRadioButtonPart);
			break;
		    case TYPE_CHECK_BUTTON:
			HiliteControl(mbPtr->control, kControlCheckBoxPart);
			break;
		}
d846 5
a850 1
	    HiliteControl(mbPtr->control, kControlNoPart);
a851 2
    }
    UpdateControlColors(mbPtr);
d853 17
a869 2
    if (butPtr->type == TYPE_BUTTON && !mbPtr->params.isBevel) {
	Boolean isDefault;
d871 38
a908 2
	if (butPtr->defaultState == STATE_ACTIVE) {
	    isDefault = true;
d910 2
a911 5
	    isDefault = false;
	}
	ChkErr(SetControlData, mbPtr->control, kControlNoPart,
		kControlPushButtonDefaultTag, sizeof(isDefault), &isDefault);
    }
d913 5
a917 13
    if (mbPtr->flags & FIRST_DRAW) {
	ShowControl(mbPtr->userPane);
	ShowControl(mbPtr->control);
	mbPtr->flags ^= FIRST_DRAW;
    } else {
	SetControlVisibility(mbPtr->control, true, true);
	Draw1Control(mbPtr->userPane);
    }

    if (mbPtr->params.isBevel) {
	if (mbPtr->bevelButtonContent.contentType ==
		kControlContentPictHandle) {
	    KillPicture(mbPtr->bevelButtonContent.u.picture);
a919 40
}

/*
 *--------------------------------------------------------------
 *
 * SetupBevelButton --
 *
 *	Sets up the Bevel Button with image by copying the
 *	source image onto the PicHandle for the button.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	The image or bitmap for the button is copied over to a picture.
 *
 *--------------------------------------------------------------
 */

void
SetupBevelButton(
    MacButton *mbPtr,		/* Mac button. */
    ControlRef controlHandle,	/* The control to set this picture to. */
    GWorldPtr destPort,		/* Off screen GWorld. */
    GC gc,			/* The GC we are drawing into - needed for the
				 * bevel button. */
    Pixmap pixmap)		/* The pixmap we are drawing into - needed for
				 * the bevel button. */
{
    TkButton *butPtr = (TkButton *) mbPtr;
    int height, width;
    ControlButtonGraphicAlignment theAlignment;
    CGrafPtr savePort;
    Boolean portChanged = false;

    if (butPtr->image != None) {
	Tk_SizeOfImage(butPtr->image, &width, &height);
    } else {
	Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
    }
d921 6
a926 6
    if ((butPtr->width > 0) && (butPtr->width < width)) {
	width = butPtr->width;
    }
    if ((butPtr->height > 0) && (butPtr->height < height)) {
	height = butPtr->height;
    }
d928 6
a933 15
    {
	portChanged = QDSwapPort(destPort, &savePort);
	mbPtr->picParams.version = -2;
	mbPtr->picParams.hRes = 0x00480000;
	mbPtr->picParams.vRes = 0x00480000;
	mbPtr->picParams.srcRect.top = 0;
	mbPtr->picParams.srcRect.left = 0;
	mbPtr->picParams.srcRect.bottom = height;
	mbPtr->picParams.srcRect.right = width;
	mbPtr->picParams.reserved1 = 0;
	mbPtr->picParams.reserved2 = 0;
	mbPtr->bevelButtonContent.contentType = kControlContentPictHandle;
	mbPtr->bevelButtonContent.u.picture = OpenCPicture(&mbPtr->picParams);
	if (!mbPtr->bevelButtonContent.u.picture) {
	    TkMacOSXDbgMsg("OpenCPicture failed");
a934 1
	tkPictureIsOpen = 1;
d937 2
a938 3
	 * TO DO - There is one case where XCopyPlane calls CopyDeepMask,
	 * which does not get recorded in the picture. So the bitmap code
	 * will fail in that case.
a939 1
     }
d941 13
a953 64
    if (butPtr->selectImage != NULL && (butPtr->flags & SELECTED)) {
	Tk_RedrawImage(butPtr->selectImage, 0, 0, width, height, pixmap, 0, 0);
    } else if (butPtr->tristateImage != NULL && (butPtr->flags & TRISTATED)) {
	Tk_RedrawImage(butPtr->tristateImage, 0, 0, width, height, pixmap, 0,
		0);
    } else if (butPtr->image != NULL) {
	Tk_RedrawImage(butPtr->image, 0, 0, width, height, pixmap, 0, 0);
    } else {
	XSetClipOrigin(butPtr->display, gc, 0, 0);
	XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, gc, 0, 0, width,
		height, 0, 0, 1);
    }

    {
	ClosePicture();
	tkPictureIsOpen = 0;
	if (portChanged) {
	    QDSwapPort(savePort, NULL);
	}
    }
    ChkErr(SetControlData, controlHandle, kControlButtonPart,
	    kControlBevelButtonContentTag,
	    sizeof(ControlButtonContentInfo),
	    (char *) &mbPtr->bevelButtonContent);

    if (butPtr->anchor == TK_ANCHOR_N) {
	theAlignment = kControlBevelButtonAlignTop;
    } else if (butPtr->anchor == TK_ANCHOR_NE) {
	theAlignment = kControlBevelButtonAlignTopRight;
    } else if (butPtr->anchor == TK_ANCHOR_E) {
	theAlignment = kControlBevelButtonAlignRight;
    } else if (butPtr->anchor == TK_ANCHOR_SE) {
	theAlignment = kControlBevelButtonAlignBottomRight;
    } else if (butPtr->anchor == TK_ANCHOR_S) {
	theAlignment = kControlBevelButtonAlignBottom;
    } else if (butPtr->anchor == TK_ANCHOR_SW) {
	theAlignment = kControlBevelButtonAlignBottomLeft;
    } else if (butPtr->anchor == TK_ANCHOR_W) {
	theAlignment = kControlBevelButtonAlignLeft;
    } else if (butPtr->anchor == TK_ANCHOR_NW) {
	theAlignment = kControlBevelButtonAlignTopLeft;
    } else if (butPtr->anchor == TK_ANCHOR_CENTER) {
	theAlignment = kControlBevelButtonAlignCenter;
    }
    ChkErr(SetControlData, controlHandle, kControlButtonPart,
	    kControlBevelButtonGraphicAlignTag,
	    sizeof(ControlButtonGraphicAlignment), (char *) &theAlignment);

    if (butPtr->compound != COMPOUND_NONE) {
	ControlButtonTextPlacement thePlacement =
		kControlBevelButtonPlaceNormally;

	if (butPtr->compound == COMPOUND_TOP) {
	    thePlacement = kControlBevelButtonPlaceBelowGraphic;
	} else if (butPtr->compound == COMPOUND_BOTTOM) {
	    thePlacement = kControlBevelButtonPlaceAboveGraphic;
	} else if (butPtr->compound == COMPOUND_LEFT) {
	    thePlacement = kControlBevelButtonPlaceToRightOfGraphic;
	} else if (butPtr->compound == COMPOUND_RIGHT) {
	    thePlacement = kControlBevelButtonPlaceToLeftOfGraphic;
	}
	ChkErr(SetControlData, controlHandle, kControlButtonPart,
		kControlBevelButtonTextPlaceTag,
		sizeof(ControlButtonTextPlacement), (char *) &thePlacement);
a954 19
}

/*
 *--------------------------------------------------------------
 *
 * SetUserPaneDrawProc --
 *
 *	Utility function to add a UserPaneDrawProc
 *	to a userPane control. From MoreControls code
 *	from Apple DTS.
 *
 * Results:
 *	MacOS system error.
 *
 * Side effects:
 *	The user pane gets a new UserPaneDrawProc.
 *
 *--------------------------------------------------------------
 */
d956 7
a962 6
OSStatus
SetUserPaneDrawProc(
    ControlRef control,
    ControlUserPaneDrawProcPtr upp)
{
    ControlUserPaneDrawUPP myControlUserPaneDrawUPP;
d964 2
a965 22
    myControlUserPaneDrawUPP = NewControlUserPaneDrawUPP(upp);
    return SetControlData(control, kControlNoPart,
	    kControlUserPaneDrawProcTag, sizeof(myControlUserPaneDrawUPP),
	    (Ptr) &myControlUserPaneDrawUPP);
}

/*
 *--------------------------------------------------------------
 *
 * SetUserPaneSetUpSpecialBackgroundProc --
 *
 *	Utility function to add a UserPaneBackgroundProc
 *	to a userPane control
 *
 * Results:
 *	MacOS system error.
 *
 * Side effects:
 *	The user pane gets a new UserPaneBackgroundProc.
 *
 *--------------------------------------------------------------
 */
d967 8
a974 6
OSStatus
SetUserPaneSetUpSpecialBackgroundProc(
    ControlRef control,
    ControlUserPaneBackgroundProcPtr upp)
{
    ControlUserPaneBackgroundUPP myControlUserPaneBackgroundUPP;
d976 11
a986 23
    myControlUserPaneBackgroundUPP = NewControlUserPaneBackgroundUPP(upp);
    return SetControlData(control, kControlNoPart,
	    kControlUserPaneBackgroundProcTag,
	    sizeof(myControlUserPaneBackgroundUPP),
	    (Ptr) &myControlUserPaneBackgroundUPP);
}

/*
 *--------------------------------------------------------------
 *
 * UserPaneDraw --
 *
 *	This function draws the background of the user pane that will
 *	lie under checkboxes and radiobuttons.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The user pane gets updated to the current color.
 *
 *--------------------------------------------------------------
 */
d988 6
a993 31
void
UserPaneDraw(
    ControlRef control,
    ControlPartCode cpc)
{
    MacButton *mbPtr = (MacButton *)(intptr_t)GetControlReference(control);
    Rect contrlRect;
    CGrafPtr port;
    
    GetPort(&port);
    GetControlBounds(control,&contrlRect);
    TkMacOSXSetColorInPort(mbPtr->userPaneBackground, 0, NULL, port);
    EraseRect(&contrlRect);
}

/*
 *--------------------------------------------------------------
 *
 * UserPaneBackgroundProc --
 *
 *	This function sets up the background of the user pane that will
 *	lie under checkboxes and radiobuttons.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The user pane background gets set to the current color.
 *
 *--------------------------------------------------------------
 */
d995 4
a998 6
void
UserPaneBackgroundProc(
    ControlHandle control,
    ControlBackgroundPtr info)
{
    MacButton * mbPtr = (MacButton *)(intptr_t)GetControlReference(control);
d1000 3
a1002 36
    if (info->colorDevice) {
	CGrafPtr port;
	
	GetPort(&port);
	TkMacOSXSetColorInPort(mbPtr->userPaneBackground, 0, NULL, port);
    }
}

/*
 *--------------------------------------------------------------
 *
 * UpdateControlColors --
 *
 *	This function will review the colors used to display
 *	a Macintosh button. If any non-standard colors are
 *	used we create a custom palette for the button, populate
 *	with the colors for the button and install the palette.
 *
 *	Under Appearance, we just set the pointer that will be
 *	used by the UserPaneDrawProc.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The Macintosh control may get a custom palette installed.
 *
 *--------------------------------------------------------------
 */

static int
UpdateControlColors(
    MacButton *mbPtr)
{
    XColor *xcolor;
    TkButton *butPtr = (TkButton *) mbPtr;
d1004 3
a1006 15
    /*
     * Under Appearance we cannot change the background of the
     * button itself. However, the color we are setting is the color
     * of the containing userPane. This will be the color that peeks
     * around the rounded corners of the button.
     * We make this the highlightbackground rather than the background,
     * because if you color the background of a frame containing a
     * button, you usually also color the highlightbackground as well,
     * or you will get a thin grey ring around the button.
     */

    if (butPtr->type == TYPE_BUTTON) {
	xcolor = Tk_3DBorderColor(butPtr->highlightBorder);
    } else {
	xcolor = Tk_3DBorderColor(butPtr->normalBorder);
d1008 2
a1009 1
    mbPtr->userPaneBackground = xcolor->pixel;
d1011 6
a1016 19
    return false;
}

/*
 *--------------------------------------------------------------
 *
 * ButtonEventProc --
 *
 *	This procedure is invoked by the Tk dispatcher for various
 *	events on buttons.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */
d1018 4
a1021 7
static void
ButtonEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkButton *buttonPtr = (TkButton *) clientData;
    MacButton *mbPtr = (MacButton *) clientData;
d1023 3
a1025 7
    if (eventPtr->type == ActivateNotify
	    || eventPtr->type == DeactivateNotify) {
	if ((buttonPtr->tkwin == NULL) || (!Tk_IsMapped(buttonPtr->tkwin))) {
	    return;
	}
	if (eventPtr->type == ActivateNotify) {
	    mbPtr->flags |= ACTIVE;
d1027 1
a1027 5
	    mbPtr->flags &= ~ACTIVE;
	}
	if ((buttonPtr->flags & REDRAW_PENDING) == 0) {
	    Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) buttonPtr);
	    buttonPtr->flags |= REDRAW_PENDING;
d1035 1
a1035 1
 * TkMacOSXComputeControlParams --
d1037 3
a1039 3
 *	This procedure computes the various parameters used
 *	when creating a Carbon control (NewControl).
 *	These are determined by the various tk button parameters
d1045 1
a1045 1
 *	Sets the control initialisation parameters
d1050 3
a1052 4
static void
TkMacOSXComputeControlParams(
    TkButton *butPtr,
    MacControlParams *paramsPtr)
d1054 5
a1058 1
    paramsPtr->isBevel = 0;
d1061 1
a1061 1
     * Determine ProcID based on button type and dimensions.
d1064 2
a1065 66
    switch (butPtr->type) {
	case TYPE_BUTTON:
	    if ((butPtr->image == None) && (butPtr->bitmap == None)) {
		paramsPtr->initialValue = 1;
		paramsPtr->minValue = 0;
		paramsPtr->maxValue = 1;
		paramsPtr->procID = kControlPushButtonProc;
	    } else {
		paramsPtr->initialValue = 0;
		paramsPtr->minValue = kControlBehaviorOffsetContents |
			kControlContentPictHandle;
		paramsPtr->maxValue = 1;
		if (butPtr->borderWidth <= 2) {
		    paramsPtr->procID = kControlBevelButtonSmallBevelProc;
		} else if (butPtr->borderWidth == 3) {
		    paramsPtr->procID = kControlBevelButtonNormalBevelProc;
		} else {
		    paramsPtr->procID = kControlBevelButtonLargeBevelProc;
		}
		paramsPtr->isBevel = 1;
	    }
	    break;
	case TYPE_RADIO_BUTTON:
	    if (((butPtr->image == None) && (butPtr->bitmap == None))
		|| (butPtr->indicatorOn)) {
		paramsPtr->initialValue = 1;
		paramsPtr->minValue = 0;
		paramsPtr->maxValue = MAX_VALUE;
		paramsPtr->procID = kControlRadioButtonProc;
	    } else {
		paramsPtr->initialValue = 0;
		paramsPtr->minValue = kControlBehaviorOffsetContents |
			kControlBehaviorSticky | kControlContentPictHandle;
		paramsPtr->maxValue = MAX_VALUE;
		if (butPtr->borderWidth <= 2) {
		    paramsPtr->procID = kControlBevelButtonSmallBevelProc;
		} else if (butPtr->borderWidth == 3) {
		    paramsPtr->procID = kControlBevelButtonNormalBevelProc;
		} else {
		    paramsPtr->procID = kControlBevelButtonLargeBevelProc;
		}
		paramsPtr->isBevel = 1;
	    }
	    break;
	case TYPE_CHECK_BUTTON:
	    if (((butPtr->image == None) && (butPtr->bitmap == None))
		    || (butPtr->indicatorOn)) {
		paramsPtr->initialValue = 1;
		paramsPtr->minValue = 0;
		paramsPtr->maxValue = MAX_VALUE;
		paramsPtr->procID = kControlCheckBoxProc;
	    } else {
		paramsPtr->initialValue = 0;
		paramsPtr->minValue = kControlBehaviorOffsetContents |
			kControlBehaviorSticky | kControlContentPictHandle;
		paramsPtr->maxValue = MAX_VALUE;
		if (butPtr->borderWidth <= 2) {
		    paramsPtr->procID = kControlBevelButtonSmallBevelProc;
		} else if (butPtr->borderWidth == 3) {
		    paramsPtr->procID = kControlBevelButtonNormalBevelProc;
		} else {
		    paramsPtr->procID = kControlBevelButtonLargeBevelProc;
		}
		paramsPtr->isBevel = 1;
	    }
	    break;
d1067 1
a1067 19
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXComputeDrawParams --
 *
 *	This procedure computes the various parameters used
 *	when drawing a button
 *	These are determined by the various tk button parameters
 *
 * Results:
 *	1 if control will be used, 0 otherwise.
 *
 * Side effects:
 *	Sets the button draw parameters
 *
 *----------------------------------------------------------------------
 */
d1069 5
a1073 18
static int
TkMacOSXComputeDrawParams(
    TkButton *butPtr,
    DrawParams *dpPtr)
{
    dpPtr->hasImageOrBitmap = ((butPtr->image != NULL)
	    || (butPtr->bitmap != None));
    dpPtr->offset = (butPtr->type == TYPE_BUTTON)
	    && dpPtr->hasImageOrBitmap;
    dpPtr->border = butPtr->normalBorder;
    if ((butPtr->state == STATE_DISABLED) && (butPtr->disabledFg != NULL)) {
	dpPtr->gc = butPtr->disabledGC;
    } else if (butPtr->type == TYPE_BUTTON && butPtr->state == STATE_ACTIVE) {
	dpPtr->gc = butPtr->activeTextGC;
	dpPtr->border = butPtr->activeBorder;
    } else {
	dpPtr->gc = butPtr->normalTextGC;
    }
d1075 6
a1080 3
    if ((butPtr->flags & SELECTED) && (butPtr->state != STATE_ACTIVE)
	    && (butPtr->selectBorder != NULL) && !butPtr->indicatorOn) {
	dpPtr->border = butPtr->selectBorder;
d1083 2
a1084 6
    /*
     * Override the relief specified for the button if this is a
     * checkbutton or radiobutton and there's no indicator.
     * However, don't do this in the presence of Appearance, since
     * then the bevel button will take care of the relief.
     */
d1086 3
a1088 1
    dpPtr->relief = butPtr->relief;
d1090 5
a1094 5
    if ((butPtr->type >= TYPE_CHECK_BUTTON) && !butPtr->indicatorOn) {
	if (!dpPtr->hasImageOrBitmap) {
	    dpPtr->relief = (butPtr->flags & SELECTED) ? TK_RELIEF_SUNKEN
		    : TK_RELIEF_RAISED;
	}
d1098 4
a1101 1
     * Determine the draw type
d1104 21
a1124 8
    if (butPtr->type == TYPE_LABEL) {
	dpPtr->drawType = DRAW_LABEL;
    } else if (butPtr->type == TYPE_BUTTON) {
	if (!dpPtr->hasImageOrBitmap) {
	    dpPtr->drawType = DRAW_CONTROL;
	} else if (butPtr->image != None) {
	    dpPtr->drawType = DRAW_BEVEL;
	} else {
d1126 1
a1126 8
	     * TO DO - The current way the we draw bitmaps (XCopyPlane)
	     * uses CopyDeepMask in this one case. The Picture recording
	     * does not record this call, and so we can't use the
	     * Appearance bevel button here. The only case that would
	     * exercise this is if you use a bitmap, with
	     * -data & -mask specified. We should probably draw the
	     * appearance button and overprint the image in this case.
	     * This just punts and draws the old-style, ugly, button.
d1129 12
a1140 4
	    if (dpPtr->gc->clip_mask == 0) {
		dpPtr->drawType = DRAW_BEVEL;
	    } else {
		TkpClipMask *clipPtr = (TkpClipMask *) dpPtr->gc->clip_mask;
d1142 9
a1150 6
		if ((clipPtr->type == TKP_CLIP_PIXMAP) &&
			(clipPtr->value.pixmap != butPtr->bitmap)) {
		    dpPtr->drawType = DRAW_CUSTOM;
		} else {
		    dpPtr->drawType = DRAW_BEVEL;
		}
a1151 6
	}
    } else if (butPtr->indicatorOn) {
	dpPtr->drawType = DRAW_CONTROL;
    } else if (dpPtr->hasImageOrBitmap) {
	if (dpPtr->gc->clip_mask == 0) {
	    dpPtr->drawType = DRAW_BEVEL;
d1153 2
a1154 1
	    TkpClipMask *clipPtr = (TkpClipMask*) dpPtr->gc->clip_mask;
d1156 5
a1160 5
	    if ((clipPtr->type == TKP_CLIP_PIXMAP) &&
		    (clipPtr->value.pixmap != butPtr->bitmap)) {
		dpPtr->drawType = DRAW_CUSTOM;
	    } else {
		dpPtr->drawType = DRAW_BEVEL;
a1162 2
    } else {
	dpPtr->drawType = DRAW_CUSTOM;
d1165 3
a1167 4
    if ((dpPtr->drawType == DRAW_CONTROL) || (dpPtr->drawType == DRAW_BEVEL)) {
	return 1;
    } else {
	return 0;
d1169 3
d1173 9
@


1.32
log
@merge stable branch onto HEAD
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.25.2.5 2007/11/12 19:22:38 dgp Exp $
d489 1
a489 1
		    butPtr->borderWidth, dpPtr->relief);
@


1.32.2.1
log
@TkpDisplayButton: use computed borderWidth
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.32 2007/12/13 15:27:08 dgp Exp $
d489 1
a489 1
		    borderWidth, dpPtr->relief);
@


1.31
log
@	* macosx/tkMacOSXButton.c:	sync formatting, whitespace, copyright
	* macosx/tkMacOSXDialog.c:	with core-8-4-branch.
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXWm.c:
	* xlib/xgc.c
	* library/bgerror.tcl:
	* library/console.tcl:
	* library/menu.tcl:
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.30 2007/11/08 14:25:59 das Exp $
@


1.30
log
@	* macosx/tkMacOSXButton.c:	replace HiliteControl() by modern API
	* macosx/tkMacOSXMenubutton.c:	for activation and enabling;
					distinguish inactive and disabled
					look&feel; correct activation handling
					to match that of container toplevel.

	* macosx/tkMacOSXMenubutton.c:	correct size computation of bevelbutton
					variant to match that of buttons;
					fix crash with bitmap due to NULL GC;
					delay picParams setup until needed;
					formatting cleanup. [Bug 1824521]
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.29 2007/10/15 20:52:47 hobbs Exp $
d28 2
d1461 1
a1461 1
		paramsPtr->maxValue = 2;
d1467 1
a1467 1
		paramsPtr->maxValue = 2;
d1483 1
a1483 1
		paramsPtr->maxValue = 2;
d1489 1
a1489 1
		paramsPtr->maxValue = 2;
@


1.29
log
@	* generic/tkFocus.c, generic/tkFrame.c, generic/tkInt.h:
	* macosx/tkMacOSXButton.c, macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXWm.c, unix/tkUnixWm.c, win/tkWinWm.c:
	* doc/wm.n, tests/wm.test: TIP #125 implementation [Bug 998125]
	Adds [wm manage|forget] for dockable frames.
	Finished X11 and Windows code, needs OS X completion.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.28 2007/10/12 03:06:37 das Exp $
d24 4
a94 1

a123 1
int tkPictureIsOpen;
d158 1
a158 1
    bzero(&macButtonPtr->fontStyle,sizeof(macButtonPtr->fontStyle));
d185 1
a185 1
    MacButton *macButtonPtr = (MacButton *)clientData;
a202 1

d716 1
a716 1
    if (TkMacOSXComputeDrawParams(butPtr,&drawParams)) {
d833 4
a836 1
    mbPtr->flags |= (1 + 2);
d870 1
d921 1
a921 1
    if (!(mbPtr->flags & 1)) {
d979 17
a995 10
    if (!Tk_MacOSXIsAppInFront() || butPtr->state == STATE_DISABLED) {
	HiliteControl(mbPtr->control, kControlInactivePart);
    } else {
	/*
	 * Use NoPart for normal and to ensure correct direct transition from
	 * disabled to active -state. [Bug 706446]
	 */

	HiliteControl(mbPtr->control, kControlNoPart);

d1012 2
d1030 1
a1030 1
    if (mbPtr->flags & 2) {
d1033 1
a1033 1
	mbPtr->flags ^= 2;
d1040 4
a1043 1
	KillPicture(mbPtr->bevelButtonContent.u.picture);
d1093 17
a1109 16
    portChanged = QDSwapPort(destPort, &savePort);
    mbPtr->picParams.version = -2;
    mbPtr->picParams.hRes = 0x00480000;
    mbPtr->picParams.vRes = 0x00480000;
    mbPtr->picParams.srcRect.top = 0;
    mbPtr->picParams.srcRect.left = 0;
    mbPtr->picParams.srcRect.right = width;
    mbPtr->picParams.srcRect.bottom = height;
    mbPtr->picParams.reserved1 = 0;
    mbPtr->picParams.reserved2 = 0;
    mbPtr->bevelButtonContent.contentType = kControlContentPictHandle;
    mbPtr->bevelButtonContent.u.picture = OpenCPicture(&mbPtr->picParams);
    if (!mbPtr->bevelButtonContent.u.picture) {
	TkMacOSXDbgMsg("OpenCPicture failed");
    }
    tkPictureIsOpen = 1;
d1111 6
a1116 5
    /*
     * TO DO - There is one case where XCopyPlane calls CopyDeepMask,
     * which does not get recorded in the picture. So the bitmap code
     * will fail in that case.
     */
d1131 6
a1136 4
    ClosePicture();
    tkPictureIsOpen = 0;
    if (portChanged) {
	QDSwapPort(savePort, NULL);
d1384 1
d1391 5
@


1.28
log
@	* macosx/tkMacOSXButton.c:	delay picParams setup until needed.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.27 2007/06/29 03:20:00 das Exp $
d866 1
d892 6
a897 1

d902 1
a902 1
	if (bcmp(&params, &mbPtr->params, sizeof(params))) {
d940 1
a940 1
	if (bcmp(mbPtr->controlTitle, controlTitle, len+1)) {
@


1.27
log
@	* macosx/tkMacOSXScrlbr.c: correct int <-> dobule conversion issues
	that could lead to Carbon getting confused about scrollbar thumb size.

	* macosx/tkMacOSXDraw.c (XCopyArea, XCopyPlane, TkPutImage) use
	TkMacOSX{Setup,Restore}DrawingContext() to setup/restore clip & colors.
	(TkMacOSXSetupDrawingContext, TkMacOSXRestoreDrawingContext): add save
	and restore of QD port clip region; factor out clip region code common
	to CG and QD branches; check for port and context validity; handle
	tkPictureIsOpen flag during QD port setup.
	(TkScrollWindow): remove unnecessary scroll region manipulation

	* macosx/tkMacOSXDraw.c:	remove second global QD temp region
	* macosx/tkMacOSXInt.h:		(no longer necessary) and rename
	* macosx/tkMacOSXRegion.c:	remaining global QD temp region.
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWindowEvent.c:

	* macosx/tkMacOSXDraw.c:	make useCGDrawing variable MODULE_SCOPE
	* macosx/tkMacOSXFont.c:	and respect it for ATSUI font drawing.

	* macosx/tkMacOSXButton.c:	reduce reliance on current QD port
	* macosx/tkMacOSXColor.c:	setting and remove unnecessary
	* macosx/tkMacOSXDebug.c:	references to a drawable's QD port,
	* macosx/tkMacOSXDebug.h:	notably replace GetWindowFromPort(
	* macosx/tkMacOSXDialog.c:	TkMacOSXGetDrawablePort()) idiom by new
	* macosx/tkMacOSXDraw.c:	TkMacOSXDrawableWindow() and change
	* macosx/tkMacOSXKeyEvent.c:	TkMacOSXSetColorInPort() to take a port
	* macosx/tkMacOSXMenu.c:	argument.
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:

	* macosx/tkMacOSXInt.h:			factor out macros, declarations
	* macosx/tkMacOSXPrivate.h (new):	and prototypes that are purely
	internal and private to the 'macosx' sources into a new internal header
	file that does _not_ get installed into Tk.framework/PrivateHeaders.

	* macosx/tkMacOSXButton.c:		#include new tkMacOSXPrivate.h
	* macosx/tkMacOSXCarbonEvents.c:	instead of tkMacOSXInt.h.
	* macosx/tkMacOSXClipboard.c:
	* macosx/tkMacOSXColor.c:
	* macosx/tkMacOSXCursor.c:
	* macosx/tkMacOSXDebug.c:
	* macosx/tkMacOSXDialog.c:
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXEntry.c:
	* macosx/tkMacOSXEvent.c:
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXHLEvents.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXNotify.c:
	* macosx/tkMacOSXRegion.c:
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXXStubs.c:
	* macosx/ttkMacOSXTheme.c:
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.26 2007/05/31 13:38:13 das Exp $
a82 2
    CCTabHandle tabHandle;
    Pixmap picPixmap;
a154 8
    macButtonPtr->picParams.version = -2;
    macButtonPtr->picParams.hRes = 0x00480000;
    macButtonPtr->picParams.vRes = 0x00480000;
    macButtonPtr->picParams.srcRect.top = 0;
    macButtonPtr->picParams.srcRect.left = 0;
    macButtonPtr->picParams.reserved1 = 0;
    macButtonPtr->picParams.reserved2 = 0;
    macButtonPtr->bevelButtonContent.contentType = kControlContentPictHandle;
d1055 1
a1055 3
    Boolean portChanged;

    portChanged = QDSwapPort(destPort, &savePort);
d1070 6
d1078 3
a1080 5

    /*
     * Set the flag to circumvent clipping and bounds problems with OS 10.0.4
     */

d1108 3
a1110 1

d1112 2
a1113 1
	    kControlBevelButtonContentTag, sizeof(ControlButtonContentInfo),
a1134 1

a1155 3
    if (portChanged) {
	QDSwapPort(savePort, NULL);
    }
@


1.26
log
@	* macosx/tkMacOSXWindowEvent.c (GenerateUpdateEvent): complete all
	pending idle-time redraws before newly posted Expose events are
	processed; add bounds of redrawn windows to update region to ensure all
	child windows overdrawn by parents are redrawn.

	* macosx/tkMacOSXWindowEvent.c:	centralize clip and window invalidation
	* macosx/tkMacOSXSubwindows.c:	after location/size changes in the
	* macosx/tkMacOSXWm.c:		BoundsChanged carbon event handler;
	correct/add window invalidation after window attribute changes.

	* macosx/tkMacOSXSubwindows.c (XResizeWindow, XMoveResizeWindow,
	XMoveWindow): factor out common code dealing with embedded and
	non-toplevel windows; remove unnecessary clip and window invalidation.

	* macosx/tkMacOSXButton.c (TkpDisplayButton): move clip setup closer to
	native button drawing calls.

	* macosx/tkMacOSXWm.c (TkMacOSXIsWindowZoomed, TkMacOSXZoomToplevel):
	correct handle gridded windows in max size calculations.

	* macosx/tkMacOSXEvent.c (TkMacOSXFlushWindows): use HIWindowFlush API
	when available.

	* macosx/tkMacOSXColor.c:	cleanup whitespace and formatting.
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWm.c:
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.25 2007/05/09 12:55:15 das Exp $
d17 1
a17 1
#include "tkMacOSXInt.h"
d800 1
a800 2
    mbPtr->windowRef = GetWindowFromPort(
	    TkMacOSXGetDrawablePort(Tk_WindowId(butPtr->tkwin)));
d1253 3
a1255 1

d1257 1
a1257 1
    TkMacOSXSetColorInPort(mbPtr->userPaneBackground, 0, NULL);
d1286 4
a1289 1
	TkMacOSXSetColorInPort(mbPtr->userPaneBackground, 0, NULL);
@


1.25
log
@	* macosx/tkMacOSXWindowEvent.c:	ensure window is brought to the front
	* macosx/tkMacOSXMouseEvent.c:	at the start of a window drag (except
	* macosx/tkMacOSXInt.h:		when cmd key is down); formatting and
					whitespace fixes.

	* macosx/tkMacOSXDialog.c (Tk_GetSaveFileObjCmd): add -filetypes option
	processing (fixes fileDialog-0.1, fileDialog-0.2 failures).

	* macosx/tkMacOSXEmbed.c (TkpMakeWindow, TkpUseWindow): fix sending of
	Visibility event for embedded windows (fixes frame-3.9 hang).

	* macosx/tkMacOSXScrlbr.c (ScrollbarBindProc):		fix testsuite
	* macosx/tkMacOSXSubwindows.c (TkMacOSXUpdateClipRgn):	crashes by
	adding sanity checks.

	* macosx/Wish.xcodeproj/project.pbxproj: add 'DebugUnthreaded' &
	* macosx/Wish.xcodeproj/default.pbxuser: 'DebugLeaks' targets and env
	var settings needed to run the 'leaks' tool.

	* macosx/tkMacOSXButton.c: fix debug msg typo.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.24 2007/04/25 15:06:13 das Exp $
a227 9
     * Set up clipping region. Make sure the we are using the port
     * for this button, or we will set the wrong window's clip.
     */

    destPort = TkMacOSXGetDrawablePort(pixmap);
    portChanged = QDSwapPort(destPort, &savePort);
    TkMacOSXSetUpClippingRgn(pixmap);

    /*
d243 9
@


1.25.2.1
log
@merge updates from HEAD
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.25 2007/05/09 12:55:15 das Exp $
d228 9
a251 9
     * Set up clipping region. Make sure the we are using the port
     * for this button, or we will set the wrong window's clip.
     */

    destPort = TkMacOSXGetDrawablePort(pixmap);
    portChanged = QDSwapPort(destPort, &savePort);
    TkMacOSXSetUpClippingRgn(pixmap);

    /*
@


1.25.2.2
log
@merge updates from HEAD
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id$
d17 1
a17 1
#include "tkMacOSXPrivate.h"
d800 2
a801 1
    mbPtr->windowRef = TkMacOSXDrawableWindow(Tk_WindowId(butPtr->tkwin));
d1254 1
a1254 3
    CGrafPtr port;
    
    GetPort(&port);
d1256 1
a1256 1
    TkMacOSXSetColorInPort(mbPtr->userPaneBackground, 0, NULL, port);
d1285 1
a1285 4
	CGrafPtr port;
	
	GetPort(&port);
	TkMacOSXSetColorInPort(mbPtr->userPaneBackground, 0, NULL, port);
@


1.25.2.3
log
@merge updates from HEAD
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.25.2.2 2007/07/01 17:31:31 dgp Exp $
d83 2
d157 8
d1065 3
a1067 1
    Boolean portChanged = false;
a1081 6
    portChanged = QDSwapPort(destPort, &savePort);
    mbPtr->picParams.version = -2;
    mbPtr->picParams.hRes = 0x00480000;
    mbPtr->picParams.vRes = 0x00480000;
    mbPtr->picParams.srcRect.top = 0;
    mbPtr->picParams.srcRect.left = 0;
d1084 5
a1088 3
    mbPtr->picParams.reserved1 = 0;
    mbPtr->picParams.reserved2 = 0;
    mbPtr->bevelButtonContent.contentType = kControlContentPictHandle;
d1116 1
a1116 3
    if (portChanged) {
	QDSwapPort(savePort, NULL);
    }
d1118 1
a1118 2
	    kControlBevelButtonContentTag,
	    sizeof(ControlButtonContentInfo),
d1140 1
d1162 3
@


1.25.2.4
log
@merge updates from HEAD
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.25.2.3 2007/10/15 18:38:34 dgp Exp $
a865 1
    int rebuild;
d891 1
a891 6
#ifdef TK_REBUILD_TOPLEVEL
    rebuild = (winPtr->flags & TK_REBUILD_TOPLEVEL);
    winPtr->flags &= ~TK_REBUILD_TOPLEVEL;
#else
    rebuild = 0;
#endif
d896 1
a896 1
	if (rebuild || bcmp(&params, &mbPtr->params, sizeof(params))) {
d934 1
a934 1
	if (rebuild || bcmp(mbPtr->controlTitle, controlTitle, len+1)) {
@


1.25.2.5
log
@merge updates from HEAD
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.25.2.4 2007/10/16 04:03:54 dgp Exp $
a23 6
#define CONTROL_INITIALIZED 1
#define FIRST_DRAW	    2
#define ACTIVE		    4

#define MAX_VALUE	    2

d91 1
d121 1
d156 1
a156 1
    bzero(&macButtonPtr->fontStyle, sizeof(macButtonPtr->fontStyle));
d183 1
a183 1
    MacButton *macButtonPtr = (MacButton *) clientData;
d201 1
d715 1
a715 1
    if (TkMacOSXComputeDrawParams(butPtr, &drawParams)) {
d832 1
a832 4
    mbPtr->flags |= (CONTROL_INITIALIZED | FIRST_DRAW);
    if (IsWindowActive(mbPtr->windowRef)) {
	mbPtr->flags |= ACTIVE;
    }
a865 1
    int active, enabled;
d916 1
a916 1
    if (!(mbPtr->flags & CONTROL_INITIALIZED)) {
d974 10
a983 17
    active = ((mbPtr->flags & ACTIVE) != 0);
    if (active != IsControlActive(mbPtr->control)) {
	if (active) {
	    ChkErr(ActivateControl, mbPtr->control);
	} else {
	    ChkErr(DeactivateControl, mbPtr->control);
	}
    }
    enabled = !(butPtr->state == STATE_DISABLED);
    if (enabled != IsControlEnabled(mbPtr->control)) {
	if (enabled) {
	    ChkErr(EnableControl, mbPtr->control);
	} else {
	    ChkErr(DisableControl, mbPtr->control);
	}
    }
    if (active && enabled) {
a999 2
	} else {
	    HiliteControl(mbPtr->control, kControlNoPart);
d1016 1
a1016 1
    if (mbPtr->flags & FIRST_DRAW) {
d1019 1
a1019 1
	mbPtr->flags ^= FIRST_DRAW;
d1026 1
a1026 4
	if (mbPtr->bevelButtonContent.contentType ==
		kControlContentPictHandle) {
	    KillPicture(mbPtr->bevelButtonContent.u.picture);
	}
d1076 16
a1091 17
    {
	portChanged = QDSwapPort(destPort, &savePort);
	mbPtr->picParams.version = -2;
	mbPtr->picParams.hRes = 0x00480000;
	mbPtr->picParams.vRes = 0x00480000;
	mbPtr->picParams.srcRect.top = 0;
	mbPtr->picParams.srcRect.left = 0;
	mbPtr->picParams.srcRect.bottom = height;
	mbPtr->picParams.srcRect.right = width;
	mbPtr->picParams.reserved1 = 0;
	mbPtr->picParams.reserved2 = 0;
	mbPtr->bevelButtonContent.contentType = kControlContentPictHandle;
	mbPtr->bevelButtonContent.u.picture = OpenCPicture(&mbPtr->picParams);
	if (!mbPtr->bevelButtonContent.u.picture) {
	    TkMacOSXDbgMsg("OpenCPicture failed");
	}
	tkPictureIsOpen = 1;
d1093 5
a1097 6
	/*
	 * TO DO - There is one case where XCopyPlane calls CopyDeepMask,
	 * which does not get recorded in the picture. So the bitmap code
	 * will fail in that case.
	 */
     }
d1112 4
a1115 6
    {
	ClosePicture();
	tkPictureIsOpen = 0;
	if (portChanged) {
	    QDSwapPort(savePort, NULL);
	}
a1362 1
    MacButton *mbPtr = (MacButton *) clientData;
a1368 5
	if (eventPtr->type == ActivateNotify) {
	    mbPtr->flags |= ACTIVE;
	} else {
	    mbPtr->flags &= ~ACTIVE;
	}
d1432 1
a1432 1
		paramsPtr->maxValue = MAX_VALUE;
d1438 1
a1438 1
		paramsPtr->maxValue = MAX_VALUE;
d1454 1
a1454 1
		paramsPtr->maxValue = MAX_VALUE;
d1460 1
a1460 1
		paramsPtr->maxValue = MAX_VALUE;
@


1.24
log
@silence debug build error messages
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.23 2007/04/23 21:24:33 das Exp $
d836 1
a836 1
	TkMacOSXDbgMsg("failed to create control of type %d\n", procID);
@


1.23
log
@	* macosx/tkMacOSXCarbonEvents.c: add window event target carbon event
	* macosx/tkMacOSXEvent.c:	 handler for all kEventClassWindow and
	* macosx/tkMacOSXEvent.h:	 kEventClassMouse events;
	* macosx/tkMacOSXNotify.c:	 move all remaining events except for
	* macosx/tkMacOSXWindowEvent.c:	 kEventClassKeyboard from dispatcher to
	application event handler; pass event handler callRef downstream; fix
	debug event tracing; process all tcl event types in carbon event timer;
	delay carbon event timer first fire; add TkMacOSXTrackingLoop() to mark
	enter/exit of event tracking loop during which all tcl events but only
	carbon update events should be processed by the timer (replaces various
	calls to Tcl_SetServiceMode()); rename TkMacOSXReceiveAndProcessEvent()
	to TkMacOSXReceiveAndDispatchEvent(), move it from tkMacOSXEvent.c to
	tkMacOSXCarbonEvents.c and modify it to dequeue only update events
	during a tracking loop; add TkMacOSXRunTclEventLoop() to standardize
	the various ways in use to run the tcl event loop; add handling of
	kEventClassAppearance events (for ScrollBarVariantChanged event).

	* macosx/tkMacOSXDialog.c:	use new TkMacOSXTrackingLoop() around
	* macosx/tkMacOSXEvent.c:	blocking API that puts up modal dialogs
	* macosx/tkMacOSXMenu.c:	or when entering/exiting menu/control
	* macosx/tkMacOSXMouseEvent.c:	tracking, window dragging and other
	* macosx/tkMacOSXScale.c:	mouse tracking loops.
	* macosx/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:

	* macosx/tkMacOSXDialog.c:	use new TkMacOSXRunTclEventLoop()
	* macosx/tkMacOSXScale.c:	instead of Tcl_DoOneEvent(),
	* macosx/tkMacOSXScrlbr.c:	Tcl_ServiceAll(), TclServiceIdle()
	* macosx/tkMacOSXWindowEvent.c:	and Tcl_GlobalEval("update idletasks").

	* macosx/tkMacOSXColor.c: make available as Tk system colors all
	* macosx/tkMacOSXPort.h:  appearance manager brushes, text colors and
	backgrounds with new and legacy names, as well as the fully transparent
	color "systemTransparent"; add TkMacOSXSetColorIn{Port,Context}() to
	directly set an X pixel color value in the current QD port resp. the
	given CG context without requiring passage through rgb representation
	(lossy for most system colors); modernize/remove Classic-era code;
	replace crufty strcmp() elseifs by Tcl_GetIndexFromObjStruct().

	* macosx/tkMacOSXButton.c:	use new TkMacOSXSetColorInPort()
	* macosx/tkMacOSXDraw.c:	instead of setting rgb color directly
	* macosx/tkMacOSXMenubutton.c:	to allow for non-rgb system colors.

	* macosx/tkMacOSXCursor.c: implement "none" cursor as on other
	platforms [Patch 1615427]; add all missing appearance manager cursors.

	* macosx/tkMacOSXDefault.h: set SELECT_FG_COLORs to None to match aqua
	L&F; use standard system color names; use new 'menu' system font;
	correct default scrollbar width.

	* macosx/tkMacOSXDraw.c:	standardize initialization, use and
	* macosx/tkMacOSXInt.h:		emptying of various static temp rgns
	* macosx/tkMacOSXRegion.c:	onto two global RgnHandles; in debug
	* macosx/tkMacOSXSubwindows.c:	builds, verify emptiness of these temp
	* macosx/tkMacOSXWindowEvent.c:	rgns before use.

	* macosx/tkMacOSXDraw.c: add TkMacOSX{Setup,Restore}DrawingContext() to
	* macosx/tkMacOSXInt.h:  abstract common setup & teardown of drawing
	environment (for both CG and QD); save/restore QD theme drawing state;
	handle GC clip region; add TkpClipDrawableToRect() to allow clipped
	drawing into drawable regardless of GC used; use new system color
	"systemWindowHeaderBackground" to setup background in themed toplevels;
	correct implementation of TkMacOSXMakeStippleMap().

	* macosx/tkMacOSXEntry.c:  use new TkMacOSXSetupDrawingContext() and
	* macosx/tkMacOSXFont.c:   TkMacOSXRestoreDrawingContext() instead of
	* macosx/ttkMacOSXTheme.c: various setup/teardown procs like
	TkMacOSX{SetUp,Release}CGContext(), TkMacOSXQuarz{Start,End}Draw(),
	TkMacOSXSetUpGraphicsPort() etc.

	* macosx/tkMacOSXEmbed.c: add CG context and drawable clip rgn fields
	* macosx/tkMacOSXInt.h:   to MacDrawable struct.
	* macosx/tkMacOSXSubwindows.c:

	* macosx/tkMacOSXDialog.c: make -parent option of tk_getOpenFile et al.
	use the sheet version of NavServices dialogs; ensure native parent win
	exists before using StandardSheet API for tk_messageBox [Bug 1677611];
	force sheets to behave like app-modal dialogs via WindowModality() API;
	use more modern ColorPicker API.

	* macosx/tkAboutDlg.r: use themed movable modal dialog, fix (c) year.

	* macosx/tkMacOSXEntry.c:  take xOff/yOff of MacDrawable into account
	* macosx/ttkMacOSXTheme.c: when computing locations/bounds to ensure
	correct posititioning when not drawing into intermediate pixmap.

	* macosx/tkMacOSXFont.c: use appearance manager API to map system font
	* macosx/tkMacOSXFont.h: names to TkFonts; add "menu" system font for
	menu item text drawing from MDEF; always draw with CG; remove QD
	dependent stippling algorithm; move most header declarations into the
	source file (as they were not used anywhere else).

	* macosx/tkMacOSXMenu.c:		 large-scale rewrite of custom
	* macosx/tkMacOSXMenu.r (removed):	 MDEF and related code that
	* macosx/Wish.xcode/project.pbxproj:	 restores many longtime-MIA
	* macosx/Wish.xcodeproj/project.pbxproj: features to working order
	* unix/Makefile.in:			 (e.g. images, custom colors &
	fonts in menus etc); implement compound menu items; use Appearance Mgr
	and ThemeText APIs to mimic native MDEF as closely as possible when
	default "menu" system font is used; remove now obsolete SICN drawing
	code and resources.

	* macosx/tkMacOSXCarbonEvents.c: handle additional menu carbon events
	* macosx/tkMacOSXEvent.c:	 in order to support <<MenuSelect>> in
	* macosx/tkMacOSXMenu.c:	 the menubar and in menus that are not
	* macosx/tkMacOSXMenus.c:	 using the custom MDEF [Bug 1620826];
	fix early and missing clearing of current Tk active menu entry; fix
	extraneous sending of <<MenuSelect>> during active menu entry clearing.

	* macosx/tkMacOSXMouseEvent.c: add support for async window dragging by
	the window server; set the corresponding window attribute by default.

	* macosx/tkMacOSXMouseEvent.c: rationalized handling order of
	non-mousedown events; add TkMacOSXModifierState() to retrieve the
	current key modifiers in carbon format.

	* macosx/tkMacOSXScrlbr.c: use appearance manager API to retrieve
	scrollbar component metrics; add awareness of multiple possibilites for
	scrollbar arrow position in aqua and handle user changes to arrow
	position pref; handle difference in metrics of small & large scrollbar
	variants; handle aqua "jump to here" scrollbar behaviour; correct
	computation of scroll view size and position; enforce min scrollbar
	height to avoid scrollbar component overlap; erase scrollbar area
	outside of standard width; remove broken auto-adjust code; account for
	window class when leaving space for grow box; remove code to manually
	draw grow box; use modern API for thumb scroll proc; replace
	HiliteControl() by modern API; replace control mgr constants with
	appearance mgr equivalents.

	* macosx/tkMacOSXSubwindows.c: use SetWindowBounds() API instead of
	SizeWindow(); invalidate clip regions after X{Map,Unmap}Window as fix
	for [Bug 940117] made them dependent on mapping state; remove unneeded
	calls to TkMacOSXInvalClipRgns() and unnecessary setting of QD port;
	use native-endian pixmap on intel; remove obsolete pixmap pix locking.

	* macosx/tkMacOSXWindowEvent.c: handle only the first of a batch of
	kEventAppAvailableWindowBoundsChanged events sent per transaction;
	handle kEventWindowBoundsChanged event to support live window resizing
	and centralized sending of location/size changed ConfigureNotify
	events; ensure HIGrowBox is redrawn after bounds change; constrain
	window after dragging to ensure titlebar is not inacessible
	offscreen or under dock/menubar; handle kEventWindowGetRegion and
	kEventWindowDrawContent for transparent windows to mark resp. paint
	content region as transparent; handle kEventWindowConstrain for
	fullscreen windows to ensure bounds match new screen size; enter/exit
	fullscreen UIMode upon activation/deactivation of fullscreen window.

	* macosx/tkMacOSXWm.c: use live-resize and async-drag carbon window
	* macosx/tkMacOSXWm.h: attributes for toplevels by default; implement
	new [wm attributes] -topmost, -transparent and -fullscreen; refactor
	WmAttributesCmd() parallelling the tkUnixWm.c implementation, use thus
	factored proc to set proxy icon from [wm iconbitmap]; dynamically
	determine default values for toplevel min and max sizes (similar to
	tkWinWm.c impl): min sizes depend on window class & attributes to
	ensure visibility of all titlebar widgets and grow box, max sizes
	depend on maximal window bounds for all active displays; factor out
	code that puts into effect changes to master or override_redirect; use
	RepositionWindow() API to determine staggered initial window bounds;
	correct resize limit calculations, handle gridding and use modern
	resize API in TkMacOSXGrowToplevel(); remove sending of ConfigureNotify
	after resize or zoom (now handled by BoundsChanged handler); correct
	composite carbon window attribute handling, remove currently unusable
	attributes and add new attributes in [tk::unsupported::MacWindowStyle];
	ensure validity of window class and attributes before use; apply
	changes to window class when handling carbon window attribute changes
	(if HIWindowChangeClass() API available); add debug build warning
	message when deprecated window style is used instead of window class;
	use transparent HIGrowBox for resizable windows; avoid unnecessary
	calls to window structure width API; use tcl time API in TkpGetMS();
	add TkMacOSXEnterExitFullscreen() to enter/exit UIMode with dock and
	menubar hidden; restrict wmTracing output to debug builds; remove
	unneeded calls to TkMacOSXInvalClipRgns() and unnecessary setting of QD
	port; workaround GetWindowStructureWidths() Carbon bug (bogus results
	for never-mapped floating windows).

	* macosx/tkMacOSXXStubs.c (TkMacOSXDisplayChanged): add maximal window
	bounds field to Screen record (in ext_data), computed as the union of
	available window positioning bounds of all graphics devices (displays).

	* macosx/tkMacOSXBitmap.c: fix macRoman encoding leak.
	* macosx/tkMacOSXCursor.c:

	* macosx/tkMacOSXDebug.c (TkMacOSXCarbonEventToAscii): use static
	* macosx/tkMacOSXDebug.h: buffer to simplify callers; const fixes.

	* macosx/tkMacOSXBitmap.c: use more efficient QDSwapPort() instead of
	* macosx/tkMacOSXButton.c: GetPort()/SetPort()/GetGWorld()/SetGWorld().
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXXStubs.c:

	* macosx/tkMacOSXColor.c: use kHIToolboxVersionNumber for runtime OS
	* macosx/tkMacOSXEntry.c: version check rather than Gestalt() etc.
	* macosx/tkMacOSXInt.h:
	* macosx/tkMacOSXWm.c:

	* macosx/tkMacOSXDraw.c: remove obsolete and now incorrect
	* macosx/tkMacOSXInt.h:  tkMenuCascadeRgn clipping code.
	* macosx/tkMacOSXMenu.c:

	* macosx/tkMacOSXHLEvents.c: replace Tcl_GlobalEval() resp. Tcl_Eval()
	* macosx/tkMacOSXScrlbr.c:   by Tcl_EvalEx().
	* macosx/tkMacOSXInit.c:

	* macosx/tkMacOSXInit.c (TkpInit): reorder initialization steps.

	* macosx/tkMacOSXKeyEvent.c: remove pre-10.2 support.

	* macosx/tkMacOSXMenus.c: remove now useless call to
	TkMacOSXHandleTearoffMenu(); use \x.. quoting for non-latin1 macroman
	literar chars to allow file to be edited as utf-8.

	* macosx/tkMacOSXScale.c: replace TrackControl() by modern
	* macosx/tkMacOSXScrlbr.c: HandleControlClick() API (using new
	TkMacOSXModifierState()).

	* macosx/tkMacOSXInt.h:		move all constant #defines needed to
	* macosx/tkMacOSXColor.c:	support building on older OS X releases
	* macosx/tkMacOSXEvent.h:	to a central location in tkMacOSXInt.h.
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXWm.c:
	* macosx/ttkMacOSXTheme.c:

	* macosx/tkMacOSXInt.h:		 add ChkErr() macro to factor out
	* macosx/tkMacOSXButton.c:	 Carbon OSStatus return value checking
	* macosx/tkMacOSXCarbonEvents.c: and TkMacOSXDbgMsg() macro to factour
	* macosx/tkMacOSXClipboard.c:	 out debug message output; use these
	* macosx/tkMacOSXColor.c:	 macros to replace #ifdef TK_MAC_DEBUG
	* macosx/tkMacOSXCursor.c:	 blocks & direct printing to stderr,
	* macosx/tkMacOSXDebug.c:	 and to do additional OSStatus return
	* macosx/tkMacOSXDialog.c:	 checking, and to standardize OSStatus
	* macosx/tkMacOSXDraw.c:	 usage.
	* macosx/tkMacOSXEntry.c:
	* macosx/tkMacOSXEvent.c:
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXHLEvents.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXXStubs.c:

	* macosx/tkMacOSXSend.c:	remove duplicate/unused declarations
	* macosx/tkMacOSXXStubs.c:

	* macosx/tkMacOSXDebug.c:	const fixes.
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXTest.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXXStubs.c:

	* macosx/Wish-Info.plist.in: add tcl document extensions/mime types and
	LSMinimumSystemVersion, LSRequiresCarbon & NSAppleScriptEnabled keys.

	* macosx/Wish-Common.xcconfig: add Wish's Info.plist as __info_plist
	section to tktest; enable more warnings.

	* macosx/Wish.xcodeproj/project.pbxproj: add 'DebugMemCompile' build
	configuration that calls configure with --enable-symbols=all; disable
	configure check for __attribute__((__visibility__("hidden"))) in Debug
	configuration to restore availability of ZeroLink.

	* macosx/Wish-Common.xcconfig:	fix whitespace.
	* macosx/Wish-Debug.xcconfig:
	* macosx/Wish-Release.xcconfig:
	* macosx/tkMacOSXAETE.r:
	* macosx/tkMacOSXConfig.c:
	* macosx/tkMacOSXCursors.r:
	* macosx/tkMacOSXKeyboard.c:
	* macosx/tkMacOSXSend.c:
	* macosx/ttkMacOSXTheme.c:
	* macosx/tkMacOSXXCursors.r:
	* macosx/README:

	* macosx/GNUmakefile:		fix/add copyright and license refs.
	* macosx/Tk-Info.plist.in:
	* macosx/Wish-Info.plist.in:
	* macosx/Wish.xcode/project.pbxproj:
	* macosx/Wish.xcodeproj/project.pbxproj:
	* macosx/tkMacOSX.h:
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.22 2007/04/21 19:06:37 hobbs Exp $
d1009 1
a1009 1
    if (butPtr->type == TYPE_BUTTON) {
@


1.22
log
@	* macosx/tkMacOSXBitmap.c, macosx/tkMacOSXButton.c:
	* macosx/tkMacOSXCarbonEvents.c, macosx/tkMacOSXClipboard.c:
	* macosx/tkMacOSXCursor.c, macosx/tkMacOSXDialog.c:
	* macosx/tkMacOSXDraw.c, macosx/tkMacOSXEvent.c:
	* macosx/tkMacOSXFont.c, macosx/tkMacOSXInit.c, macosx/tkMacOSXInt.h:
	* macosx/tkMacOSXKeyEvent.c, macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c, macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXScale.c, macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c: Revert of commits from 2007-04-13 which
	broke the OS X build.
@
text
@d1 1
a1 1
/* 
d4 2
a5 2
 *        This file implements the Macintosh specific portion of the
 *        button widgets.
d9 1
d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.20 2006/08/18 07:30:54 das Exp $
d27 1
d42 1
a42 1
/*  
d51 1
a51 1
    int	   isBevel;
d58 1
a58 1
    int offset;			/* 0 means this is a normal widget.  1 means
d62 1
a62 1
    GC	gc;
a65 1

d67 15
a81 15
    TkButton                 info;       /* generic button info */
    int                      id;
    int                      usingControl;
    int                      useTkText;
    int                      flags;     /* initialisation status */
    MacControlParams         params;
    WindowRef                windowRef;
    RGBColor                 userPaneBackground;
    ControlRef               userPane;  /* Carbon control */
    ControlRef               control;   /* Carbon control */
    Str255                   controlTitle;
    ControlFontStyleRec      fontStyle;
    /* 
     * the following are used to store the image content for
     * beveled buttons - i.e. buttons with images.
d83 2
a84 1
    CCTabHandle              tabHandle;
d86 1
a86 2
    OpenCPicParams           picParams;
    Pixmap                   picPixmap;
d94 4
a97 4
static OSErr SetUserPaneDrawProc(ControlRef control,
        ControlUserPaneDrawProcPtr upp);
static OSErr SetUserPaneSetUpSpecialBackgroundProc(ControlRef control,
        ControlUserPaneBackgroundProcPtr upp);
d100 1
a100 1
        ControlBackgroundPtr info);
d102 9
a110 9
static void ButtonEventProc _ANSI_ARGS_(( ClientData clientData, XEvent *eventPtr));
static int UpdateControlColors _ANSI_ARGS_((MacButton *mbPtr ));
static void TkMacOSXComputeControlParams _ANSI_ARGS_((TkButton * butPtr, MacControlParams * paramsPtr));
static int TkMacOSXComputeDrawParams _ANSI_ARGS_((TkButton * butPtr, DrawParams * dpPtr));
static void TkMacOSXDrawControl _ANSI_ARGS_((MacButton *butPtr,
        GWorldPtr destPort, GC gc, Pixmap pixmap));
static void SetupBevelButton _ANSI_ARGS_((MacButton *butPtr,
        ControlRef controlHandle, 
        GWorldPtr destPort, GC gc, Pixmap pixmap));
d116 3
a118 3
Tk_ClassProcs tkpButtonProcs = { 
    sizeof(Tk_ClassProcs),        /* size */
    TkButtonWorldChanged,        /* worldChangedProc */
d130 1
a130 1
 *        Allocate a new TkButton structure.
d133 1
a133 1
 *        Returns a newly allocated TkButton structure.
d136 1
a136 1
 *        Registers an event handler for the widget.
d145 2
a146 2
    MacButton *macButtonPtr;
    macButtonPtr = (MacButton *) ckalloc(sizeof(MacButton));
d148 1
a148 1
            ButtonEventProc, (ClientData) macButtonPtr);
d152 1
a152 3
    macButtonPtr->userPaneBackground.red = 0;
    macButtonPtr->userPaneBackground.green = 0;
    macButtonPtr->userPaneBackground.blue = ~0;
d167 1
d176 2
a177 2
 *        This procedure is invoked to display a button widget.  It is
 *        normally invoked as an idle handler.
d180 1
a180 1
 *        None.
d183 2
a184 2
 *        Commands are output to X to display the button in its
 *        current mode.  The REDRAW_PENDING flag is cleared.
d191 1
a191 1
    ClientData clientData)        /* Information about widget. */
d194 4
a197 7
    TkButton  *butPtr       = (TkButton *) clientData;
    Tk_Window tkwin         = butPtr->tkwin;
    int width, height, fullWidth, fullHeight;
    int textXOffset, textYOffset;
    int haveImage = 0, haveText = 0;
    GWorldPtr destPort;
    int borderWidth;
d199 3
a201 2
    int wasUsingControl;
    int imageWidth = 0, imageHeight = 0;
d205 1
a205 1
    DrawParams drawParams, * dpPtr = &drawParams;
d209 1
a209 1
        return;
d216 6
a221 6
        macButtonPtr->usingControl = 1;
        if (butPtr->type == TYPE_BUTTON) {
            macButtonPtr->useTkText = 0;
        } else {
            macButtonPtr->useTkText = 1;
        }
d223 2
a224 2
        macButtonPtr->usingControl = 0;
        macButtonPtr->useTkText = 1;
d226 4
a229 4
   
    /* 
     * set up clipping region.  Make sure the we are using the port
     * for this button, or we will set the wrong window's clip. 
d231 1
a231 1
    
d233 1
a233 1
    SetGWorld(destPort, NULL);
a235 1

d237 1
a237 1
     * See the comment in UpdateControlColors as to why we use the 
d242 7
a248 7
        if (butPtr->type == TYPE_BUTTON) {
            Tk_Fill3DRectangle(tkwin, pixmap, butPtr->highlightBorder, 0, 0,
                Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
        } else {
            Tk_Fill3DRectangle(tkwin, pixmap, butPtr->normalBorder, 0, 0,
                Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
        }
d253 2
a254 2
     * if it doesn't already exist.  Then configure the Macintosh control from
     * the Tk info.  Finally, we call Draw1Control to draw to the screen.
d258 7
a264 9
        borderWidth = 0;
        TkMacOSXDrawControl(macButtonPtr, destPort, dpPtr->gc, pixmap);
    } else {
       if (wasUsingControl && macButtonPtr->userPane) {
           DisposeControl(macButtonPtr->userPane);
           macButtonPtr->userPane = NULL;
           macButtonPtr->control  = NULL;
           macButtonPtr->flags = 0;
       }
d268 1
a268 1
        borderWidth = butPtr->borderWidth;
d272 1
a272 1
     * Display image or bitmap or text for button.  This has
d278 168
a445 175
        /* Empty Body */
    } else {
        if (butPtr->image != None) {
            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) {
            int x;
            int y;
            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;
            
            x += dpPtr->offset;
            y += dpPtr->offset;
            if (dpPtr->relief == TK_RELIEF_RAISED) {
                x -= dpPtr->offset;
                y -= dpPtr->offset;
            } else if (dpPtr->relief == TK_RELIEF_SUNKEN) {
                x += dpPtr->offset;
                y += dpPtr->offset;
            }
	    imageXOffset += x;
	    imageYOffset += y;
            if (butPtr->image != NULL) {
                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, dpPtr->gc,
			imageXOffset, imageYOffset);
                XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, dpPtr->gc,
                        0, 0, (unsigned int) width, (unsigned int) height,
			imageXOffset, imageYOffset, 1);
                XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0);
            }

            if (macButtonPtr->useTkText) {
                Tk_DrawTextLayout(butPtr->display, pixmap, 
                        dpPtr->gc, butPtr->textLayout,
                        x + textXOffset, y + textYOffset, 0, -1);
                Tk_UnderlineTextLayout(butPtr->display, pixmap, dpPtr->gc,
                        butPtr->textLayout, 
                        x + textXOffset, y + textYOffset,
                        butPtr->underline);
            }
            y += fullHeight/2;
        } else {
            if (haveImage) {
                int x = 0;
                int y;

                TkComputeAnchor(butPtr->anchor, tkwin, 0, 0,
                        butPtr->indicatorSpace + width, height, &x, &y);
                x += butPtr->indicatorSpace;

                x += dpPtr->offset;
                y += dpPtr->offset;
                if (dpPtr->relief == TK_RELIEF_RAISED) {
                    x -= dpPtr->offset;
                    y -= dpPtr->offset;
                } else if (dpPtr->relief == TK_RELIEF_SUNKEN) {
                    x += dpPtr->offset;
                    y += dpPtr->offset;
                }
		imageXOffset += x;
		imageYOffset += y;
                if (butPtr->image != NULL) {
                    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, dpPtr->gc, x, y);
                    XCopyPlane(butPtr->display, butPtr->bitmap, 
                            pixmap, dpPtr->gc,
                            0, 0, (unsigned int) width,
                            (unsigned int) height, x, y, 1);
                    XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0);
                }
                y += height/2;
            } else if (macButtonPtr->useTkText) {
                int x = 0;
                int y;
                TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX,
                        butPtr->padY,
                        butPtr->indicatorSpace + butPtr->textWidth,
                        butPtr->textHeight, &x, &y);                
                x += butPtr->indicatorSpace;                
                Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc,
                        butPtr->textLayout, x, y, 0, -1);
            }
        }
d450 1
a450 1
     * foreground color, generate the stippled effect.  If the widget
d455 1
d457 3
a459 3
        if ((butPtr->state == STATE_DISABLED)
                && ((butPtr->disabledFg == NULL) || (butPtr->image != NULL))) {
            if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn
d461 1
a461 1
                XSetForeground(butPtr->display, butPtr->stippleGC,
d463 2
a464 1
            }
d469 1
d479 1
a479 1
            if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn
d484 9
a492 1
        }
d494 7
a500 11
        /*
         * Draw the border and traversal highlight last.  This way, if the
         * button's contents overflow they'll be covered up by the border.
         */
         
        if (dpPtr->relief != TK_RELIEF_FLAT) {
            int inset = butPtr->highlightWidth;
            Tk_Draw3DRectangle(tkwin, pixmap, dpPtr->border, inset, inset,
                Tk_Width(tkwin) - 2*inset, Tk_Height(tkwin) - 2*inset,
                butPtr->borderWidth, dpPtr->relief);
        }
d509 3
a511 3
 *        After changes in a button's text or bitmap, this procedure
 *        recomputes the button's geometry and passes this information
 *        along to the geometry manager for the window.
d514 1
a514 1
 *        None.
d517 1
a517 1
 *        The button's window may change size.
d524 1
a524 1
    TkButton *butPtr)        /* Button whose geometry may have changed. */
d527 1
a527 2
    int xInset, yInset;
    int txtWidth, txtHeight;
d534 1
a534 1
     
a540 1
     
d543 2
a544 2
        Tk_SizeOfImage(butPtr->image, &width, &height);
        haveImage = 1;
d546 2
a547 2
        Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
        haveImage = 1;
d551 10
a560 10
        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);
d571 36
a606 47
        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;
            }
        }
d608 8
a615 2
        width += 2 * butPtr->padX;
        height += 2 * butPtr->padY;
d617 17
d635 16
a650 33
        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;
            }
        }
d656 1
a656 1
     
d658 1
a658 1
        butPtr->highlightWidth = 0;
d660 1
a660 1
    
d662 2
a663 2
     * The width and height calculation for Appearance buttons with images & 
     * non-Appearance buttons with images is different.         In the latter case, 
d665 1
a665 1
     * 3-D border over the image.  In the former, we add it to the height,
d669 1
a669 1
     * if any, and for the border and padding, plus if this is an image two 
d675 1
a675 1
     * button.        The actual width of the default ring is one less than the
d677 1
a677 1
     * Appearance buttons with images do not have a highlight ring, because the 
d682 2
a683 2
        width += 2*butPtr->padX;
        height += 2*butPtr->padY;
d685 1
a685 1
    
d687 14
a700 35
        if ((butPtr->image == None) && (butPtr->bitmap == None)) {
            butPtr->inset = 0;
            if (butPtr->defaultState != STATE_DISABLED) {
                butPtr->inset += butPtr->highlightWidth;
            }
        } else  {
            butPtr->inset = 0;
            width += (2 * butPtr->borderWidth + 4);
            height += (2 * butPtr->borderWidth + 4);
        }
    } else if ((butPtr->type != TYPE_LABEL)) {
        if (butPtr->indicatorOn) {
            butPtr->inset = 0;
        } else {
            /*
             * Under Appearance, the Checkbutton or radiobutton with an image
             * is represented by a BevelButton with the Sticky defProc...  
             * So we must set its height in the same way as the Button 
             * with an image or bitmap.
             */
             
            if ( (butPtr->image != None) || (butPtr->bitmap != None)) {
                int border;
                butPtr->inset = 0;
                if ( butPtr->borderWidth <= 2 ) {
                    border = 6;
                }  else {
                    border = 2 * butPtr->borderWidth + 2;
                }               
                width += border;
                height += border;
            } else {
                butPtr->inset = butPtr->borderWidth;
            }        
        }        
d702 21
a722 1
        butPtr->inset = butPtr->borderWidth;
d726 2
a727 2
        xInset = butPtr->indicatorSpace + DEF_INSET_LEFT + DEF_INSET_RIGHT;
        yInset = DEF_INSET_TOP + DEF_INSET_BOTTOM;
d729 2
a730 2
        xInset = butPtr->indicatorSpace+butPtr->inset*2;
        yInset = butPtr->inset*2;
d741 1
a741 1
 *        Free data structures associated with the button control.
d744 1
a744 1
 *        None.
d747 1
a747 1
 *        Restores the default control state.
d756 2
a757 1
    MacButton *mbPtr = ( MacButton *) butPtr; /* Mac button. */
d759 2
a760 2
        DisposeControl(mbPtr->userPane);
        mbPtr->userPane = NULL;
d769 1
a769 1
 *        This procedure initialises a Carbon control
d772 1
a772 1
 *        0 on success, 1 on failure.
d775 5
a779 5
 *        A background pane control and the control itself is created
 *      The contol is embedded in the background control
 *      The background control is embedded in the root control
 *      of the containing window
 *      The creation parameters for the control are also computed
d785 7
a791 8
TkMacOSXInitControl (
    MacButton *mbPtr,                /* Mac button. */
    GWorldPtr  destPort,
    GC         gc,
    Pixmap     pixmap,
    Rect      *paneRect,
    Rect      *cntrRect
)
d793 1
a793 2
    OSErr      status;
    TkButton * butPtr = ( TkButton * )mbPtr;
d795 3
a797 6
    SInt16     procID;
    Boolean    initiallyVisible;
    SInt16     initialValue;
    SInt16     minValue;
    SInt16     maxValue;
    SInt32     controlReference;
d800 2
a801 2
    mbPtr->windowRef
            = GetWindowFromPort(TkMacOSXGetDrawablePort(Tk_WindowId(butPtr->tkwin)));
d803 2
a804 2
    /* 
     * Set up the user pane
d808 4
a811 4
    initialValue     = kControlSupportsEmbedding|kControlHasSpecialBackground;
    minValue         = 0;
    maxValue         = 1;
    procID           = kControlUserPaneProc;
d813 4
a816 9
    mbPtr->userPane  = NewControl(mbPtr->windowRef,
        paneRect, "\p",
        initiallyVisible,
        initialValue,
        minValue,
        maxValue,
        procID,
        controlReference );
        
d818 5
a822 11
#ifdef TK_MAC_DEBUG
        fprintf(stderr,"Failed to create user pane control\n");
#endif
        return 1;
    }
    
    if ((status = EmbedControl(mbPtr->userPane,rootControl)) != noErr) {
#ifdef TK_MAC_DEBUG
        fprintf(stderr,"Failed to embed user pane control %d\n", status);
#endif
        return 1;
d824 1
a824 1
    
d826 1
a826 1
        UserPaneBackgroundProc);
d830 5
a834 9
    mbPtr->control = NewControl(mbPtr->windowRef,
        cntrRect, "\p",
        initiallyVisible,
        mbPtr->params.initialValue,
        mbPtr->params.minValue,
        mbPtr->params.maxValue,
        mbPtr->params.procID,
        controlReference );
        
d836 5
a840 11
#ifdef TK_MAC_DEBUG
        fprintf(stderr,"failed to create control of type %d\n",procID);
#endif
        return 1;
    }
    
    if (EmbedControl(mbPtr->control,mbPtr->userPane) != noErr ) {
#ifdef TK_MAC_DEBUG
        fprintf(stderr,"failed to embed control of type %d\n",procID);
#endif
        return 1;
d842 1
a842 1
    
d846 1
a846 1

d852 3
a854 3
 *        This function draws the tk button using Mac controls
 *        In addition, this code may apply custom colors passed 
 *        in the TkButton.
d857 1
a857 1
 *        None.
d860 1
a860 2
 *      The control is created, or reinitialised as needed
 *
d867 6
a872 7
    MacButton *mbPtr,    /* Mac button. */
    GWorldPtr destPort,  /* Off screen GWorld. */
    GC gc,               /* The GC we are drawing into - needed for
                          * the bevel button */
    Pixmap pixmap)       /* The pixmap we are drawing into - needed
                          * for the bevel button */
                
d874 9
a882 11
    TkButton * butPtr = ( TkButton *)mbPtr;
    int        err;
    TkWindow * winPtr;
    Rect       paneRect;
    Rect       cntrRect;

    winPtr = (TkWindow *)butPtr->tkwin;
   
    paneRect.left   = winPtr->privatePtr->xOff;
    paneRect.top    = winPtr->privatePtr->yOff;
    paneRect.right  = paneRect.left + Tk_Width(butPtr->tkwin);
d888 3
a890 3
    cntrRect.left   += butPtr->inset;
    cntrRect.top    += butPtr->inset;
    cntrRect.right  -= butPtr->inset;
d893 3
a895 3
    cntrRect.left   += DEF_INSET_LEFT;
    cntrRect.top    += DEF_INSET_TOP;
    cntrRect.right  -= DEF_INSET_RIGHT;
d898 3
a900 3
    /* 
     * The control has been previously initialised
     * It may need to be re-initialised 
d902 1
a902 1
     
d904 16
a919 15
        MacControlParams params;
        TkMacOSXComputeControlParams(butPtr, &params);
        if (bcmp(&params, &mbPtr->params, sizeof(params))) {
            /* 
             * the type of control has changed
             * Clean it up and clear the flag 
             */
             
            if (mbPtr->userPane) {
                DisposeControl(mbPtr->userPane);
                mbPtr->userPane = NULL;
                mbPtr->control = NULL;
            }
            mbPtr->flags = 0;
        }
d922 4
a925 4
        if (TkMacOSXInitControl(mbPtr, destPort, gc, 
                pixmap, &paneRect, &cntrRect) ) {
            return;
        }
d931 31
a961 36
        Str255              controlTitle;
        ControlFontStyleRec fontStyle;
        Tk_Font    font;
        int        len;
        
        if (((mbPtr->info.image == NULL) && (mbPtr->info.bitmap == None))
               || (mbPtr->info.compound != COMPOUND_NONE)) {
            len = TkFontGetFirstTextLayout(butPtr->textLayout, 
                    &font, (char*) controlTitle);
            controlTitle[len] = 0;
        } else {
            len = 0;
            controlTitle[0] = 0;
        }
        if (bcmp(mbPtr->controlTitle, controlTitle, len+1)) {
            CFStringRef cf;    	    
            cf = CFStringCreateWithCString(NULL,
                  (char*) controlTitle, kCFStringEncodingUTF8);
            if (cf != NULL) {
            SetControlTitleWithCFString(mbPtr->control, cf);
            CFRelease(cf);
            }
            bcopy(controlTitle, mbPtr->controlTitle, len+1);
        }
        if (len) {
            TkMacOSXInitControlFontStyle(font, &fontStyle);
            if (bcmp(&mbPtr->fontStyle, &fontStyle, sizeof(fontStyle)) ) {
                if (SetControlFontStyle(mbPtr->control, &fontStyle) != noErr) {
#ifdef TK_MAC_DEBUG
                    fprintf(stderr,"SetControlFontStyle failed\n");
#endif
                }
                bcopy(&fontStyle, &mbPtr->fontStyle, 
                        sizeof(fontStyle));
            }
        }
d964 5
a968 3
        /* Initialiase the image/button parameters */
        SetupBevelButton(mbPtr, mbPtr->control, destPort, 
                      gc, pixmap);
d972 1
a972 1
     SetControlValue(mbPtr->control, 1);
d974 1
a974 1
     SetControlValue(mbPtr->control, 2);
d976 1
a976 1
     SetControlValue(mbPtr->control, 0);
d986 1
d995 1
a995 1
			HiliteControl(mbPtr->control,  kControlButtonPart);
d1010 1
a1010 1
        Boolean isDefault;
d1012 13
a1024 15
        if (butPtr->defaultState == STATE_ACTIVE) {
            isDefault = true;
        } else {
            isDefault = false;
        }
        if ((err=SetControlData(mbPtr->control, kControlNoPart, 
                kControlPushButtonDefaultTag,
                sizeof(isDefault), (Ptr) &isDefault)) != noErr) {
        }
    }

    if (mbPtr->flags&2) {
        ShowControl(mbPtr->userPane);
        ShowControl(mbPtr->control);
        mbPtr->flags ^= 2;
d1026 2
a1027 2
        SetControlVisibility(mbPtr->control, true, true);
        Draw1Control(mbPtr->userPane);
d1031 1
a1031 1
        KillPicture(mbPtr->bevelButtonContent.u.picture);
d1040 2
a1041 2
 *        Sets up the Bevel Button with image by copying the
 *        source image onto the PicHandle for the button.
d1044 1
a1044 1
 *        None
d1047 1
a1047 1
 *        The image or bitmap for the button is copied over to a picture.
d1051 1
d1054 7
a1060 8
    MacButton *mbPtr,                /* Mac button. */
    ControlRef controlHandle,         /* The control to set this picture to */
    GWorldPtr destPort,                /* Off screen GWorld. */
    GC gc,                        /* The GC we are drawing into - needed for
                                 * the bevel button */
    Pixmap pixmap                /* The pixmap we are drawing into - needed
                                   for the bevel button */
    )
d1062 1
a1062 2
    int       err;
    TkButton *butPtr = ( TkButton *)mbPtr;
d1065 4
a1068 2
    
    SetPort(destPort);
d1071 1
a1071 2
        Tk_SizeOfImage(butPtr->image, 
                &width, &height);
d1073 1
a1073 2
        Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, 
                &width, &height);
d1075 1
a1075 1
            
d1077 1
a1077 1
        width = butPtr->width;
d1080 1
a1080 1
        height = butPtr->height;
d1086 2
a1087 2
    /* 
     * Set the flag to circumvent clipping and bounds problems with OS 10.0.4 
d1089 4
a1092 6
     
    if (!(mbPtr->bevelButtonContent.u.picture 
            = OpenCPicture(&mbPtr->picParams)) ) {
#ifdef TK_MAC_DEBUG
        fprintf(stderr,"OpenCPicture failed\n");
#endif
d1095 1
a1095 1
    
d1098 1
a1098 1
     * which does not get recorded in the picture.  So the bitmap code
d1101 6
a1106 7
     
    if ((butPtr->selectImage != NULL) && (butPtr->flags & SELECTED)) {
        Tk_RedrawImage(butPtr->selectImage, 0, 0, width, height,
                pixmap, 0, 0);
    } else if ((butPtr->tristateImage != NULL) && (butPtr->flags & TRISTATED)) {
        Tk_RedrawImage(butPtr->tristateImage, 0, 0, width, height,
                pixmap, 0, 0);
d1108 5
a1112 6
        Tk_RedrawImage(butPtr->image, 0, 0, width, 
                height, pixmap, 0, 0);
    } else {                        
        XSetClipOrigin(butPtr->display, gc, 0, 0);
        XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, gc, 0, 0,
                (unsigned int) width, (unsigned int) height, 0, 0, 1);
d1114 1
a1114 1
    
d1117 5
a1121 11
    
    if ((err = SetControlData(controlHandle, kControlButtonPart,
            kControlBevelButtonContentTag,
            sizeof(ControlButtonContentInfo),
            (char *) &mbPtr->bevelButtonContent)) != noErr) {
#ifdef TK_MAC_DEBUG
        fprintf(stderr,
                "SetControlData BevelButtonContent failed, %d\n", err );
#endif
    }
            
d1123 5
a1127 5
        theAlignment = kControlBevelButtonAlignTop;
    } else if (butPtr->anchor == TK_ANCHOR_NE) { 
        theAlignment = kControlBevelButtonAlignTopRight;
    } else if (butPtr->anchor == TK_ANCHOR_E) { 
        theAlignment = kControlBevelButtonAlignRight;
d1129 1
a1129 1
        theAlignment = kControlBevelButtonAlignBottomRight;
d1131 1
a1131 1
        theAlignment = kControlBevelButtonAlignBottom;
d1133 1
a1133 1
        theAlignment = kControlBevelButtonAlignBottomLeft;
d1135 1
a1135 1
        theAlignment = kControlBevelButtonAlignLeft;
d1137 1
a1137 1
        theAlignment = kControlBevelButtonAlignTopLeft;
d1139 1
a1139 1
        theAlignment = kControlBevelButtonAlignCenter;
d1142 3
a1144 9
    if ((err = SetControlData(controlHandle, kControlButtonPart,
            kControlBevelButtonGraphicAlignTag,
            sizeof(ControlButtonGraphicAlignment),
            (char *) &theAlignment)) != noErr) {
#ifdef TK_MAC_DEBUG
        fprintf(stderr,
                "SetControlData BevelButtonGraphicAlign failed, %d\n", err );
#endif
    }
d1147 18
a1164 20
        ControlButtonTextPlacement thePlacement = \
                kControlBevelButtonPlaceNormally;
        if (butPtr->compound == COMPOUND_TOP) {
            thePlacement = kControlBevelButtonPlaceBelowGraphic;
        } else if (butPtr->compound == COMPOUND_BOTTOM) {
            thePlacement = kControlBevelButtonPlaceAboveGraphic;
        } else if (butPtr->compound == COMPOUND_LEFT) {
            thePlacement = kControlBevelButtonPlaceToRightOfGraphic;
        } else if (butPtr->compound == COMPOUND_RIGHT) {
            thePlacement = kControlBevelButtonPlaceToLeftOfGraphic;
        }
        if ((err = SetControlData(controlHandle, kControlButtonPart,
                kControlBevelButtonTextPlaceTag,
                sizeof(ControlButtonTextPlacement),
                (char *) &thePlacement)) != noErr) {
#ifdef TK_MAC_DEBUG
            fprintf(stderr,
                    "SetControlData BevelButtonTextPlace failed, %d\n", err );
#endif
        }
d1173 3
a1175 3
 *        Utility function to add a UserPaneDrawProc
 *        to a userPane control.        From MoreControls code
 *        from Apple DTS.
d1178 1
a1178 1
 *        MacOS system error.
d1181 1
a1181 1
 *        The user pane gets a new UserPaneDrawProc.
d1185 3
a1187 1
OSErr SetUserPaneDrawProc (
d1192 5
a1196 5
    myControlUserPaneDrawUPP = NewControlUserPaneDrawUPP(upp);        
    return SetControlData (control, 
            kControlNoPart, kControlUserPaneDrawProcTag, 
            sizeof(myControlUserPaneDrawUPP), 
            (Ptr) &myControlUserPaneDrawUPP);
d1204 2
a1205 2
 *        Utility function to add a UserPaneBackgroundProc
 *        to a userPane control
d1208 1
a1208 1
 *        MacOS system error.
d1211 1
a1211 1
 *        The user pane gets a new UserPaneBackgroundProc.
d1215 2
a1216 1
OSErr
d1218 1
a1218 1
    ControlRef control, 
d1222 1
d1224 4
a1227 4
    return SetControlData (control, kControlNoPart, 
            kControlUserPaneBackgroundProcTag, 
            sizeof(myControlUserPaneBackgroundUPP), 
            (Ptr) &myControlUserPaneBackgroundUPP);
d1235 2
a1236 2
 *        This function draws the background of the user pane that will 
 *        lie under checkboxes and radiobuttons.
d1239 1
a1239 1
 *        None.
d1242 1
a1242 1
 *        The user pane gets updated to the current color.
d1246 1
d1252 1
d1254 1
a1254 2
    MacButton * mbPtr;
    mbPtr = ( MacButton *)GetControlReference(control);
d1256 2
a1257 2
    RGBBackColor (&mbPtr->userPaneBackground);
    EraseRect (&contrlRect);
d1265 2
a1266 2
 *        This function sets up the background of the user pane that will 
 *        lie under checkboxes and radiobuttons.
d1269 1
a1269 1
 *        None.
d1272 1
a1272 1
 *        The user pane background gets set to the current color.
d1282 2
a1283 2
    MacButton * mbPtr;
    mbPtr = ( MacButton *)GetControlReference(control);
d1285 1
a1285 1
        RGBBackColor (&mbPtr->userPaneBackground);
d1294 4
a1297 4
 *        This function will review the colors used to display
 *        a Macintosh button.  If any non-standard colors are
 *        used we create a custom palette for the button, populate
 *        with the colors for the button and install the palette.
d1299 2
a1300 2
 *        Under Appearance, we just set the pointer that will be
 *        used by the UserPaneDrawProc.
d1303 1
a1303 1
 *        None.
d1306 1
a1306 1
 *        The Macintosh control may get a custom palette installed.
d1312 2
a1313 1
UpdateControlColors(MacButton * mbPtr)
d1316 2
a1317 2
    TkButton * butPtr = ( TkButton * )mbPtr;
    
d1320 3
a1322 3
     * button itself.  However, the color we are setting is the color
     * of the containing userPane.  This will be the color that peeks 
     * around the rounded corners of the button.  
d1328 1
a1328 1
      
d1330 1
a1330 1
        xcolor = Tk_3DBorderColor(butPtr->highlightBorder);
d1332 1
a1332 1
        xcolor = Tk_3DBorderColor(butPtr->normalBorder);
d1334 2
a1335 2
    TkSetMacColor(xcolor->pixel, &mbPtr->userPaneBackground);
    
d1337 2
a1338 1
}
d1344 2
a1345 2
 *        This procedure is invoked by the Tk dispatcher for various
 *        events on buttons.
d1348 1
a1348 1
 *        None.
d1351 1
a1351 1
 *      When it gets exposed, it is redisplayed.
d1358 2
a1359 2
    ClientData clientData,        /* Information about window. */
    XEvent *eventPtr)                /* Information about event. */
d1362 1
d1364 8
a1371 9
            || eventPtr->type == DeactivateNotify) {
        if ((buttonPtr->tkwin == NULL) 
                || (!Tk_IsMapped(buttonPtr->tkwin))) {
            return;
        }
        if ((buttonPtr->flags & REDRAW_PENDING) == 0) {
            Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) buttonPtr);
            buttonPtr->flags |= REDRAW_PENDING;
        }
d1380 3
a1382 3
 *        This procedure computes the various parameters used
 *        when creating a Carbon control (NewControl)
 *      These are determined by the various tk button parameters
d1385 1
a1385 1
 *        None.
d1388 1
a1388 1
 *        Sets the control initialisation parameters
d1394 3
a1396 1
TkMacOSXComputeControlParams(TkButton * butPtr, MacControlParams * paramsPtr )
d1399 3
a1401 3
    
    /* 
     * Determine ProcID based on button type and dimensions 
d1403 1
a1403 1
     
d1405 65
a1469 68
        case TYPE_BUTTON:
            if ((butPtr->image == None) && (butPtr->bitmap == None)) {
                paramsPtr->initialValue = 1;
                paramsPtr->minValue = 0;
                paramsPtr->maxValue = 1;
                paramsPtr->procID = kControlPushButtonProc;
            } else {
                paramsPtr->initialValue = 0;
                paramsPtr->minValue = kControlBehaviorOffsetContents
                    | kControlContentPictHandle;
                paramsPtr->maxValue = 1;
                if (butPtr->borderWidth <= 2) {
                    paramsPtr->procID = kControlBevelButtonSmallBevelProc;
                } else if (butPtr->borderWidth == 3) {
                    paramsPtr->procID = kControlBevelButtonNormalBevelProc;
                } else {
                    paramsPtr->procID = kControlBevelButtonLargeBevelProc;
                }
                paramsPtr->isBevel = 1;                
            }
            break;
        case TYPE_RADIO_BUTTON:
            if (((butPtr->image == None) && (butPtr->bitmap == None))
                || (butPtr->indicatorOn)) {
                paramsPtr->initialValue = 1;
                paramsPtr->minValue = 0;
                paramsPtr->maxValue = 2;
                paramsPtr->procID = kControlRadioButtonProc;
            } else {
                paramsPtr->initialValue = 0;
                paramsPtr->minValue = kControlBehaviorOffsetContents|
                    kControlBehaviorSticky|
                    kControlContentPictHandle;
                paramsPtr->maxValue = 2;
                if (butPtr->borderWidth <= 2) {
                    paramsPtr->procID = kControlBevelButtonSmallBevelProc;
                } else if (butPtr->borderWidth == 3) {
                    paramsPtr->procID = kControlBevelButtonNormalBevelProc;
                } else {
                    paramsPtr->procID = kControlBevelButtonLargeBevelProc;
                }
                paramsPtr->isBevel = 1;                
            }
            break;
        case TYPE_CHECK_BUTTON:
            if (((butPtr->image == None) 
                    && (butPtr->bitmap == None))
                    || (butPtr->indicatorOn)) {
                paramsPtr->initialValue = 1;
                paramsPtr->minValue = 0;
                paramsPtr->maxValue = 2;
                paramsPtr->procID = kControlCheckBoxProc;
            } else {
                paramsPtr->initialValue = 0;
                paramsPtr->minValue = kControlBehaviorOffsetContents
                    | kControlBehaviorSticky
                    | kControlContentPictHandle;
                paramsPtr->maxValue = 2;
                if (butPtr->borderWidth <= 2) {
                    paramsPtr->procID = kControlBevelButtonSmallBevelProc;
                } else if (butPtr->borderWidth == 3) {
                    paramsPtr->procID = kControlBevelButtonNormalBevelProc;
                } else {
                    paramsPtr->procID = kControlBevelButtonLargeBevelProc;
                }
                paramsPtr->isBevel = 1;                
            }   
            break;
d1471 2
a1472 1
}
d1478 3
a1480 3
 *        This procedure computes the various parameters used
 *        when drawing a button
 *      These are determined by the various tk button parameters
d1483 1
a1483 1
 *        1 if control will be used, 0 otherwise.
d1486 1
a1486 1
 *        Sets the button draw parameters
d1492 3
a1494 1
TkMacOSXComputeDrawParams(TkButton * butPtr, DrawParams * dpPtr)
d1496 4
a1499 4
    dpPtr->hasImageOrBitmap = ((butPtr->image != NULL) 
            || (butPtr->bitmap != None));
    dpPtr->offset = (butPtr->type == TYPE_BUTTON) 
            && dpPtr->hasImageOrBitmap;
d1501 5
a1505 7
    if ((butPtr->state == STATE_DISABLED) 
            && (butPtr->disabledFg != NULL)) {
        dpPtr->gc = butPtr->disabledGC;
    } else if ((butPtr->type == TYPE_BUTTON)
            && (butPtr->state == STATE_ACTIVE)) {
        dpPtr->gc = butPtr->activeTextGC;
        dpPtr->border = butPtr->activeBorder;
d1507 1
a1507 1
        dpPtr->gc = butPtr->normalTextGC;
d1510 3
a1512 5
    if ((butPtr->flags & SELECTED) 
            && (butPtr->state != STATE_ACTIVE)
            && (butPtr->selectBorder != NULL) 
            && !butPtr->indicatorOn) {
       dpPtr->border = butPtr->selectBorder;
d1514 1
a1514 1
    
d1525 4
a1528 4
        if (!dpPtr->hasImageOrBitmap) {
            dpPtr->relief = (butPtr->flags & SELECTED) ? TK_RELIEF_SUNKEN
                : TK_RELIEF_RAISED;
        }
d1534 1
d1536 1
a1536 1
        dpPtr->drawType = DRAW_LABEL;
d1538 44
a1581 28
        if (!dpPtr->hasImageOrBitmap) {
            dpPtr->drawType = DRAW_CONTROL;
        } else if (butPtr->image != None) {
            dpPtr->drawType = DRAW_BEVEL;
        } else {
            /*
             * TO DO - The current way the we draw bitmaps (XCopyPlane)
             * uses CopyDeepMask in this one case.  The Picture recording 
             * does not record this call, and so we can't use the
             * Appearance bevel button here.  The only case that would
             * exercise this is if you use a bitmap, with
             * -data & -mask specified.         We should probably draw the 
             * appearance button and overprint the image in this case.
             * This just punts and draws the old-style, ugly, button.
             */
             
            if (dpPtr->gc->clip_mask == 0) {
                dpPtr->drawType = DRAW_BEVEL;
            } else {
                TkpClipMask *clipPtr = (TkpClipMask*) dpPtr->gc->clip_mask;
                if ((clipPtr->type == TKP_CLIP_PIXMAP) &&
                        (clipPtr->value.pixmap != butPtr->bitmap)) {
                    dpPtr->drawType = DRAW_CUSTOM;
                } else {
                    dpPtr->drawType = DRAW_BEVEL;
                }
            }
        }
d1583 1
a1583 17
        if (butPtr->indicatorOn) {
            dpPtr->drawType = DRAW_CONTROL;
        } else if (dpPtr->hasImageOrBitmap) {
            if (dpPtr->gc->clip_mask == 0) {
                dpPtr->drawType = DRAW_BEVEL;
            } else {
                TkpClipMask *clipPtr = (TkpClipMask*) dpPtr->gc->clip_mask;
                if ((clipPtr->type == TKP_CLIP_PIXMAP) &&
                        (clipPtr->value.pixmap != butPtr->bitmap)) {
                    dpPtr->drawType = DRAW_CUSTOM;
                } else {
                    dpPtr->drawType = DRAW_BEVEL;
                }
            }
        } else {
            dpPtr->drawType = DRAW_CUSTOM;
        }
d1587 1
a1587 1
        return 1;
d1589 1
a1589 1
        return 0;
@


1.21
log
@Reduce the #ifdef count a lot by adding debug-print macros
@
text
@d1 1
a1 1
/*
d4 2
a5 2
 *	This file implements the Macintosh specific portion of the button
 *	widgets.
d10 2
a11 2
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
a25 1

d40 1
a40 1
/*
d49 1
a49 1
    int isBevel;
d56 5
a60 5
    int offset;			/* 0 means this is a normal widget. 1 means it
				 * is an image button, so we offset the image
				 * to make the button appear to move up and
				 * down as the relief changes. */
    GC gc;
d64 1
d66 15
a80 15
    TkButton info;		/* Generic button info */
    int id;
    int usingControl;
    int useTkText;
    int flags;			/* Initialisation status */
    MacControlParams params;
    WindowRef windowRef;
    RGBColor userPaneBackground;
    ControlRef userPane;	/* Carbon control */
    ControlRef control;		/* Carbon control */
    Str255 controlTitle;
    ControlFontStyleRec fontStyle;
    /*
     * The following are used to store the image content for beveled buttons -
     * i.e. buttons with images.
d82 1
a82 1
    CCTabHandle tabHandle;
d84 2
a85 2
    OpenCPicParams picParams;
    Pixmap picPixmap;
d92 18
a109 21
static OSErr		SetUserPaneDrawProc(ControlRef control,
			    ControlUserPaneDrawProcPtr upp);
static OSErr		SetUserPaneSetUpSpecialBackgroundProc(
			    ControlRef control,
			    ControlUserPaneBackgroundProcPtr upp);
static void		UserPaneDraw(ControlRef control, ControlPartCode cpc);
static void		UserPaneBackgroundProc(ControlHandle,
			    ControlBackgroundPtr info);

static void		ButtonEventProc(ClientData clientData,
			    XEvent *eventPtr);
static int		UpdateControlColors(MacButton *mbPtr);
static void		TkMacOSXComputeControlParams(TkButton *butPtr,
			    MacControlParams *paramsPtr);
static int		TkMacOSXComputeDrawParams(TkButton *butPtr,
			    DrawParams *dpPtr);
static void		TkMacOSXDrawControl(MacButton *butPtr,
			    GWorldPtr destPort, GC gc, Pixmap pixmap);
static void		SetupBevelButton(MacButton *butPtr,
			    ControlRef controlHandle, GWorldPtr destPort,
			    GC gc, Pixmap pixmap);
d115 3
a117 3
Tk_ClassProcs tkpButtonProcs = {
    sizeof(Tk_ClassProcs),	/* size */
    TkButtonWorldChanged,	/* worldChangedProc */
d129 1
a129 1
 *	Allocate a new TkButton structure.
d132 1
a132 1
 *	Returns a newly allocated TkButton structure.
d135 1
a135 1
 *	Registers an event handler for the widget.
d144 2
a145 2
    MacButton *macButtonPtr = (MacButton *) ckalloc(sizeof(MacButton));

d147 1
a147 1
	    ButtonEventProc, (ClientData) macButtonPtr);
a167 1

d176 2
a177 2
 *	This procedure is invoked to display a button widget. It is normally
 *	invoked as an idle handler.
d180 1
a180 1
 *	None.
d183 2
a184 2
 *	Commands are output to X to display the button in its current mode.
 *	The REDRAW_PENDING flag is cleared.
d191 1
a191 1
    ClientData clientData)	/* Information about widget. */
d194 5
a198 2
    TkButton *butPtr = (TkButton *) clientData;
    Tk_Window tkwin = butPtr->tkwin;
d200 1
d202 6
a207 7
    int width, height, fullWidth, fullHeight, textXOffset, textYOffset;
    int borderWidth, wasUsingControl;
    int haveImage = 0, haveText = 0, imageWidth = 0, imageHeight = 0;
    int imageXOffset = 0, imageYOffset = 0;
				/* Image information that will be used to
				 * restrict disabled pixmap as well. */
    DrawParams drawParams, *dpPtr = &drawParams;
d211 1
a211 1
	return;
d218 6
a223 6
	macButtonPtr->usingControl = 1;
	if (butPtr->type == TYPE_BUTTON) {
	    macButtonPtr->useTkText = 0;
	} else {
	    macButtonPtr->useTkText = 1;
	}
d225 2
a226 2
	macButtonPtr->usingControl = 0;
	macButtonPtr->useTkText = 1;
d228 4
a231 4

    /*
     * Set up clipping region. Make sure the we are using the port for this
     * button, or we will set the wrong window's clip.
d233 1
a233 1

d238 1
d240 1
a240 1
     * See the comment in UpdateControlColors as to why we use the
d245 7
a251 7
	if (butPtr->type == TYPE_BUTTON) {
	    Tk_Fill3DRectangle(tkwin, pixmap, butPtr->highlightBorder, 0, 0,
		    Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
	} else {
	    Tk_Fill3DRectangle(tkwin, pixmap, butPtr->normalBorder, 0, 0,
		    Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
	}
d256 2
a257 2
     * if it doesn't already exist. Then configure the Macintosh control from
     * the Tk info. Finally, we call Draw1Control to draw to the screen.
d261 9
a269 7
	borderWidth = 0;
	TkMacOSXDrawControl(macButtonPtr, destPort, dpPtr->gc, pixmap);
    } else if (wasUsingControl && macButtonPtr->userPane) {
	DisposeControl(macButtonPtr->userPane);
	macButtonPtr->userPane = NULL;
	macButtonPtr->control = NULL;
	macButtonPtr->flags = 0;
d273 1
a273 1
	borderWidth = butPtr->borderWidth;
d277 3
a279 2
     * Display image or bitmap or text for button. This has already been done
     * under Appearance with the Bevel button types.
d283 104
a386 102
	goto applyStipple;
    }

    if (butPtr->image != None) {
	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) {
	int x, y;

	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;

	x += dpPtr->offset;
	y += dpPtr->offset;
	if (dpPtr->relief == TK_RELIEF_RAISED) {
	    x -= dpPtr->offset;
	    y -= dpPtr->offset;
	} else if (dpPtr->relief == TK_RELIEF_SUNKEN) {
	    x += dpPtr->offset;
	    y += dpPtr->offset;
	}
	imageXOffset += x;
	imageYOffset += y;
	if (butPtr->image != NULL) {
	    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,
d388 70
a457 65
	    }
	} else {
	    XSetClipOrigin(butPtr->display, dpPtr->gc, imageXOffset,
		    imageYOffset);
	    XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, dpPtr->gc,
		    0, 0, (unsigned int) width, (unsigned int) height,
		    imageXOffset, imageYOffset, 1);
	    XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0);
	}

	if (macButtonPtr->useTkText) {
	    Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc,
		    butPtr->textLayout, x + textXOffset, y + textYOffset,
		    0, -1);
	    Tk_UnderlineTextLayout(butPtr->display, pixmap, dpPtr->gc,
		    butPtr->textLayout, x + textXOffset, y + textYOffset,
		    butPtr->underline);
	}
	y += fullHeight/2;
    } else if (haveImage) {
	int x = 0, y;

	TkComputeAnchor(butPtr->anchor, tkwin, 0, 0,
		butPtr->indicatorSpace + width, height, &x, &y);
	x += butPtr->indicatorSpace;

	x += dpPtr->offset;
	y += dpPtr->offset;
	if (dpPtr->relief == TK_RELIEF_RAISED) {
	    x -= dpPtr->offset;
	    y -= dpPtr->offset;
	} else if (dpPtr->relief == TK_RELIEF_SUNKEN) {
	    x += dpPtr->offset;
	    y += dpPtr->offset;
	}
	imageXOffset += x;
	imageYOffset += y;
	if (butPtr->image != NULL) {
	    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, dpPtr->gc, x, y);
	    XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, dpPtr->gc,
		    0, 0, (unsigned) width, (unsigned) height, x, y, 1);
	    XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0);
	}
	y += height/2;
    } else if (macButtonPtr->useTkText) {
	int x = 0, y;

	TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY,
		butPtr->indicatorSpace + butPtr->textWidth,
		butPtr->textHeight, &x, &y);
	x += butPtr->indicatorSpace;
	Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc,
		butPtr->textLayout, x, y, 0, -1);
d462 3
a464 3
     * 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.
a466 1
  applyStipple:
d468 3
a470 3
	if ((butPtr->state == STATE_DISABLED)
		&& ((butPtr->disabledFg == NULL) || (butPtr->image != NULL))) {
	    if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn
d472 1
a472 1
		XSetForeground(butPtr->display, butPtr->stippleGC,
d474 1
a474 2
	    }

a478 1

d488 1
a488 1
	    if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn
d493 1
a493 6
	}

	/*
	 * Draw the border and traversal highlight last. This way, if the
	 * button's contents overflow they'll be covered up by the border.
	 */
d495 11
a505 7
	if (dpPtr->relief != TK_RELIEF_FLAT) {
	    int inset = butPtr->highlightWidth;

	    Tk_Draw3DRectangle(tkwin, pixmap, dpPtr->border, inset, inset,
		    Tk_Width(tkwin) - 2*inset, Tk_Height(tkwin) - 2*inset,
		    butPtr->borderWidth, dpPtr->relief);
	}
d514 3
a516 3
 *	After changes in a button's text or bitmap, this procedure recomputes
 *	the button's geometry and passes this information along to the
 *	geometry manager for the window.
d519 1
a519 1
 *	None.
d522 1
a522 1
 *	The button's window may change size.
d529 1
a529 1
    TkButton *butPtr)		/* Button whose geometry may have changed. */
d532 2
a533 1
    int xInset, yInset, txtWidth, txtHeight;
d540 1
a540 1

d547 1
d550 2
a551 2
	Tk_SizeOfImage(butPtr->image, &width, &height);
	haveImage = 1;
d553 2
a554 2
	Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
	haveImage = 1;
d558 10
a567 10
	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);
d571 4
a574 4
     * If the button is compound (ie, 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.
d578 47
a624 15
	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.
	     */
d626 2
a627 7
	    width += txtWidth + butPtr->padX;
	    height = (height > txtHeight ? height : txtHeight);
	    break;
	case COMPOUND_CENTER:
	    /*
	     * Image and text are superimposed.
	     */
a628 39
	    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;
	    }
	}
d630 33
a662 16
	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;
	}
d668 1
a668 1

d670 1
a670 1
	butPtr->highlightWidth = 0;
d672 1
a672 1

d674 4
a677 4
     * The width and height calculation for Appearance buttons with images &
     * non-Appearance buttons with images is different. In the latter case, we
     * add the borderwidth to the inset, since we are going to stamp a 3-D
     * border over the image. In the former, we add it to the height,
d681 1
a681 1
     * if any, and for the border and padding, plus if this is an image two
d687 4
a690 4
     * button. The actual width of the default ring is one less than the
     * highlight width as there is also one pixel of spacing. Appearance
     * buttons with images do not have a highlight ring, because the Bevel
     * button type does not support one.
d694 2
a695 2
	width += 2*butPtr->padX;
	height += 2*butPtr->padY;
d697 1
a697 1

d699 35
a733 14
	if ((butPtr->image == None) && (butPtr->bitmap == None)) {
	    butPtr->inset = 0;
	    if (butPtr->defaultState != STATE_DISABLED) {
		butPtr->inset += butPtr->highlightWidth;
	    }
	} else {
	    butPtr->inset = 0;
	    width += (2 * butPtr->borderWidth + 4);
	    height += (2 * butPtr->borderWidth + 4);
	}
    } else if (butPtr->type == TYPE_LABEL) {
	butPtr->inset = butPtr->borderWidth;
    } else if (butPtr->indicatorOn) {
	butPtr->inset = 0;
d735 1
a735 21
	/*
	 * Under Appearance, the Checkbutton or radiobutton with an image is
	 * represented by a BevelButton with the Sticky defProc... So we must
	 * set its height in the same way as the Button with an image or
	 * bitmap.
	 */

	if ((butPtr->image != None) || (butPtr->bitmap != None)) {
	    int border;

	    butPtr->inset = 0;
	    if (butPtr->borderWidth <= 2) {
		border = 6;
	    } else {
		border = 2 * butPtr->borderWidth + 2;
	    }
	    width += border;
	    height += border;
	} else {
	    butPtr->inset = butPtr->borderWidth;
	}
d739 2
a740 2
	xInset = butPtr->indicatorSpace + DEF_INSET_LEFT + DEF_INSET_RIGHT;
	yInset = DEF_INSET_TOP + DEF_INSET_BOTTOM;
d742 2
a743 2
	xInset = butPtr->indicatorSpace+butPtr->inset*2;
	yInset = butPtr->inset*2;
d754 1
a754 1
 *	Free data structures associated with the button control.
d757 1
a757 1
 *	None.
d760 1
a760 1
 *	Restores the default control state.
d769 1
a769 2
    MacButton *mbPtr = (MacButton *) butPtr; /* Mac button. */

d771 2
a772 2
	DisposeControl(mbPtr->userPane);
	mbPtr->userPane = NULL;
d781 1
a781 1
 *	This procedure initialises a Carbon control.
d784 1
a784 1
 *	0 on success, 1 on failure.
d787 5
a791 4
 *	A background pane control and the control itself is created. The
 *	contol is embedded in the background control. The background control
 *	is embedded in the root control of the containing window. The creation
 *	parameters for the control are also computed.
d797 8
a804 7
TkMacOSXInitControl(
    MacButton *mbPtr,		/* Mac button. */
    GWorldPtr destPort,
    GC gc,
    Pixmap pixmap,
    Rect *paneRect,
    Rect *cntrRect)
d806 2
a807 2
    OSErr status;
    TkButton *butPtr = (TkButton *) mbPtr;
d809 6
a814 3
    SInt16 procID, initialValue, minValue, maxValue;
    Boolean initiallyVisible;
    SInt32 controlReference;
d817 2
a818 2
    mbPtr->windowRef = GetWindowFromPort(
	    TkMacOSXGetDrawablePort(Tk_WindowId(butPtr->tkwin)));
d820 2
a821 2
    /*
     * Set up the user pane.
d825 4
a828 4
    initialValue = kControlSupportsEmbedding|kControlHasSpecialBackground;
    minValue = 0;
    maxValue = 1;
    procID = kControlUserPaneProc;
d830 9
a838 4
    mbPtr->userPane = NewControl(mbPtr->windowRef, paneRect, "\p",
	    initiallyVisible, initialValue, minValue, maxValue, procID,
	    controlReference);

d840 4
a843 2
	LOG_MSG("Failed to create user pane control");
	return 1;
d845 1
a845 1

d847 4
a850 2
	LOG_MSG("Failed to embed user pane control %d", status);
	return 1;
d852 1
a852 1

d854 1
a854 1
	    UserPaneBackgroundProc);
d858 9
a866 5
    mbPtr->control = NewControl(mbPtr->windowRef, cntrRect, "\p",
	    initiallyVisible, mbPtr->params.initialValue,
	    mbPtr->params.minValue, mbPtr->params.maxValue,
	    mbPtr->params.procID, controlReference);

d868 11
a878 7
	LOG_MSG("failed to create control of type %d", procID);
	return 1;
    }

    if (EmbedControl(mbPtr->control,mbPtr->userPane) != noErr) {
	LOG_MSG("failed to embed control of type %d", procID);
	return 1;
d880 1
a880 1

d884 1
a884 1

d890 3
a892 2
 *	This function draws the tk button using Mac controls. In addition,
 *	this code may apply custom colors passed in the TkButton.
d895 1
a895 1
 *	None.
d898 2
a899 1
 *	The control is created, or reinitialised as needed.
d906 7
a912 6
    MacButton *mbPtr,		/* Mac button. */
    GWorldPtr destPort,		/* Off screen GWorld. */
    GC gc,			/* The GC we are drawing into - needed for the
				 * bevel button */
    Pixmap pixmap)		/* The pixmap we are drawing into - needed for
				 * the bevel button */
d914 11
a924 10
    TkButton *butPtr = (TkButton *) mbPtr;
    int err;
    TkWindow *winPtr;
    Rect paneRect, cntrRect;

    winPtr = (TkWindow *) butPtr->tkwin;

    paneRect.left = winPtr->privatePtr->xOff;
    paneRect.top = winPtr->privatePtr->yOff;
    paneRect.right = paneRect.left + Tk_Width(butPtr->tkwin);
d930 3
a932 3
    cntrRect.left += butPtr->inset;
    cntrRect.top += butPtr->inset;
    cntrRect.right -= butPtr->inset;
d935 3
a937 3
    cntrRect.left += DEF_INSET_LEFT;
    cntrRect.top += DEF_INSET_TOP;
    cntrRect.right -= DEF_INSET_RIGHT;
d940 3
a942 3
    /*
     * The control has been previously initialised. It may need to be
     * re-initialised.
d944 1
a944 1

d946 15
a960 16
	MacControlParams params;

	TkMacOSXComputeControlParams(butPtr, &params);
	if (bcmp(&params, &mbPtr->params, sizeof(params))) {
	    /*
	     * The type of control has changed. Clean it up and clear the
	     * flag.
	     */

	    if (mbPtr->userPane) {
		DisposeControl(mbPtr->userPane);
		mbPtr->userPane = NULL;
		mbPtr->control = NULL;
	    }
	    mbPtr->flags = 0;
	}
d963 4
a966 4
	if (TkMacOSXInitControl(mbPtr, destPort, gc, pixmap,
		&paneRect, &cntrRect)) {
	    return;
	}
d972 36
a1007 33
	Str255 controlTitle;
	ControlFontStyleRec fontStyle;
	Tk_Font font;
	int len;

	if (((mbPtr->info.image == NULL) && (mbPtr->info.bitmap == None))
		|| (mbPtr->info.compound != COMPOUND_NONE)) {
	    len = TkFontGetFirstTextLayout(butPtr->textLayout,
		    &font, (char*) controlTitle);
	    controlTitle[len] = 0;
	} else {
	    len = 0;
	    controlTitle[0] = 0;
	}
	if (bcmp(mbPtr->controlTitle, controlTitle, len+1)) {
	    CFStringRef cf = CFStringCreateWithCString(NULL,
		    (char*) controlTitle, kCFStringEncodingUTF8);

	    if (cf != NULL) {
		SetControlTitleWithCFString(mbPtr->control, cf);
		CFRelease(cf);
	    }
	    bcopy(controlTitle, mbPtr->controlTitle, len+1);
	}
	if (len) {
	    TkMacOSXInitControlFontStyle(font, &fontStyle);
	    if (bcmp(&mbPtr->fontStyle, &fontStyle, sizeof(fontStyle)) ) {
		if (SetControlFontStyle(mbPtr->control, &fontStyle) != noErr) {
		    LOG_MSG("SetControlFontStyle failed");
		}
		bcopy(&fontStyle, &mbPtr->fontStyle, sizeof(fontStyle));
	    }
	}
d1010 3
a1012 5
	/*
	 * Initialiase the image/button parameters.
	 */

	SetupBevelButton(mbPtr, mbPtr->control, destPort, gc, pixmap);
d1016 1
a1016 1
	SetControlValue(mbPtr->control, 1);
d1018 1
a1018 1
	SetControlValue(mbPtr->control, 2);
d1020 1
a1020 1
	SetControlValue(mbPtr->control, 0);
a1029 1

d1037 9
a1045 9
		case TYPE_BUTTON:
		    HiliteControl(mbPtr->control, kControlButtonPart);
		    break;
		case TYPE_RADIO_BUTTON:
		    HiliteControl(mbPtr->control, kControlRadioButtonPart);
		    break;
		case TYPE_CHECK_BUTTON:
		    HiliteControl(mbPtr->control, kControlCheckBoxPart);
		    break;
d1053 1
a1053 1
	Boolean isDefault;
d1055 9
a1063 9
	if (butPtr->defaultState == STATE_ACTIVE) {
	    isDefault = true;
	} else {
	    isDefault = false;
	}
	if (SetControlData(mbPtr->control, kControlNoPart,
		kControlPushButtonDefaultTag,
		sizeof(isDefault), (Ptr) &isDefault) != noErr) {
	}
d1067 3
a1069 3
	ShowControl(mbPtr->userPane);
	ShowControl(mbPtr->control);
	mbPtr->flags ^= 2;
d1071 2
a1072 2
	SetControlVisibility(mbPtr->control, true, true);
	Draw1Control(mbPtr->userPane);
d1076 1
a1076 1
	KillPicture(mbPtr->bevelButtonContent.u.picture);
d1085 2
a1086 2
 *	Sets up the Bevel Button with image by copying the source image onto
 *	the PicHandle for the button.
d1089 1
a1089 1
 *	None
d1092 1
a1092 1
 *	The image or bitmap for the button is copied over to a picture.
a1095 1

d1098 8
a1105 7
    MacButton *mbPtr,		/* Mac button. */
    ControlRef controlHandle,	/* The control to set this picture to */
    GWorldPtr destPort,		/* Off screen GWorld. */
    GC gc,			/* The GC we are drawing into - needed for the
				 * bevel button */
    Pixmap pixmap)		/* The pixmap we are drawing into - needed for
				 * the bevel button */
d1107 3
a1109 2
    int err, height, width;
    TkButton *butPtr = (TkButton *) mbPtr;
d1111 1
a1111 1

d1115 2
a1116 1
	Tk_SizeOfImage(butPtr->image, &width, &height);
d1118 2
a1119 1
	Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
d1121 1
a1121 1

d1123 1
a1123 1
	width = butPtr->width;
d1126 1
a1126 1
	height = butPtr->height;
d1132 2
a1133 2
    /*
     * Set the flag to circumvent clipping and bounds problems with OS 10.0.4
d1135 6
a1140 4

    mbPtr->bevelButtonContent.u.picture = OpenCPicture(&mbPtr->picParams);
    if (!mbPtr->bevelButtonContent.u.picture) {
	LOG_MSG("OpenCPicture failed");
d1143 1
a1143 1

d1145 3
a1147 3
     * TO DO - There is one case where XCopyPlane calls CopyDeepMask, which
     * does not get recorded in the picture. So the bitmap code will fail in
     * that case.
d1149 1
a1149 1

d1151 5
a1155 3
	Tk_RedrawImage(butPtr->selectImage, 0,0, width, height, pixmap, 0,0);
    } else if ((butPtr->tristateImage!=NULL) && (butPtr->flags & TRISTATED)) {
	Tk_RedrawImage(butPtr->tristateImage, 0,0, width,height, pixmap, 0,0);
d1157 6
a1162 5
	Tk_RedrawImage(butPtr->image, 0, 0, width, height, pixmap, 0, 0);
    } else {
	XSetClipOrigin(butPtr->display, gc, 0, 0);
	XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, gc, 0, 0,
		(unsigned int) width, (unsigned int) height, 0, 0, 1);
d1164 1
a1164 1

d1167 11
a1177 7

    err = SetControlData(controlHandle, kControlButtonPart,
	    kControlBevelButtonContentTag,
	    sizeof(ControlButtonContentInfo),
	    (char *) &mbPtr->bevelButtonContent);
    LOG_ON_ERROR(SetControlData_BevelButtonContent);

d1179 5
a1183 5
	theAlignment = kControlBevelButtonAlignTop;
    } else if (butPtr->anchor == TK_ANCHOR_NE) {
	theAlignment = kControlBevelButtonAlignTopRight;
    } else if (butPtr->anchor == TK_ANCHOR_E) {
	theAlignment = kControlBevelButtonAlignRight;
d1185 1
a1185 1
	theAlignment = kControlBevelButtonAlignBottomRight;
d1187 1
a1187 1
	theAlignment = kControlBevelButtonAlignBottom;
d1189 1
a1189 1
	theAlignment = kControlBevelButtonAlignBottomLeft;
d1191 1
a1191 1
	theAlignment = kControlBevelButtonAlignLeft;
d1193 1
a1193 1
	theAlignment = kControlBevelButtonAlignTopLeft;
d1195 1
a1195 1
	theAlignment = kControlBevelButtonAlignCenter;
d1198 9
a1206 5
    err = SetControlData(controlHandle, kControlButtonPart,
	    kControlBevelButtonGraphicAlignTag,
	    sizeof(ControlButtonGraphicAlignment),
	    (char *) &theAlignment);
    LOG_ON_ERROR(SetControlData_BevelButtonGraphicAlign);
d1209 20
a1228 17
	ControlButtonTextPlacement thePlacement =
		kControlBevelButtonPlaceNormally;

	if (butPtr->compound == COMPOUND_TOP) {
	    thePlacement = kControlBevelButtonPlaceBelowGraphic;
	} else if (butPtr->compound == COMPOUND_BOTTOM) {
	    thePlacement = kControlBevelButtonPlaceAboveGraphic;
	} else if (butPtr->compound == COMPOUND_LEFT) {
	    thePlacement = kControlBevelButtonPlaceToRightOfGraphic;
	} else if (butPtr->compound == COMPOUND_RIGHT) {
	    thePlacement = kControlBevelButtonPlaceToLeftOfGraphic;
	}
	err = SetControlData(controlHandle, kControlButtonPart,
		kControlBevelButtonTextPlaceTag,
		sizeof(ControlButtonTextPlacement),
		(char *) &thePlacement);
	LOG_ON_ERROR(SetControlData_BevelButtonTextPlace);
d1237 3
a1239 2
 *	Utility function to add a UserPaneDrawProc to a userPane control. From
 *	MoreControls code from Apple DTS.
d1242 1
a1242 1
 *	MacOS system error.
d1245 1
a1245 1
 *	The user pane gets a new UserPaneDrawProc.
d1249 1
a1249 3

OSErr
SetUserPaneDrawProc(
d1254 5
a1258 6

    myControlUserPaneDrawUPP = NewControlUserPaneDrawUPP(upp);
    return SetControlData(control, kControlNoPart,
	    kControlUserPaneDrawProcTag,
	    sizeof(myControlUserPaneDrawUPP),
	    (Ptr) &myControlUserPaneDrawUPP);
d1266 2
a1267 1
 *	Utility function to add a UserPaneBackgroundProc to a userPane control
d1270 1
a1270 1
 *	MacOS system error.
d1273 1
a1273 1
 *	The user pane gets a new UserPaneBackgroundProc.
a1276 1

d1279 1
a1279 1
    ControlRef control,
a1282 1

d1284 4
a1287 4
    return SetControlData(control, kControlNoPart,
	    kControlUserPaneBackgroundProcTag,
	    sizeof(myControlUserPaneBackgroundUPP),
	    (Ptr) &myControlUserPaneBackgroundUPP);
d1295 2
a1296 2
 *	This function draws the background of the user pane that will lie
 *	under checkboxes and radiobuttons.
d1299 1
a1299 1
 *	None.
d1302 1
a1302 1
 *	The user pane gets updated to the current color.
a1305 1

a1310 1
    MacButton *mbPtr = (MacButton *) GetControlReference(control);
d1312 2
a1313 1

d1315 2
a1316 2
    RGBBackColor(&mbPtr->userPaneBackground);
    EraseRect(&contrlRect);
d1324 2
a1325 2
 *	This function sets up the background of the user pane that will lie
 *	under checkboxes and radiobuttons.
d1328 1
a1328 1
 *	None.
d1331 1
a1331 1
 *	The user pane background gets set to the current color.
d1341 2
a1342 2
    MacButton *mbPtr = (MacButton *) GetControlReference(control);

d1344 1
a1344 1
	RGBBackColor(&mbPtr->userPaneBackground);
d1353 4
a1356 4
 *	This function will review the colors used to display a Macintosh
 *	button. If any non-standard colors are used we create a custom palette
 *	for the button, populate with the colors for the button and install
 *	the palette.
d1358 2
a1359 2
 *	Under Appearance, we just set the pointer that will be used by the
 *	UserPaneDrawProc.
d1362 1
a1362 1
 *	None.
d1365 1
a1365 1
 *	The Macintosh control may get a custom palette installed.
d1371 1
a1371 2
UpdateControlColors(
    MacButton *mbPtr)
d1374 2
a1375 2
    TkButton *butPtr = (TkButton *) mbPtr;

d1377 8
a1384 7
     * Under Appearance we cannot change the background of the button itself.
     * However, the color we are setting is the color of the containing
     * userPane. This will be the color that peeks around the rounded corners
     * of the button. We make this the highlightbackground rather than the
     * background, because if you color the background of a frame containing a
     * button, you usually also color the highlightbackground as well, or you
     * will get a thin grey ring around the button.
d1386 1
a1386 1

d1388 1
a1388 1
	xcolor = Tk_3DBorderColor(butPtr->highlightBorder);
d1390 1
a1390 1
	xcolor = Tk_3DBorderColor(butPtr->normalBorder);
d1393 1
a1393 1

d1395 1
a1395 2
}

d1401 2
a1402 2
 *	This procedure is invoked by the Tk dispatcher for various events on
 *	buttons.
d1405 1
a1405 1
 *	None.
d1408 1
a1408 1
 *	When it gets exposed, it is redisplayed.
d1415 2
a1416 2
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
a1418 1

d1420 9
a1428 8
	    || eventPtr->type == DeactivateNotify) {
	if ((buttonPtr->tkwin == NULL) || (!Tk_IsMapped(buttonPtr->tkwin))) {
	    return;
	}
	if ((buttonPtr->flags & REDRAW_PENDING) == 0) {
	    Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) buttonPtr);
	    buttonPtr->flags |= REDRAW_PENDING;
	}
d1437 3
a1439 3
 *	This procedure computes the various parameters used when creating a
 *	Carbon control (NewControl). These are determined by the various Tk
 *	button parameters
d1442 1
a1442 1
 *	None.
d1445 1
a1445 1
 *	Sets the control initialisation parameters
d1451 1
a1451 3
TkMacOSXComputeControlParams(
    TkButton *butPtr,
    MacControlParams *paramsPtr)
d1454 3
a1456 3

    /*
     * Determine ProcID based on button type and dimensions.
d1458 1
a1458 1

d1460 68
a1527 65
    case TYPE_BUTTON:
	if ((butPtr->image == None) && (butPtr->bitmap == None)) {
	    paramsPtr->initialValue = 1;
	    paramsPtr->minValue = 0;
	    paramsPtr->maxValue = 1;
	    paramsPtr->procID = kControlPushButtonProc;
	} else {
	    paramsPtr->initialValue = 0;
	    paramsPtr->minValue = kControlBehaviorOffsetContents
		    | kControlContentPictHandle;
	    paramsPtr->maxValue = 1;
	    if (butPtr->borderWidth <= 2) {
		paramsPtr->procID = kControlBevelButtonSmallBevelProc;
	    } else if (butPtr->borderWidth == 3) {
		paramsPtr->procID = kControlBevelButtonNormalBevelProc;
	    } else {
		paramsPtr->procID = kControlBevelButtonLargeBevelProc;
	    }
	    paramsPtr->isBevel = 1;
	}
	break;
    case TYPE_RADIO_BUTTON:
	if (((butPtr->image == None) && (butPtr->bitmap == None))
		|| (butPtr->indicatorOn)) {
	    paramsPtr->initialValue = 1;
	    paramsPtr->minValue = 0;
	    paramsPtr->maxValue = 2;
	    paramsPtr->procID = kControlRadioButtonProc;
	} else {
	    paramsPtr->initialValue = 0;
	    paramsPtr->minValue = kControlBehaviorOffsetContents |
		    kControlBehaviorSticky | kControlContentPictHandle;
	    paramsPtr->maxValue = 2;
	    if (butPtr->borderWidth <= 2) {
		paramsPtr->procID = kControlBevelButtonSmallBevelProc;
	    } else if (butPtr->borderWidth == 3) {
		paramsPtr->procID = kControlBevelButtonNormalBevelProc;
	    } else {
		paramsPtr->procID = kControlBevelButtonLargeBevelProc;
	    }
	    paramsPtr->isBevel = 1;
	}
	break;
    case TYPE_CHECK_BUTTON:
	if (((butPtr->image == None) && (butPtr->bitmap == None))
		|| (butPtr->indicatorOn)) {
	    paramsPtr->initialValue = 1;
	    paramsPtr->minValue = 0;
	    paramsPtr->maxValue = 2;
	    paramsPtr->procID = kControlCheckBoxProc;
	} else {
	    paramsPtr->initialValue = 0;
	    paramsPtr->minValue = kControlBehaviorOffsetContents |
		    kControlBehaviorSticky | kControlContentPictHandle;
	    paramsPtr->maxValue = 2;
	    if (butPtr->borderWidth <= 2) {
		paramsPtr->procID = kControlBevelButtonSmallBevelProc;
	    } else if (butPtr->borderWidth == 3) {
		paramsPtr->procID = kControlBevelButtonNormalBevelProc;
	    } else {
		paramsPtr->procID = kControlBevelButtonLargeBevelProc;
	    }
	    paramsPtr->isBevel = 1;
	}
	break;
d1529 1
a1529 2
}

d1535 3
a1537 2
 *	This procedure computes the various parameters used when drawing a
 *	button. These are determined by the various Tk button parameters.
d1540 1
a1540 1
 *	1 if control will be used, 0 otherwise.
d1543 1
a1543 1
 *	Sets the button draw parameters
d1549 1
a1549 3
TkMacOSXComputeDrawParams(
    TkButton *butPtr,
    DrawParams *dpPtr)
d1551 4
a1554 4
    dpPtr->hasImageOrBitmap = ((butPtr->image != NULL)
	    || (butPtr->bitmap != None));
    dpPtr->offset = (butPtr->type == TYPE_BUTTON)
	    && dpPtr->hasImageOrBitmap;
d1556 7
a1562 5
    if ((butPtr->state == STATE_DISABLED) && (butPtr->disabledFg != NULL)) {
	dpPtr->gc = butPtr->disabledGC;
    } else if ((butPtr->type==TYPE_BUTTON) && (butPtr->state==STATE_ACTIVE)) {
	dpPtr->gc = butPtr->activeTextGC;
	dpPtr->border = butPtr->activeBorder;
d1564 1
a1564 1
	dpPtr->gc = butPtr->normalTextGC;
d1567 5
a1571 3
    if ((butPtr->flags & SELECTED) && (butPtr->state != STATE_ACTIVE)
	    && (butPtr->selectBorder != NULL) && !butPtr->indicatorOn) {
	dpPtr->border = butPtr->selectBorder;
d1573 1
a1573 1

d1575 4
a1578 4
     * Override the relief specified for the button if this is a checkbutton
     * or radiobutton and there's no indicator. However, don't do this in the
     * presence of Appearance, since then the bevel button will take care of
     * the relief.
d1584 4
a1587 4
	if (!dpPtr->hasImageOrBitmap) {
	    dpPtr->relief = (butPtr->flags & SELECTED) ? TK_RELIEF_SUNKEN
		    : TK_RELIEF_RAISED;
	}
a1592 1

d1594 1
a1594 1
	dpPtr->drawType = DRAW_LABEL;
d1596 28
a1623 43
	if (!dpPtr->hasImageOrBitmap) {
	    dpPtr->drawType = DRAW_CONTROL;
	} else if (butPtr->image != None) {
	    dpPtr->drawType = DRAW_BEVEL;
	} else {
	    /*
	     * TO DO - The current way the we draw bitmaps (XCopyPlane) uses
	     * CopyDeepMask in this one case. The Picture recording does not
	     * record this call, and so we can't use the Appearance bevel
	     * button here. The only case that would exercise this is if you
	     * use a bitmap, with -data & -mask specified. We should probably
	     * draw the appearance button and overprint the image in this
	     * case. This just punts and draws the old-style, ugly, button.
	     */

	    if (dpPtr->gc->clip_mask == 0) {
		dpPtr->drawType = DRAW_BEVEL;
	    } else {
		TkpClipMask *clipPtr = (TkpClipMask *) dpPtr->gc->clip_mask;

		if ((clipPtr->type == TKP_CLIP_PIXMAP) &&
			(clipPtr->value.pixmap != butPtr->bitmap)) {
		    dpPtr->drawType = DRAW_CUSTOM;
		} else {
		    dpPtr->drawType = DRAW_BEVEL;
		}
	    }
	}
    } else if (butPtr->indicatorOn) {
	dpPtr->drawType = DRAW_CONTROL;
    } else if (dpPtr->hasImageOrBitmap) {
	if (dpPtr->gc->clip_mask == 0) {
	    dpPtr->drawType = DRAW_BEVEL;
	} else {
	    TkpClipMask *clipPtr = (TkpClipMask*) dpPtr->gc->clip_mask;

	    if ((clipPtr->type == TKP_CLIP_PIXMAP) &&
		    (clipPtr->value.pixmap != butPtr->bitmap)) {
		dpPtr->drawType = DRAW_CUSTOM;
	    } else {
		dpPtr->drawType = DRAW_BEVEL;
	    }
	}
d1625 17
a1641 1
	dpPtr->drawType = DRAW_CUSTOM;
d1645 1
a1645 1
	return 1;
d1647 1
a1647 1
	return 0;
a1649 8

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
@


1.20
log
@sync whitespace with core-8-4-branch
@
text
@d1 1
a1 1
/* 
d4 2
a5 2
 *        This file implements the Macintosh specific portion of the
 *        button widgets.
d10 2
a11 2
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.19 2006/05/26 21:42:37 hobbs Exp $
d26 1
d41 1
a41 1
/*  
d50 1
a50 1
    int	   isBevel;
d57 5
a61 5
    int offset;			/* 0 means this is a normal widget.  1 means
				 * it is an image button, so we offset the
				 * image to make the button appear to move
				 * up and down as the relief changes. */
    GC	gc;
a64 1

d66 15
a80 15
    TkButton                 info;       /* generic button info */
    int                      id;
    int                      usingControl;
    int                      useTkText;
    int                      flags;     /* initialisation status */
    MacControlParams         params;
    WindowRef                windowRef;
    RGBColor                 userPaneBackground;
    ControlRef               userPane;  /* Carbon control */
    ControlRef               control;   /* Carbon control */
    Str255                   controlTitle;
    ControlFontStyleRec      fontStyle;
    /* 
     * the following are used to store the image content for
     * beveled buttons - i.e. buttons with images.
d82 1
a82 1
    CCTabHandle              tabHandle;
d84 2
a85 2
    OpenCPicParams           picParams;
    Pixmap                   picPixmap;
d92 21
a112 18

static OSErr SetUserPaneDrawProc(ControlRef control,
        ControlUserPaneDrawProcPtr upp);
static OSErr SetUserPaneSetUpSpecialBackgroundProc(ControlRef control,
        ControlUserPaneBackgroundProcPtr upp);
static void UserPaneDraw(ControlRef control, ControlPartCode cpc);
static void UserPaneBackgroundProc(ControlHandle,
        ControlBackgroundPtr info);

static void ButtonEventProc _ANSI_ARGS_(( ClientData clientData, XEvent *eventPtr));
static int UpdateControlColors _ANSI_ARGS_((MacButton *mbPtr ));
static void TkMacOSXComputeControlParams _ANSI_ARGS_((TkButton * butPtr, MacControlParams * paramsPtr));
static int TkMacOSXComputeDrawParams _ANSI_ARGS_((TkButton * butPtr, DrawParams * dpPtr));
static void TkMacOSXDrawControl _ANSI_ARGS_((MacButton *butPtr,
        GWorldPtr destPort, GC gc, Pixmap pixmap));
static void SetupBevelButton _ANSI_ARGS_((MacButton *butPtr,
        ControlRef controlHandle, 
        GWorldPtr destPort, GC gc, Pixmap pixmap));
d118 3
a120 3
Tk_ClassProcs tkpButtonProcs = { 
    sizeof(Tk_ClassProcs),        /* size */
    TkButtonWorldChanged,        /* worldChangedProc */
d132 1
a132 1
 *        Allocate a new TkButton structure.
d135 1
a135 1
 *        Returns a newly allocated TkButton structure.
d138 1
a138 1
 *        Registers an event handler for the widget.
d147 2
a148 2
    MacButton *macButtonPtr;
    macButtonPtr = (MacButton *) ckalloc(sizeof(MacButton));
d150 1
a150 1
            ButtonEventProc, (ClientData) macButtonPtr);
d171 1
d180 2
a181 2
 *        This procedure is invoked to display a button widget.  It is
 *        normally invoked as an idle handler.
d184 1
a184 1
 *        None.
d187 2
a188 2
 *        Commands are output to X to display the button in its
 *        current mode.  The REDRAW_PENDING flag is cleared.
d195 1
a195 1
    ClientData clientData)        /* Information about widget. */
d198 2
a199 5
    TkButton  *butPtr       = (TkButton *) clientData;
    Tk_Window tkwin         = butPtr->tkwin;
    int width, height, fullWidth, fullHeight;
    int textXOffset, textYOffset;
    int haveImage = 0, haveText = 0;
a200 1
    int borderWidth;
d202 7
a208 6
    int wasUsingControl;
    int imageWidth = 0, imageHeight = 0;
    int imageXOffset = 0, imageYOffset = 0; /* image information that will
					     * be used to restrict disabled
					     * pixmap as well */
    DrawParams drawParams, * dpPtr = &drawParams;
d212 1
a212 1
        return;
d219 6
a224 6
        macButtonPtr->usingControl = 1;
        if (butPtr->type == TYPE_BUTTON) {
            macButtonPtr->useTkText = 0;
        } else {
            macButtonPtr->useTkText = 1;
        }
d226 2
a227 2
        macButtonPtr->usingControl = 0;
        macButtonPtr->useTkText = 1;
d229 4
a232 4
   
    /* 
     * set up clipping region.  Make sure the we are using the port
     * for this button, or we will set the wrong window's clip. 
d234 1
a234 1
    
a238 1

d240 1
a240 1
     * See the comment in UpdateControlColors as to why we use the 
d245 7
a251 7
        if (butPtr->type == TYPE_BUTTON) {
            Tk_Fill3DRectangle(tkwin, pixmap, butPtr->highlightBorder, 0, 0,
                Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
        } else {
            Tk_Fill3DRectangle(tkwin, pixmap, butPtr->normalBorder, 0, 0,
                Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
        }
d256 2
a257 2
     * if it doesn't already exist.  Then configure the Macintosh control from
     * the Tk info.  Finally, we call Draw1Control to draw to the screen.
d261 7
a267 9
        borderWidth = 0;
        TkMacOSXDrawControl(macButtonPtr, destPort, dpPtr->gc, pixmap);
    } else {
       if (wasUsingControl && macButtonPtr->userPane) {
           DisposeControl(macButtonPtr->userPane);
           macButtonPtr->userPane = NULL;
           macButtonPtr->control  = NULL;
           macButtonPtr->flags = 0;
       }
d271 1
a271 1
        borderWidth = butPtr->borderWidth;
d275 2
a276 3
     * Display image or bitmap or text for button.  This has
     * already been done under Appearance with the Bevel
     * button types.
d280 150
a429 104
        /* Empty Body */
    } else {
        if (butPtr->image != None) {
            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) {
            int x;
            int y;
            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;
            
            x += dpPtr->offset;
            y += dpPtr->offset;
            if (dpPtr->relief == TK_RELIEF_RAISED) {
                x -= dpPtr->offset;
                y -= dpPtr->offset;
            } else if (dpPtr->relief == TK_RELIEF_SUNKEN) {
                x += dpPtr->offset;
                y += dpPtr->offset;
            }
	    imageXOffset += x;
	    imageYOffset += y;
            if (butPtr->image != NULL) {
                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, dpPtr->gc,
d431 17
a447 70
                XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, dpPtr->gc,
                        0, 0, (unsigned int) width, (unsigned int) height,
			imageXOffset, imageYOffset, 1);
                XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0);
            }

            if (macButtonPtr->useTkText) {
                Tk_DrawTextLayout(butPtr->display, pixmap, 
                        dpPtr->gc, butPtr->textLayout,
                        x + textXOffset, y + textYOffset, 0, -1);
                Tk_UnderlineTextLayout(butPtr->display, pixmap, dpPtr->gc,
                        butPtr->textLayout, 
                        x + textXOffset, y + textYOffset,
                        butPtr->underline);
            }
            y += fullHeight/2;
        } else {
            if (haveImage) {
                int x = 0;
                int y;

                TkComputeAnchor(butPtr->anchor, tkwin, 0, 0,
                        butPtr->indicatorSpace + width, height, &x, &y);
                x += butPtr->indicatorSpace;

                x += dpPtr->offset;
                y += dpPtr->offset;
                if (dpPtr->relief == TK_RELIEF_RAISED) {
                    x -= dpPtr->offset;
                    y -= dpPtr->offset;
                } else if (dpPtr->relief == TK_RELIEF_SUNKEN) {
                    x += dpPtr->offset;
                    y += dpPtr->offset;
                }
		imageXOffset += x;
		imageYOffset += y;
                if (butPtr->image != NULL) {
                    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, dpPtr->gc, x, y);
                    XCopyPlane(butPtr->display, butPtr->bitmap, 
                            pixmap, dpPtr->gc,
                            0, 0, (unsigned int) width,
                            (unsigned int) height, x, y, 1);
                    XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0);
                }
                y += height/2;
            } else if (macButtonPtr->useTkText) {
                int x = 0;
                int y;
                TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX,
                        butPtr->padY,
                        butPtr->indicatorSpace + butPtr->textWidth,
                        butPtr->textHeight, &x, &y);                
                x += butPtr->indicatorSpace;                
                Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc,
                        butPtr->textLayout, x, y, 0, -1);
            }
        }
d452 3
a454 3
     * 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.
d457 1
d459 3
a461 3
        if ((butPtr->state == STATE_DISABLED)
                && ((butPtr->disabledFg == NULL) || (butPtr->image != NULL))) {
            if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn
d463 1
a463 1
                XSetForeground(butPtr->display, butPtr->stippleGC,
d465 2
a466 1
            }
d471 1
d481 1
a481 1
            if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn
d486 6
a491 1
        }
d493 7
a499 11
        /*
         * Draw the border and traversal highlight last.  This way, if the
         * button's contents overflow they'll be covered up by the border.
         */
         
        if (dpPtr->relief != TK_RELIEF_FLAT) {
            int inset = butPtr->highlightWidth;
            Tk_Draw3DRectangle(tkwin, pixmap, dpPtr->border, inset, inset,
                Tk_Width(tkwin) - 2*inset, Tk_Height(tkwin) - 2*inset,
                butPtr->borderWidth, dpPtr->relief);
        }
d508 3
a510 3
 *        After changes in a button's text or bitmap, this procedure
 *        recomputes the button's geometry and passes this information
 *        along to the geometry manager for the window.
d513 1
a513 1
 *        None.
d516 1
a516 1
 *        The button's window may change size.
d523 1
a523 1
    TkButton *butPtr)        /* Button whose geometry may have changed. */
d526 1
a526 2
    int xInset, yInset;
    int txtWidth, txtHeight;
d533 1
a533 1
     
a539 1
     
d542 2
a543 2
        Tk_SizeOfImage(butPtr->image, &width, &height);
        haveImage = 1;
d545 2
a546 2
        Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
        haveImage = 1;
d550 10
a559 10
        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);
d563 4
a566 4
     * If the button is compound (ie, 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.
d570 15
a584 47
        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;
            }
        }
d586 7
a592 2
        width += 2 * butPtr->padX;
        height += 2 * butPtr->padY;
d594 39
d634 16
a649 33
        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;
            }
        }
d655 1
a655 1
     
d657 1
a657 1
        butPtr->highlightWidth = 0;
d659 1
a659 1
    
d661 4
a664 4
     * The width and height calculation for Appearance buttons with images & 
     * non-Appearance buttons with images is different.         In the latter case, 
     * we add the borderwidth to the inset, since we are going to stamp a
     * 3-D border over the image.  In the former, we add it to the height,
d668 1
a668 1
     * if any, and for the border and padding, plus if this is an image two 
d674 4
a677 4
     * button.        The actual width of the default ring is one less than the
     * highlight width as there is also one pixel of spacing.
     * Appearance buttons with images do not have a highlight ring, because the 
     * Bevel button type does not support one.
d681 2
a682 2
        width += 2*butPtr->padX;
        height += 2*butPtr->padY;
d684 1
a684 1
    
d686 14
a699 35
        if ((butPtr->image == None) && (butPtr->bitmap == None)) {
            butPtr->inset = 0;
            if (butPtr->defaultState != STATE_DISABLED) {
                butPtr->inset += butPtr->highlightWidth;
            }
        } else  {
            butPtr->inset = 0;
            width += (2 * butPtr->borderWidth + 4);
            height += (2 * butPtr->borderWidth + 4);
        }
    } else if ((butPtr->type != TYPE_LABEL)) {
        if (butPtr->indicatorOn) {
            butPtr->inset = 0;
        } else {
            /*
             * Under Appearance, the Checkbutton or radiobutton with an image
             * is represented by a BevelButton with the Sticky defProc...  
             * So we must set its height in the same way as the Button 
             * with an image or bitmap.
             */
             
            if ( (butPtr->image != None) || (butPtr->bitmap != None)) {
                int border;
                butPtr->inset = 0;
                if ( butPtr->borderWidth <= 2 ) {
                    border = 6;
                }  else {
                    border = 2 * butPtr->borderWidth + 2;
                }               
                width += border;
                height += border;
            } else {
                butPtr->inset = butPtr->borderWidth;
            }        
        }        
d701 21
a721 1
        butPtr->inset = butPtr->borderWidth;
d725 2
a726 2
        xInset = butPtr->indicatorSpace + DEF_INSET_LEFT + DEF_INSET_RIGHT;
        yInset = DEF_INSET_TOP + DEF_INSET_BOTTOM;
d728 2
a729 2
        xInset = butPtr->indicatorSpace+butPtr->inset*2;
        yInset = butPtr->inset*2;
d740 1
a740 1
 *        Free data structures associated with the button control.
d743 1
a743 1
 *        None.
d746 1
a746 1
 *        Restores the default control state.
d755 2
a756 1
    MacButton *mbPtr = ( MacButton *) butPtr; /* Mac button. */
d758 2
a759 2
        DisposeControl(mbPtr->userPane);
        mbPtr->userPane = NULL;
d768 1
a768 1
 *        This procedure initialises a Carbon control
d771 1
a771 1
 *        0 on success, 1 on failure.
d774 4
a777 5
 *        A background pane control and the control itself is created
 *      The contol is embedded in the background control
 *      The background control is embedded in the root control
 *      of the containing window
 *      The creation parameters for the control are also computed
d783 7
a789 8
TkMacOSXInitControl (
    MacButton *mbPtr,                /* Mac button. */
    GWorldPtr  destPort,
    GC         gc,
    Pixmap     pixmap,
    Rect      *paneRect,
    Rect      *cntrRect
)
d791 2
a792 2
    OSErr      status;
    TkButton * butPtr = ( TkButton * )mbPtr;
d794 3
a796 6
    SInt16     procID;
    Boolean    initiallyVisible;
    SInt16     initialValue;
    SInt16     minValue;
    SInt16     maxValue;
    SInt32     controlReference;
d799 2
a800 2
    mbPtr->windowRef
            = GetWindowFromPort(TkMacOSXGetDrawablePort(Tk_WindowId(butPtr->tkwin)));
d802 2
a803 2
    /* 
     * Set up the user pane
d807 4
a810 4
    initialValue     = kControlSupportsEmbedding|kControlHasSpecialBackground;
    minValue         = 0;
    maxValue         = 1;
    procID           = kControlUserPaneProc;
d812 4
a815 9
    mbPtr->userPane  = NewControl(mbPtr->windowRef,
        paneRect, "\p",
        initiallyVisible,
        initialValue,
        minValue,
        maxValue,
        procID,
        controlReference );
        
d817 2
a818 4
#ifdef TK_MAC_DEBUG
        fprintf(stderr,"Failed to create user pane control\n");
#endif
        return 1;
d820 1
a820 1
    
d822 2
a823 4
#ifdef TK_MAC_DEBUG
        fprintf(stderr,"Failed to embed user pane control %d\n", status);
#endif
        return 1;
d825 1
a825 1
    
d827 1
a827 1
        UserPaneBackgroundProc);
d831 5
a835 9
    mbPtr->control = NewControl(mbPtr->windowRef,
        cntrRect, "\p",
        initiallyVisible,
        mbPtr->params.initialValue,
        mbPtr->params.minValue,
        mbPtr->params.maxValue,
        mbPtr->params.procID,
        controlReference );
        
d837 7
a843 11
#ifdef TK_MAC_DEBUG
        fprintf(stderr,"failed to create control of type %d\n",procID);
#endif
        return 1;
    }
    
    if (EmbedControl(mbPtr->control,mbPtr->userPane) != noErr ) {
#ifdef TK_MAC_DEBUG
        fprintf(stderr,"failed to embed control of type %d\n",procID);
#endif
        return 1;
d845 1
a845 1
    
d849 1
a849 1

d855 2
a856 3
 *        This function draws the tk button using Mac controls
 *        In addition, this code may apply custom colors passed 
 *        in the TkButton.
d859 1
a859 1
 *        None.
d862 1
a862 2
 *      The control is created, or reinitialised as needed
 *
d869 6
a874 7
    MacButton *mbPtr,    /* Mac button. */
    GWorldPtr destPort,  /* Off screen GWorld. */
    GC gc,               /* The GC we are drawing into - needed for
                          * the bevel button */
    Pixmap pixmap)       /* The pixmap we are drawing into - needed
                          * for the bevel button */
                
d876 10
a885 11
    TkButton * butPtr = ( TkButton *)mbPtr;
    int        err;
    TkWindow * winPtr;
    Rect       paneRect;
    Rect       cntrRect;

    winPtr = (TkWindow *)butPtr->tkwin;
   
    paneRect.left   = winPtr->privatePtr->xOff;
    paneRect.top    = winPtr->privatePtr->yOff;
    paneRect.right  = paneRect.left + Tk_Width(butPtr->tkwin);
d891 3
a893 3
    cntrRect.left   += butPtr->inset;
    cntrRect.top    += butPtr->inset;
    cntrRect.right  -= butPtr->inset;
d896 3
a898 3
    cntrRect.left   += DEF_INSET_LEFT;
    cntrRect.top    += DEF_INSET_TOP;
    cntrRect.right  -= DEF_INSET_RIGHT;
d901 3
a903 3
    /* 
     * The control has been previously initialised
     * It may need to be re-initialised 
d905 1
a905 1
     
d907 16
a922 15
        MacControlParams params;
        TkMacOSXComputeControlParams(butPtr, &params);
        if (bcmp(&params, &mbPtr->params, sizeof(params))) {
            /* 
             * the type of control has changed
             * Clean it up and clear the flag 
             */
             
            if (mbPtr->userPane) {
                DisposeControl(mbPtr->userPane);
                mbPtr->userPane = NULL;
                mbPtr->control = NULL;
            }
            mbPtr->flags = 0;
        }
d925 4
a928 4
        if (TkMacOSXInitControl(mbPtr, destPort, gc, 
                pixmap, &paneRect, &cntrRect) ) {
            return;
        }
d934 33
a966 36
        Str255              controlTitle;
        ControlFontStyleRec fontStyle;
        Tk_Font    font;
        int        len;
        
        if (((mbPtr->info.image == NULL) && (mbPtr->info.bitmap == None))
               || (mbPtr->info.compound != COMPOUND_NONE)) {
            len = TkFontGetFirstTextLayout(butPtr->textLayout, 
                    &font, (char*) controlTitle);
            controlTitle[len] = 0;
        } else {
            len = 0;
            controlTitle[0] = 0;
        }
        if (bcmp(mbPtr->controlTitle, controlTitle, len+1)) {
            CFStringRef cf;    	    
            cf = CFStringCreateWithCString(NULL,
                  (char*) controlTitle, kCFStringEncodingUTF8);
            if (cf != NULL) {
            SetControlTitleWithCFString(mbPtr->control, cf);
            CFRelease(cf);
            }
            bcopy(controlTitle, mbPtr->controlTitle, len+1);
        }
        if (len) {
            TkMacOSXInitControlFontStyle(font, &fontStyle);
            if (bcmp(&mbPtr->fontStyle, &fontStyle, sizeof(fontStyle)) ) {
                if (SetControlFontStyle(mbPtr->control, &fontStyle) != noErr) {
#ifdef TK_MAC_DEBUG
                    fprintf(stderr,"SetControlFontStyle failed\n");
#endif
                }
                bcopy(&fontStyle, &mbPtr->fontStyle, 
                        sizeof(fontStyle));
            }
        }
d969 5
a973 3
        /* Initialiase the image/button parameters */
        SetupBevelButton(mbPtr, mbPtr->control, destPort, 
                      gc, pixmap);
d977 1
a977 1
     SetControlValue(mbPtr->control, 1);
d979 1
a979 1
     SetControlValue(mbPtr->control, 2);
d981 1
a981 1
     SetControlValue(mbPtr->control, 0);
d991 1
d999 9
a1007 9
		    case TYPE_BUTTON:
			HiliteControl(mbPtr->control,  kControlButtonPart);
			break;
		    case TYPE_RADIO_BUTTON:
			HiliteControl(mbPtr->control, kControlRadioButtonPart);
			break;
		    case TYPE_CHECK_BUTTON:
			HiliteControl(mbPtr->control, kControlCheckBoxPart);
			break;
d1015 1
a1015 1
        Boolean isDefault;
d1017 9
a1025 9
        if (butPtr->defaultState == STATE_ACTIVE) {
            isDefault = true;
        } else {
            isDefault = false;
        }
        if ((err=SetControlData(mbPtr->control, kControlNoPart, 
                kControlPushButtonDefaultTag,
                sizeof(isDefault), (Ptr) &isDefault)) != noErr) {
        }
d1029 3
a1031 3
        ShowControl(mbPtr->userPane);
        ShowControl(mbPtr->control);
        mbPtr->flags ^= 2;
d1033 2
a1034 2
        SetControlVisibility(mbPtr->control, true, true);
        Draw1Control(mbPtr->userPane);
d1038 1
a1038 1
        KillPicture(mbPtr->bevelButtonContent.u.picture);
d1047 2
a1048 2
 *        Sets up the Bevel Button with image by copying the
 *        source image onto the PicHandle for the button.
d1051 1
a1051 1
 *        None
d1054 1
a1054 1
 *        The image or bitmap for the button is copied over to a picture.
d1058 1
d1061 7
a1067 8
    MacButton *mbPtr,                /* Mac button. */
    ControlRef controlHandle,         /* The control to set this picture to */
    GWorldPtr destPort,                /* Off screen GWorld. */
    GC gc,                        /* The GC we are drawing into - needed for
                                 * the bevel button */
    Pixmap pixmap                /* The pixmap we are drawing into - needed
                                   for the bevel button */
    )
d1069 2
a1070 3
    int       err;
    TkButton *butPtr = ( TkButton *)mbPtr;
    int height, width;
d1072 1
a1072 1
    
d1076 1
a1076 2
        Tk_SizeOfImage(butPtr->image, 
                &width, &height);
d1078 1
a1078 2
        Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, 
                &width, &height);
d1080 1
a1080 1
            
d1082 1
a1082 1
        width = butPtr->width;
d1085 1
a1085 1
        height = butPtr->height;
d1091 2
a1092 2
    /* 
     * Set the flag to circumvent clipping and bounds problems with OS 10.0.4 
d1094 4
a1097 6
     
    if (!(mbPtr->bevelButtonContent.u.picture 
            = OpenCPicture(&mbPtr->picParams)) ) {
#ifdef TK_MAC_DEBUG
        fprintf(stderr,"OpenCPicture failed\n");
#endif
d1100 1
a1100 1
    
d1102 3
a1104 3
     * TO DO - There is one case where XCopyPlane calls CopyDeepMask,
     * which does not get recorded in the picture.  So the bitmap code
     * will fail in that case.
d1106 1
a1106 1
     
d1108 3
a1110 5
        Tk_RedrawImage(butPtr->selectImage, 0, 0, width, height,
                pixmap, 0, 0);
    } else if ((butPtr->tristateImage != NULL) && (butPtr->flags & TRISTATED)) {
        Tk_RedrawImage(butPtr->tristateImage, 0, 0, width, height,
                pixmap, 0, 0);
d1112 5
a1116 6
        Tk_RedrawImage(butPtr->image, 0, 0, width, 
                height, pixmap, 0, 0);
    } else {                        
        XSetClipOrigin(butPtr->display, gc, 0, 0);
        XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, gc, 0, 0,
                (unsigned int) width, (unsigned int) height, 0, 0, 1);
d1118 1
a1118 1
    
d1121 7
a1127 11
    
    if ((err = SetControlData(controlHandle, kControlButtonPart,
            kControlBevelButtonContentTag,
            sizeof(ControlButtonContentInfo),
            (char *) &mbPtr->bevelButtonContent)) != noErr) {
#ifdef TK_MAC_DEBUG
        fprintf(stderr,
                "SetControlData BevelButtonContent failed, %d\n", err );
#endif
    }
            
d1129 5
a1133 5
        theAlignment = kControlBevelButtonAlignTop;
    } else if (butPtr->anchor == TK_ANCHOR_NE) { 
        theAlignment = kControlBevelButtonAlignTopRight;
    } else if (butPtr->anchor == TK_ANCHOR_E) { 
        theAlignment = kControlBevelButtonAlignRight;
d1135 1
a1135 1
        theAlignment = kControlBevelButtonAlignBottomRight;
d1137 1
a1137 1
        theAlignment = kControlBevelButtonAlignBottom;
d1139 1
a1139 1
        theAlignment = kControlBevelButtonAlignBottomLeft;
d1141 1
a1141 1
        theAlignment = kControlBevelButtonAlignLeft;
d1143 1
a1143 1
        theAlignment = kControlBevelButtonAlignTopLeft;
d1145 1
a1145 1
        theAlignment = kControlBevelButtonAlignCenter;
d1148 5
a1152 9
    if ((err = SetControlData(controlHandle, kControlButtonPart,
            kControlBevelButtonGraphicAlignTag,
            sizeof(ControlButtonGraphicAlignment),
            (char *) &theAlignment)) != noErr) {
#ifdef TK_MAC_DEBUG
        fprintf(stderr,
                "SetControlData BevelButtonGraphicAlign failed, %d\n", err );
#endif
    }
d1155 17
a1171 20
        ControlButtonTextPlacement thePlacement = \
                kControlBevelButtonPlaceNormally;
        if (butPtr->compound == COMPOUND_TOP) {
            thePlacement = kControlBevelButtonPlaceBelowGraphic;
        } else if (butPtr->compound == COMPOUND_BOTTOM) {
            thePlacement = kControlBevelButtonPlaceAboveGraphic;
        } else if (butPtr->compound == COMPOUND_LEFT) {
            thePlacement = kControlBevelButtonPlaceToRightOfGraphic;
        } else if (butPtr->compound == COMPOUND_RIGHT) {
            thePlacement = kControlBevelButtonPlaceToLeftOfGraphic;
        }
        if ((err = SetControlData(controlHandle, kControlButtonPart,
                kControlBevelButtonTextPlaceTag,
                sizeof(ControlButtonTextPlacement),
                (char *) &thePlacement)) != noErr) {
#ifdef TK_MAC_DEBUG
            fprintf(stderr,
                    "SetControlData BevelButtonTextPlace failed, %d\n", err );
#endif
        }
d1180 2
a1181 3
 *        Utility function to add a UserPaneDrawProc
 *        to a userPane control.        From MoreControls code
 *        from Apple DTS.
d1184 1
a1184 1
 *        MacOS system error.
d1187 1
a1187 1
 *        The user pane gets a new UserPaneDrawProc.
d1191 3
a1193 1
OSErr SetUserPaneDrawProc (
d1198 6
a1203 5
    myControlUserPaneDrawUPP = NewControlUserPaneDrawUPP(upp);        
    return SetControlData (control, 
            kControlNoPart, kControlUserPaneDrawProcTag, 
            sizeof(myControlUserPaneDrawUPP), 
            (Ptr) &myControlUserPaneDrawUPP);
d1211 1
a1211 2
 *        Utility function to add a UserPaneBackgroundProc
 *        to a userPane control
d1214 1
a1214 1
 *        MacOS system error.
d1217 1
a1217 1
 *        The user pane gets a new UserPaneBackgroundProc.
d1221 1
d1224 1
a1224 1
    ControlRef control, 
d1228 1
d1230 4
a1233 4
    return SetControlData (control, kControlNoPart, 
            kControlUserPaneBackgroundProcTag, 
            sizeof(myControlUserPaneBackgroundUPP), 
            (Ptr) &myControlUserPaneBackgroundUPP);
d1241 2
a1242 2
 *        This function draws the background of the user pane that will 
 *        lie under checkboxes and radiobuttons.
d1245 1
a1245 1
 *        None.
d1248 1
a1248 1
 *        The user pane gets updated to the current color.
d1252 1
d1258 1
d1260 1
a1260 2
    MacButton * mbPtr;
    mbPtr = ( MacButton *)GetControlReference(control);
d1262 2
a1263 2
    RGBBackColor (&mbPtr->userPaneBackground);
    EraseRect (&contrlRect);
d1271 2
a1272 2
 *        This function sets up the background of the user pane that will 
 *        lie under checkboxes and radiobuttons.
d1275 1
a1275 1
 *        None.
d1278 1
a1278 1
 *        The user pane background gets set to the current color.
d1288 2
a1289 2
    MacButton * mbPtr;
    mbPtr = ( MacButton *)GetControlReference(control);
d1291 1
a1291 1
        RGBBackColor (&mbPtr->userPaneBackground);
d1300 4
a1303 4
 *        This function will review the colors used to display
 *        a Macintosh button.  If any non-standard colors are
 *        used we create a custom palette for the button, populate
 *        with the colors for the button and install the palette.
d1305 2
a1306 2
 *        Under Appearance, we just set the pointer that will be
 *        used by the UserPaneDrawProc.
d1309 1
a1309 1
 *        None.
d1312 1
a1312 1
 *        The Macintosh control may get a custom palette installed.
d1318 2
a1319 1
UpdateControlColors(MacButton * mbPtr)
d1322 2
a1323 2
    TkButton * butPtr = ( TkButton * )mbPtr;
    
d1325 7
a1331 8
     * Under Appearance we cannot change the background of the
     * button itself.  However, the color we are setting is the color
     * of the containing userPane.  This will be the color that peeks 
     * around the rounded corners of the button.  
     * We make this the highlightbackground rather than the background,
     * because if you color the background of a frame containing a
     * button, you usually also color the highlightbackground as well,
     * or you will get a thin grey ring around the button.
d1333 1
a1333 1
      
d1335 1
a1335 1
        xcolor = Tk_3DBorderColor(butPtr->highlightBorder);
d1337 1
a1337 1
        xcolor = Tk_3DBorderColor(butPtr->normalBorder);
d1340 1
a1340 1
    
d1342 2
a1343 1
}
d1349 2
a1350 2
 *        This procedure is invoked by the Tk dispatcher for various
 *        events on buttons.
d1353 1
a1353 1
 *        None.
d1356 1
a1356 1
 *      When it gets exposed, it is redisplayed.
d1363 2
a1364 2
    ClientData clientData,        /* Information about window. */
    XEvent *eventPtr)                /* Information about event. */
d1367 1
d1369 8
a1376 9
            || eventPtr->type == DeactivateNotify) {
        if ((buttonPtr->tkwin == NULL) 
                || (!Tk_IsMapped(buttonPtr->tkwin))) {
            return;
        }
        if ((buttonPtr->flags & REDRAW_PENDING) == 0) {
            Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) buttonPtr);
            buttonPtr->flags |= REDRAW_PENDING;
        }
d1385 3
a1387 3
 *        This procedure computes the various parameters used
 *        when creating a Carbon control (NewControl)
 *      These are determined by the various tk button parameters
d1390 1
a1390 1
 *        None.
d1393 1
a1393 1
 *        Sets the control initialisation parameters
d1399 3
a1401 1
TkMacOSXComputeControlParams(TkButton * butPtr, MacControlParams * paramsPtr )
d1404 3
a1406 3
    
    /* 
     * Determine ProcID based on button type and dimensions 
d1408 1
a1408 1
     
d1410 65
a1474 68
        case TYPE_BUTTON:
            if ((butPtr->image == None) && (butPtr->bitmap == None)) {
                paramsPtr->initialValue = 1;
                paramsPtr->minValue = 0;
                paramsPtr->maxValue = 1;
                paramsPtr->procID = kControlPushButtonProc;
            } else {
                paramsPtr->initialValue = 0;
                paramsPtr->minValue = kControlBehaviorOffsetContents
                    | kControlContentPictHandle;
                paramsPtr->maxValue = 1;
                if (butPtr->borderWidth <= 2) {
                    paramsPtr->procID = kControlBevelButtonSmallBevelProc;
                } else if (butPtr->borderWidth == 3) {
                    paramsPtr->procID = kControlBevelButtonNormalBevelProc;
                } else {
                    paramsPtr->procID = kControlBevelButtonLargeBevelProc;
                }
                paramsPtr->isBevel = 1;                
            }
            break;
        case TYPE_RADIO_BUTTON:
            if (((butPtr->image == None) && (butPtr->bitmap == None))
                || (butPtr->indicatorOn)) {
                paramsPtr->initialValue = 1;
                paramsPtr->minValue = 0;
                paramsPtr->maxValue = 2;
                paramsPtr->procID = kControlRadioButtonProc;
            } else {
                paramsPtr->initialValue = 0;
                paramsPtr->minValue = kControlBehaviorOffsetContents|
                    kControlBehaviorSticky|
                    kControlContentPictHandle;
                paramsPtr->maxValue = 2;
                if (butPtr->borderWidth <= 2) {
                    paramsPtr->procID = kControlBevelButtonSmallBevelProc;
                } else if (butPtr->borderWidth == 3) {
                    paramsPtr->procID = kControlBevelButtonNormalBevelProc;
                } else {
                    paramsPtr->procID = kControlBevelButtonLargeBevelProc;
                }
                paramsPtr->isBevel = 1;                
            }
            break;
        case TYPE_CHECK_BUTTON:
            if (((butPtr->image == None) 
                    && (butPtr->bitmap == None))
                    || (butPtr->indicatorOn)) {
                paramsPtr->initialValue = 1;
                paramsPtr->minValue = 0;
                paramsPtr->maxValue = 2;
                paramsPtr->procID = kControlCheckBoxProc;
            } else {
                paramsPtr->initialValue = 0;
                paramsPtr->minValue = kControlBehaviorOffsetContents
                    | kControlBehaviorSticky
                    | kControlContentPictHandle;
                paramsPtr->maxValue = 2;
                if (butPtr->borderWidth <= 2) {
                    paramsPtr->procID = kControlBevelButtonSmallBevelProc;
                } else if (butPtr->borderWidth == 3) {
                    paramsPtr->procID = kControlBevelButtonNormalBevelProc;
                } else {
                    paramsPtr->procID = kControlBevelButtonLargeBevelProc;
                }
                paramsPtr->isBevel = 1;                
            }   
            break;
d1476 2
a1477 1
}
d1483 2
a1484 3
 *        This procedure computes the various parameters used
 *        when drawing a button
 *      These are determined by the various tk button parameters
d1487 1
a1487 1
 *        1 if control will be used, 0 otherwise.
d1490 1
a1490 1
 *        Sets the button draw parameters
d1496 3
a1498 1
TkMacOSXComputeDrawParams(TkButton * butPtr, DrawParams * dpPtr)
d1500 4
a1503 4
    dpPtr->hasImageOrBitmap = ((butPtr->image != NULL) 
            || (butPtr->bitmap != None));
    dpPtr->offset = (butPtr->type == TYPE_BUTTON) 
            && dpPtr->hasImageOrBitmap;
d1505 5
a1509 7
    if ((butPtr->state == STATE_DISABLED) 
            && (butPtr->disabledFg != NULL)) {
        dpPtr->gc = butPtr->disabledGC;
    } else if ((butPtr->type == TYPE_BUTTON)
            && (butPtr->state == STATE_ACTIVE)) {
        dpPtr->gc = butPtr->activeTextGC;
        dpPtr->border = butPtr->activeBorder;
d1511 1
a1511 1
        dpPtr->gc = butPtr->normalTextGC;
d1514 3
a1516 5
    if ((butPtr->flags & SELECTED) 
            && (butPtr->state != STATE_ACTIVE)
            && (butPtr->selectBorder != NULL) 
            && !butPtr->indicatorOn) {
       dpPtr->border = butPtr->selectBorder;
d1518 1
a1518 1
    
d1520 4
a1523 4
     * Override the relief specified for the button if this is a
     * checkbutton or radiobutton and there's no indicator.
     * However, don't do this in the presence of Appearance, since
     * then the bevel button will take care of the relief.
d1529 4
a1532 4
        if (!dpPtr->hasImageOrBitmap) {
            dpPtr->relief = (butPtr->flags & SELECTED) ? TK_RELIEF_SUNKEN
                : TK_RELIEF_RAISED;
        }
d1538 1
d1540 1
a1540 1
        dpPtr->drawType = DRAW_LABEL;
d1542 43
a1584 28
        if (!dpPtr->hasImageOrBitmap) {
            dpPtr->drawType = DRAW_CONTROL;
        } else if (butPtr->image != None) {
            dpPtr->drawType = DRAW_BEVEL;
        } else {
            /*
             * TO DO - The current way the we draw bitmaps (XCopyPlane)
             * uses CopyDeepMask in this one case.  The Picture recording 
             * does not record this call, and so we can't use the
             * Appearance bevel button here.  The only case that would
             * exercise this is if you use a bitmap, with
             * -data & -mask specified.         We should probably draw the 
             * appearance button and overprint the image in this case.
             * This just punts and draws the old-style, ugly, button.
             */
             
            if (dpPtr->gc->clip_mask == 0) {
                dpPtr->drawType = DRAW_BEVEL;
            } else {
                TkpClipMask *clipPtr = (TkpClipMask*) dpPtr->gc->clip_mask;
                if ((clipPtr->type == TKP_CLIP_PIXMAP) &&
                        (clipPtr->value.pixmap != butPtr->bitmap)) {
                    dpPtr->drawType = DRAW_CUSTOM;
                } else {
                    dpPtr->drawType = DRAW_BEVEL;
                }
            }
        }
d1586 1
a1586 17
        if (butPtr->indicatorOn) {
            dpPtr->drawType = DRAW_CONTROL;
        } else if (dpPtr->hasImageOrBitmap) {
            if (dpPtr->gc->clip_mask == 0) {
                dpPtr->drawType = DRAW_BEVEL;
            } else {
                TkpClipMask *clipPtr = (TkpClipMask*) dpPtr->gc->clip_mask;
                if ((clipPtr->type == TKP_CLIP_PIXMAP) &&
                        (clipPtr->value.pixmap != butPtr->bitmap)) {
                    dpPtr->drawType = DRAW_CUSTOM;
                } else {
                    dpPtr->drawType = DRAW_BEVEL;
                }
            }
        } else {
            dpPtr->drawType = DRAW_CUSTOM;
        }
d1590 1
a1590 1
        return 1;
d1592 1
a1592 1
        return 0;
d1595 8
@


1.19
log
@	* macosx/tkMacOSXButton.c (TkMacOSXDrawControl): correct redraw
	for direct transition from disabled to active state. [Bug 706446]
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.18 2006/03/24 14:58:01 das Exp $
d1052 1
a1052 1
    if ((butPtr->type == TYPE_BUTTON) ) {
d1062 1
a1062 1
                sizeof(isDefault), (Ptr) &isDefault)) != noErr ) {
d1074 1
a1074 1
 
d1077 1
a1077 1
    }         
@


1.18
log
@	* generic/tkTextDisp.c:   moved #ifdef MAC_OSX_TK code added by
	* macosx/tkMacOSXColor.c: Patch #638966 into platform specific
	* macosx/tkMacOSXInt.h:   files.

	* macosx/tkMacOSX.h:             cleaned up & rationalized order of
	* macosx/tkMacOSXBitmap.c:       #includes of tk and carbon headers.
	* macosx/tkMacOSXButton.c:
	* macosx/tkMacOSXCarbonEvents.c:
	* macosx/tkMacOSXClipboard.c:
	* macosx/tkMacOSXColor.c:
	* macosx/tkMacOSXConfig.c:
	* macosx/tkMacOSXCursor.c:
	* macosx/tkMacOSXDialog.c:
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXEmbed.c:
	* macosx/tkMacOSXEntry.c:
	* macosx/tkMacOSXEvent.c:
	* macosx/tkMacOSXEvent.h:
	* macosx/tkMacOSXFont.h:
	* macosx/tkMacOSXHLEvents.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXInt.h:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXKeyboard.c:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXRegion.c:
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXSend.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXWm.h:
	* macosx/tkMacOSXXStubs.c:
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.17 2006/03/22 00:21:17 das Exp $
d1022 1
a1022 1
    
d1024 1
a1024 17
        HiliteControl(mbPtr->control, kControlInactivePart);
    } else if (butPtr->state == STATE_ACTIVE) {
        if (mbPtr->params.isBevel) {
           HiliteControl(mbPtr->control, kControlButtonPart);
        } else {
            switch (butPtr->type) {
                case TYPE_BUTTON:
                    HiliteControl(mbPtr->control,  kControlButtonPart);
                    break;
                case TYPE_RADIO_BUTTON:
                    HiliteControl(mbPtr->control, kControlRadioButtonPart);
                    break;
                case TYPE_CHECK_BUTTON:
                    HiliteControl(mbPtr->control, kControlCheckBoxPart);
                    break;
            }
        }
d1026 23
a1048 1
        HiliteControl(mbPtr->control, kControlNoPart);
d1051 1
a1051 1
        
d1054 1
a1054 1
        
@


1.17
log
@	* generic/tkFont.c:             implementation of ATSUI text rendering
	* generic/tkInt.h:              in TkAqua provided by Benjamin
	* generic/tkTextDisp.c:         Riefenstahl. [Patch 638966]
	* library/demos/unicodeout.tcl:
	* macosx/tkMacOSXFont.h (new file):
	* macosx/tkMacOSXFont.c:
	* tests/font.test:
	* unix/tkUnixFont.c:
	* win/tkWinFont.c:

	* generic/tkFont.c:             moved MODULE_SCOPE declarations of
	* generic/tkFont.h:             font helper procs into header files.
	* macosx/tkMacOSXButton.c:
	* macosx/tkMacOSXFont.h:
	* macosx/tkMacOSXMenubutton.c:

	* macosx/Wish.xcode/project.pbxproj:     add new tkMacOSXFont.h file,
	* macosx/Wish.xcodeproj/project.pbxproj: turn off dead code stripping
	as it interferes with -sectcreate (rdar://4486223).

	* macosx/Wish.xcode/default.pbxuser:     add TCLLIBPATH=/Library/Tcl
	* macosx/Wish.xcodeproj/default.pbxuser: env var setting to tktest.

	* unix/configure.in: fix detection of symbols build when enabling
	TkAqua debug code; filter nm output of libtclstub better to avoid
	error on intel macs [Bug 1415789].
	* unix/configure: autoconf-2.59
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.16 2005/11/27 02:36:14 das Exp $
d16 1
a17 1
#include "tkMacOSXInt.h"
a30 2
#include <Carbon/Carbon.h>

@


1.16
log
@	* unix/tcl.m4 (Darwin): add 64bit support, check for Tiger copyfile(),
	add CFLAGS to SHLIB_LD to support passing -isysroot in env(CFLAGS) to
	configure (flag can't be present twice, so can't be in both CFLAGS and
	LDFLAGS during configure), don't use -prebind when deploying on 10.4,
	define TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING (rdar://3171542).
	(SC_ENABLE_LANGINFO, SC_TIME_HANDLER): add/fix caching, fix obsolete
	autoconf macros. Sync with tcl/unix/tcl.m4.

	* unix/configure.in: fix obsolete autoconf macros, sync gratuitous
	formatting/ordering differences with tcl/unix/configure.in.

	* unix/Makefile.in: add CFLAGS to wish/tktest link to make executable
	linking the same as during configure (needed to avoid loosing any linker
	relevant flags in CFLAGS, in particular flags that can't be in LDFLAGS).
	Avoid concurrent linking of wish and compiling of tkTestInit.o during
	parallel make, fix dependencies and flags for building tkMacOSXInit.o
	(checkstubs, checkexports): dependency and Darwin fixes
	(dist): add new macosx files.

	* macosx/tkMacOSXEvent.c (TkMacOSXProcessEvent):
	* macosx/tkMacOSXEvent.h:
	* macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent):
	* macosx/tkMacOSXCarbonEvents.c: install standard application event
	handler, add & call functions to start and stop carbon even timer that
	runs the tcl event loop periodically during a nested carbon event loop
	in the toolbox (e.g. during menutracking) to ensure tcl timers etc
	continue to fire, register app event handler for menu tracking and HI
	command carbon events, move menu event handling to new handlers for
	those carbon events, no longer register for/handle appleevent carbon
	event (now dealt with by standard application event handler), event
	debugging code dynamically acquires carbon event debugging functions to
	allow use on Tiger where they are no longer exported from HIToolbox.

	* macosx/tkMacOSXFont.c (TkMacOSXUseAntialiasedText):
	* macosx/tkMacOSXKeyEvent.c (GetKeyboardLayout):
	* macosx/tkMacOSXCarbonEvents.c (TkMacOSXInitCarbonEvents):
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXInt.h: abstract common code to dynamically acquire
	address of a named symbol (from a loaded dynamic library) into new
	function TkMacOSXGetNamedSymbol() and macro TkMacOSXInitNamedSymbol.

	* macosx/tkMacOSXMenu.c (TkpNewMenu):
	* macosx/tkMacOSXMenubutton.c (MenuButtonInitControl):
	* macosx/tkMacOSXMenus.c (TkMacOSXHandleMenuSelect): switch to  modern
	utf8 aware menu manager API, remove obsolete code, add error handling.

	* macosx/tkMacOSXMouseEvent.c: define OSX 10.3 or later only constants
	if necessary to allow compilation on OSX 10.2

	* macosx/tkMacOSXWm.c (UpdateSizeHints): remove code that is never
	executed.

	* xlib/xgc.c (XCreateGC): sync with core-8-4-branch change.

	* generic/tk.h: add/correct location of version numbers in macosx files.

	* generic/tkInt.h: clarify fat compile comment.

	* macosx/Wish.pbproj/default.pbxuser (new file):
	* macosx/Wish.pbproj/jingham.pbxuser:
	* macosx/Wish.pbproj/project.pbxproj:
	* macosx/Wish.xcode/default.pbxuser:
	* macosx/Wish.xcode/project.pbxproj:
	* macosx/Wish.xcodeproj/default.pbxuser (new file):
	* macosx/Wish.xcodeproj/project.pbxproj (new file): new/updated projects
	for Xcode 2.2 on 10.4, Xcode 1.5 on 10.3 & ProjectBuilder on 10.2, with
	native tktest targets and support for universal (fat) compiles.

	* macosx/Tk-Info.plist (removed):
	* macosx/Wish-Info.plist (removed):
	* macosx/buildTkConfig.tcl (removed): remove obsolete build files.

	* macosx/README: clarification/cleanup, document new Xcode projects and
	universal (fat) builds via CFLAGS (i.e. ppc and i386 at the same time).

	* unix/Makefile.in:
	* unix/aclocal.m4:
	* unix/configure.in:
	* macosx/configure.ac (new file): add support for inclusion of
	unix/configure.in by macosx/configure.ac, allows generation of a config
	headers enabled configure script in macosx (required by Xcode projects).

	* macosx/GNUmakefile: rename from Makefile to avoid overwriting by
	configure run in tk/macosx, add support for reusing configure cache,
	build target fixes.

	* generic/tk3d.h:
	* generic/tkButton.h:
	* generic/tkCanvas.c:
	* generic/tkCanvas.h:
	* generic/tkColor.h:
	* generic/tkEntry.h:
	* generic/tkFileFilter.h:
	* generic/tkFont.c:
	* generic/tkFont.h:
	* generic/tkImage.c:
	* generic/tkImgPhoto.c:
	* generic/tkInt.h:
	* generic/tkMenu.c:
	* generic/tkMenu.h:
	* generic/tkMenubutton.h:
	* generic/tkScale.h:
	* generic/tkScrollbar.h:
	* generic/tkSelect.h:
	* generic/tkStubInit.c:
	* generic/tkStubLib.c:
	* generic/tkText.h:
	* generic/tkUndo.h:
	* macosx/tkMacOSXButton.c:
	* macosx/tkMacOSXDebug.c:
	* macosx/tkMacOSXDebug.h:
	* macosx/tkMacOSXDialog.c:
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXEntry.c:
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXInt.h:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXSend.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXXStubs.c:
	* unix/tkUnixButton.c:
	* unix/tkUnixMenu.c:
	* xlib/xgc.c: ensure externally visible symbols not contained in stubs
	table are declared as MODULE_SCOPE (or as static if not used outside of
	own source file), #ifdef out a few Xlib and aqua functions that are
	never called. These changes allow 'make checkstubs' to complete without
	error on Darwin with gcc 4.

	* macosx/tkMacOSXTest.c:
	* macosx/tkMacOSXPort.h:
	* win/tkWinTest.c:
	* generic/tkInt.decls: add functions needed by tktest to internal stubs
	table, correct signature of TkMacOSXHandleMenuSelect, add XSync to aqua
	Xlib stubs.

	* unix/tkUnixSend.c:
	* generic/tkText.c:
	* generic/tkTest.c: #ifdef unix only declarations.
	(TestmetricsCmd): unify win and mac implementation.
	(TestsendCmd): move to tkUnixSend.c to avoid access to global var.
	(TesttextCmd): move to tkText.c to avoid having to put all the internal
	text functions it uses into the stubs table.

	* generic/tkTextDisp.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXXStubs.c: fix gcc 4 warnings.

	* macosx/tkMacOSXNotify.c:
	* macosx/tkMacOSXScrlbr.c: sync with core-8-4-branch.

	* generic/tkIntDecls.h:
	* generic/tkIntPlatDecls.h:
	* generic/tkIntXlibDecls.h:
	* generic/tkStubInit.c:
	* unix/configure:
	* unix/tkConfig.h.in: regen.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.15 2005/09/10 14:53:20 das Exp $
d18 1
a112 3
MODULE_SCOPE int TkFontGetFirstTextLayout(Tk_TextLayout layout, Tk_Font * font, char * dst); 
MODULE_SCOPE void TkMacOSXInitControlFontStyle(Tk_Font tkfont,ControlFontStylePtr fsPtr);

@


1.15
log
@	* macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent): check if
	process is in front on MouseDown, otherwise request process activation
	from BringWindowForward() via new isFrontProcess param.

	* macosx/tkMacOSXCarbonEvents.c (TkMacOSXInitCarbonEvents): register our
	event handler on the dispatcher target for all carbon events of interest
	to TkAqua; this replaces event processing directly from the event queue
	and thus allows to capture events that are syntesized by Carbon and sent
	directly to the dispatcher and not to the event queue.

	* macosx/tkMacOSXEvent.c: remove TkMacOSXCountAndProcessMacEvents(),
	rename ReceiveAndProcessEvent() to TkMacOSXReceiveAndProcessEvent().
	(TkMacOSXReceiveAndProcessEvent): remove tk event processing before
	sending events to the dispatcher, all events of interest are now
	processed in our dispatcher target event handler.

	* macosx/tkMacOSXNotify.c (CarbonEventsCheckProc): dispatch events
	directly via TkMacOSXReceiveAndProcessEvent(), but dispatch no more than
	four carbon events at one time to avoid starving other event sources.

	* macosx/tkMacOSXEvent.c: formatting cleanup, move XSync() to XStubs,
	* macosx/tkMacOSXEvent.h: removed obsolete kEventClassWish handling.
	* macosx/tkMacOSXXStubs.c

	* macosx/tkMacOSXEvent.h: declare macosx internal procs as MODULE_SCOPE.
	* macosx/tkMacOSXEvent.c:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXWindowEvent.c:

	* macosx/tkMacOSXButton.c: conditionalize all debug message printing to
	* macosx/tkMacOSXCursor.c: stderr via TK_MAC_DEBUG define.
	* macosx/tkMacOSXDebug.c:
	* macosx/tkMacOSXDebug.h:
	* macosx/tkMacOSXDialog.c:
	* macosx/tkMacOSXEvent.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:

	* unix/configure.in: define TK_MAC_DEBUG on aqua when symbols enabled.
	* unix/configure: autoconf-2.59
	* unix/tkConfig.h.in: autoheader-2.59

	* library/listbox.tcl: synced aqua MouseWheel bindings with
	* library/scrlbar.tcl: core-8-4-branch.
	* library/text.tcl:

	* xlib/xcolors.c: fixed warning
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.14 2005/08/22 11:54:20 das Exp $
d112 2
a113 2
extern int TkFontGetFirstTextLayout(Tk_TextLayout layout, Tk_Font * font, char * dst); 
extern void TkMacOSXInitControlFontStyle(Tk_Font tkfont,ControlFontStylePtr fsPtr);
d800 1
a800 1
int
@


1.14
log
@	* macosx/tkMacOSXButton.c:
	* macosx/tkMacOSXDialog.c: fix warnings.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.13 2005/08/09 07:39:19 das Exp $
d844 1
d846 1
d851 1
d853 1
d872 1
d874 1
d879 1
d881 1
d1004 1
d1006 1
d1136 1
d1138 1
d1170 1
d1173 1
d1200 1
d1203 1
d1222 1
d1225 1
@


1.13
log
@	* macosx/tkMacOSXCarbonEvents.c (AppEventHandlerProc): handle carbon
	events sent directly to application event target via the general
	TkMacOSXProcessEvent() in the same way as events posted to the event
	loop. Moved existing app event handlers to tkMacOSXWindowEvent.c.
	(TkMacOSXInitCarbonEvents): register our application event handler for
	kEventWindowExpanded events to deal with uncollapsing from the dock.

	* macosx/tkMacOSXEvent.h: made TkMacOSXProcessEvent() non-static, added
	* macosx/tkMacOSXEvent.c: new interp field to TkMacOSXEvent struct for
	                          use by app event handler.

	* macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent): retrieve
	current window, partCode, modifiers and local cursor position from
	carbon mouse event if possible. Use new static GenerateButtonEvent()
	taking a MouseEventData struct instead of TkGenerateButtonEvent() to
	avoid recomputing already known values. Move process activation on
	MouseDown into BringWindowForward() to allow clicking on window titlebar
	widgets without activating process. Move code dealing with clicks in
	window titelbar into separate function HandleWindowTitlebarMouseDown()
	to avoid code duplication. Avoid repeated calls to TkMacOSXGetXWindow()
	by storing result in MouseEventData struct.
	(TkMacOSXButtonKeyState, XQueryPointer): try to get button and modifier
	state from currently processed carbon event (to avoid unnecessary IPC
	with the window server), otherwise use modern carbon API to get this
	info instead of Button() and GetKeys(); only retrieve info caller asks
	for (via non-NULL ptr passed to XQueryPointer).
	(ButtonModifiers2State): new static function converting carbon button
	and modifier state into tk state, allows detection of more than 3 mouse
	buttons (tk supports up to 5) and of NumLock and Fn modifier keys
	(NumLock is mapped to Mod3 and Fn to Mod4).

	* macosx/tkMacOSXWindowEvent.c (TkMacOSXProcessApplicationEvent): handle
	kEventWindowExpanded event to deal with window uncollapsing from the
	dock by generating tk Map event, handle kEventAppHidden and
	kEventAppShown events (moved here from tkMacOSXCarbonEvents.c).

	* macosx/tkMacOSXSubwindows.c (XUnmapWindow): only hide window when
	it is not iconified to avoid window flashing on collapse.

	* macosx/tkMacOSXWm.c: replaced Tk_DoWhenIdle() by Tcl_DoWhenIdle().
	(TkMacOSXZoomToplevel): remove call to TrackBox(), now done in
	HandleWindowTitlebarMouseDown() in tkMacOSXMouseEvent.c.
	(TkpWmSetState): avoid window flashing on collapse by unmapping after
	calling CollapseWindow(); only uncollapse window if it is collapsed.

	* generic/tkInt.decls: changed TkMacOSXZoomToplevel() signature.
	* generic/tkIntPlatDecls.h:

	* macosx/tkMacOSXKeyEvent.c (TkMacOSXProcessKeyboardEvent): only call
	GetMenuItemCommandID() on KeyDown or KeyRepeat events.

	* macosx/tkMacOSXMenu.c (ReconfigureMacintoshMenu): remove call to
	obsolete AppendResMenu() API.

	* macosx/tkMacOSXKeyEvent.c: replaced all direct uses of expensive
	* macosx/tkMacOSXMenu.c:     GetMouse() and TkMacOSXButtonKeyState()
	* macosx/tkMacOSXMenus.c:    APIs by calls to XQueryPointer()
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXWm.c:

	* macosx/tkMacOSXDialog.c:   replaced use of FrontNonFloatingWindow()
	* macosx/tkMacOSXKeyEvent.c: by ActiveNonFloatingWindow() as
	* macosx/tkMacOSXMenu.c:     recommended by Carbon docs.
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWm.c:

	* macosx/tkMacOSXDialog.c: fixed warnings
	* macosx/tkMacOSXTest.c:

	* macosx/tkMacOSXCarbonEvents.c: added CVS Id line to file header.
	* macosx/tkMacOSXDebug.c:
	* macosx/tkMacOSXDebug.h:
	* macosx/tkMacOSXEntry.c:
	* macosx/tkMacOSXEvent.h:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.h:

	* macosx/tkMacOSXInt.h: declare macosx internal procs as MODULE_SCOPE.
	* macosx/tkMacOSXCarbonEvents.c:
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXHLEvents.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXWindowEvent.c

	* library/bgerror.tcl: sync with core-8-4-branch changes of 2005-07-28.
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXMouseEvent.c:

	* generic/tkFrame.c:   sync with core-8-4-branch changes of 2005-07-27.
	* generic/tkIntDecls.h:
	* generic/tkStubInit.c:
	* generic/tkFrame.c:
	* win/tkWinDraw.c:
	* unix/tkUnixDraw.c:
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXInt.h:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXSubwindows.c:

	* macosx/tkMacOSXButton.c: sync with core-8-4-branch.
	* macosx/tkMacOSXEntry.c:
	* macosx/tkMacOSXScale.c:

	* library/demos/menu.tcl: removed errant '}'.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.12 2005/05/14 20:48:14 das Exp $
d207 1
a207 1
    int imageWidth, imageHeight;
@


1.12
log
@	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXNotify.c: introduction of new tcl notifier based on
	CFRunLoop allows replacement of the custom TkAqua notifier by a
	standard tcl event source. Removes requirement of threaded tcl core
	for TkAqua, allows to stub-link TkAqua against Tcl by removing use of
	the unstubbed TclInitNotifier & TclFinalizeNotifier. [Tcl Patch 1202052]

	* macosx/Wish.xcode/project.pbxproj:
	* macosx/Wish.pbproj/project.pbxproj: stub-link TkAqua: build with
	USE_TCL_STUBS and link against libtclstub instead of Tcl.framework,
	unexport libtclstub symbols from Tk to avoid duplicate symbol warnings
	when linking with both Tcl and Tk, fixes for gcc4.0 warnings.

	* macosx/Wish.xcode/project.pbxproj: sync with Wish.pbproj changes
	since 2004-11-19.
	NOTE: to use this project, need to uncomment the tclConfig.h settings
	at the top of tcl/unix/configure.in, autoconf and rebuild tcl !

	* macosx/tkMacOSXBitmap.c:
	* macosx/tkMacOSXButton.c:
	* macosx/tkMacOSXDialog.c:
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXHLEvents.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXKeyboard.c:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXXStubs.c: fixed gcc 4.0 warnings.

	* unix/tcl.m4: sync with tcl
	* unix/configure: autoconf-2.59
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.11 2005/03/12 00:27:15 wolfsuit Exp $
a915 1

d973 9
a981 9
	if ((mbPtr->info.image == NULL) && (mbPtr->info.bitmap == None) 
	  || (mbPtr->info.compound != COMPOUND_NONE)) {
	    len = TkFontGetFirstTextLayout(butPtr->textLayout, 
					   &font, (char*) controlTitle);
	    controlTitle[len] = 0;
	} else {
	    len = 0;
	    controlTitle[0] = 0;
	}
@


1.11
log
@Fix the mysterious "sometimes one button doesn't draw" bug.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.10 2004/11/09 12:46:10 vincentdarley Exp $
a914 1
    int        hilitePart = -1;
d977 1
a977 1
					   &font, controlTitle);
d986 1
a986 1
                  controlTitle, kCFStringEncodingUTF8);
@


1.10
log
@fix to MacOSX compound button layout
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.9 2004/02/18 00:40:24 hobbs Exp $
a199 3
    int x = 0;                  /* Initialization only needed to stop
                                 * compiler warning. */
    int y;
d234 2
a235 1
     * set up clipping region 
d238 2
d242 1
a265 7
        /*
         * This part uses Macintosh rather than Tk calls to draw
         * to the screen.  Make sure the ports etc. are set correctly.
         */
         
        destPort = TkMacOSXGetDrawablePort(pixmap);
        SetGWorld(destPort, NULL);
d301 2
d410 3
d450 3
a452 1
            } else {
d456 3
a458 6
                        butPtr->textHeight, &x, &y);
                
                x += butPtr->indicatorSpace;
                
                if (macButtonPtr->useTkText) {
                    Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc,
a459 2
                }
                y += butPtr->textHeight/2;
d1057 1
a1058 1
        ShowControl(mbPtr->userPane);
d1061 1
a1062 1
        SetControlVisibility(mbPtr->control, true, true);
@


1.9
log
@	* doc/checkbutton.n: TIP#110 implementation
	* doc/radiobutton.n: Tristate Checkbutton and Radiobuttons
	* generic/tkButton.c:
	* generic/tkButton.h:
	* library/demos/check.tcl:
	* library/demos/radio.tcl:
	* macosx/tkMacOSXButton.c:
	* macosx/tkMacOSXDefault.h:
	* tests/button.test:
	* unix/tkUnixButton.c:
	* unix/tkUnixDefault.h:
	* win/tkWinButton.c:
	* win/tkWinDefault.h:
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.7 2003/10/10 20:19:51 hobbs Exp $
d979 9
a987 3
        len = TkFontGetFirstTextLayout(butPtr->textLayout, 
                &font, controlTitle);
        controlTitle[len] = 0;
@


1.8
log
@Fix a bug in tk_getOpenFile - files with no types are rejected when they would
pass in Mac OS Classic.
Add the tkMacOSXCarbonEvents.c - just a skeleton right now.
A bunch of formatting nits fixed.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id$
d385 4
d434 4
d833 4
a836 5
    initialValue = kControlSupportsEmbedding|   
        kControlHasSpecialBackground;
    minValue = 0;
    maxValue = 1;
    procID = kControlUserPaneProc;
d838 1
a838 1
    mbPtr->userPane = NewControl(mbPtr->windowRef,
d852 1
a852 1
    if ((status=EmbedControl(mbPtr->userPane,rootControl)) != noErr) {
d919 2
d924 3
a926 3
    paneRect.left = winPtr->privatePtr->xOff;
    paneRect.top = winPtr->privatePtr->yOff;
    paneRect.right = paneRect.left + Tk_Width(butPtr->tkwin);
d932 3
a934 3
    cntrRect.left += butPtr->inset;
    cntrRect.top += butPtr->inset;
    cntrRect.right -= butPtr->inset;
d937 3
a939 3
    cntrRect.left += DEF_INSET_LEFT;
    cntrRect.top += DEF_INSET_TOP;
    cntrRect.right -= DEF_INSET_RIGHT;
d1011 2
d1139 3
d1157 1
a1157 1
            (char *) &mbPtr->bevelButtonContent)) != noErr ) {
d1185 1
a1185 1
            (char *) &theAlignment)) != noErr ) {
d1205 1
a1205 1
                (char *) &thePlacement)) != noErr ) {
d1466 1
a1466 1
                paramsPtr->maxValue = 1;
d1473 1
a1473 1
                paramsPtr->maxValue = 1;
d1490 1
a1490 1
                paramsPtr->maxValue = 1;
d1497 1
a1497 1
                paramsPtr->maxValue = 1;
@


1.7
log
@	* mac/tkMacButton.c (TkpDisplayButton):
	* macosx/tkMacOSXButton.c (TkpDisplayButton):
	* unix/tkUnixButton.c (TkpDisplayButton): correct imageYOffset for
	buttons with just images.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.6 2003/09/30 23:26:09 wolfsuit Exp $
d152 10
a161 10
    macButtonPtr->id=bCount++;
    macButtonPtr->usingControl=0;
    macButtonPtr->flags=0;
    macButtonPtr->userPaneBackground.red=0;
    macButtonPtr->userPaneBackground.green=0;
    macButtonPtr->userPaneBackground.blue=~0;
    macButtonPtr->userPane=NULL;
    macButtonPtr->control=NULL;
    macButtonPtr->controlTitle[0]=
    macButtonPtr->controlTitle[1]=0;
d225 1
a225 1
        macButtonPtr->usingControl=1;
d232 2
a233 2
        macButtonPtr->usingControl=0;
        macButtonPtr->useTkText=1;
d824 2
a825 2
    initiallyVisible=false;
    initialValue=kControlSupportsEmbedding|   
d827 5
a831 5
    minValue=0;
    maxValue=1;
    procID=kControlUserPaneProc;
    controlReference=(SInt32)mbPtr;
    mbPtr->userPane=NewControl(mbPtr->windowRef,
d845 1
a845 1
    if ((status=EmbedControl(mbPtr->userPane,rootControl))!=noErr) {
d853 1
a853 1
    initiallyVisible=false;
d855 1
a855 1
    mbPtr->control=NewControl(mbPtr->windowRef,
d874 1
a874 1
    mbPtr->flags|=(1 + 2);
a911 1
    int        hilitePart = -1;
d913 1
a913 2

    winPtr=(TkWindow *)butPtr->tkwin;
d920 1
a920 1
    cntrRect=paneRect;
d923 4
a926 4
    cntrRect.left+=butPtr->inset;
    cntrRect.top+=butPtr->inset;
    cntrRect.right-=butPtr->inset;
    cntrRect.bottom-=butPtr->inset;
d928 4
a931 4
    cntrRect.left+=DEF_INSET_LEFT;
    cntrRect.top+=DEF_INSET_TOP;
    cntrRect.right-=DEF_INSET_RIGHT;
    cntrRect.bottom-=DEF_INSET_BOTTOM;
d1140 1
a1140 1
    if ( (err=SetControlData(controlHandle, kControlButtonPart,
d1168 1
a1168 1
    if ((err=SetControlData(controlHandle, kControlButtonPart,
d1188 1
a1188 1
        if ((err=SetControlData(controlHandle, kControlButtonPart,
@


1.6
log
@Add an implementation of XSync that flushes the window buffers.  This fixes 814810.
Also use tk text drawing for checkbutton & radiobutton labels.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id$
d424 1
a424 1
		imageXOffset += y;
d429 1
a429 1
                                height, pixmap, x, y);
d432 1
a432 1
                                pixmap, x, y);
@


1.5
log
@	* library/demos/widget: don't create iconwindow on aqua, but add
	about menu like on classic.
	* macosx/Makefile: pass MAKEOVERRIDES to pxbuild.
	* macosx/tkMacOSXButton.c: added -compound support for bevel buttons.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.4 2003/04/30 16:16:39 hobbs Exp $
d226 5
a230 1
        macButtonPtr->useTkText=DEFAULT_USE_TK_TEXT;
@


1.4
log
@	* macosx/tkMacOSXButton.c (TkpDisplayButton): correct typo for
	stippleGC [Bug #730124].
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.3 2003/04/26 02:59:20 hobbs Exp $
d1174 20
@


1.3
log
@	* generic/tkButton.h:                         Rewrote the handling
	* generic/tkButton.c (TkButtonWorldChanged):  of compound *buttons
	* mac/tkMacButton.c (TkpDisplayButton):       to correctly display
	* macosx/tkMacOSXButton.c (TkpDisplayButton): mixture of disabledfg,
	* unix/tkUnixButton.c (TkpDisplayButton):     selectcolor, indicator,
	* win/tkWinButton.c (TkpDisplayButton):       etc.  *buttons will
	now only stipple the image, unless no disabledfg is given, in which
	case it will stipple the whole button.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.2.2.1 2003/04/26 02:53:47 hobbs Exp $
d468 1
a468 1
                XSetForeground(butPtr->display, butPtr->stippledGC,
d486 1
a486 1
		XSetForeground(butPtr->display, butPtr->stippledGC,
@


1.2
log
@	*** macosx-8-4-branch merged into the mainline [tcl patch #602770] ***

	* generic/tk.decls:
	* generic/tkInt.decls: added new "aqua" specific entries to the
	stubs tables. Changed all "unix" entries to "x11" to allow us to
	distinguish and build both "aqua" on MacOSX and "x11" on MacOSX.

	* generic/tk.h: added a #ifnded RESOURCE_INCLUDED so that tk.h can
	be passed to the resource compiler.

	* generic/tkCmds.c (Tk_TkObjCmd): added [tk windowingsystem]
	subcommand: returns "x11" when running on X11, "win32" on Windows,
	"classic" on MacOS9 and "aqua" on MacOSX Aqua (i.e. Carbon)

	* generic/tkFont.c (TkFontGetFirstTextLayout): new private function
	returning the first chunk of a Tk_TextLayout, i.e. until the first
	font change on the first line (or the whole first line if there is
	no such font change).

	* generic/tkMain.c: made Tcl_ThreadDataKey static

	* library/demos/puzzle.tcl: fixed button metrics for aqua

	* tests/cursor.test: check for presence of arrow cursor instead of
	heart cursor

	* xlib/xcolors.c: changed xColors static initialization to more
	standard C

	* macosx/Wish.pbproj/jingham.pbxuser (new):
	* macosx/Wish.pbproj/project.pbxproj (new): project for Apple's
	ProjectBuilder IDE.

	* macosx/Makefile (new): simple makefile for building the project
	from the command line via the ProjectBuilder tool 'pbxbuild'.

	* macosx/tkMacOSXAppInit.c (new): macosx specific AppInit looking
	for a AppMain.tcl file in its bundled Resources/Scripts folder. If
	present, argv[1] is set to that file and the Scripts folder is
	added to the auto_path. This allows tk apps to embed scripts within
	their bundle directory structure.

	* macosx/tkMacOSXInit.c (new): macosx adapted version of
	tkUnixInit.c: we initialize & cache the Carbon native encoding
	(e.g. 'macRoman') and try to find the tk script library files
	inside Tk packaged as a framework.

	* macosx/tkMacOSXNotify.c (new): new macosx specific merged
	Carbon/select-based notifier.

	* macosx/tkMacOSXEvent.c (new):
	* macosx/tkMacOSXEvent.h (new):
	* macosx/tkMacOSXKeyEvent.c (new):
	* macosx/tkMacOSXMouseEvent.c (new):
	* macosx/tkMacOSXWindowEvent.c (new): new macosx specific event
	handling functionality.

	* macosx/tkMacOSX.h (new):
	* macosx/tkMacOSXBitmap.c (new):
	* macosx/tkMacOSXButton.c (new):
	* macosx/tkMacOSXClipboard.c (new):
	* macosx/tkMacOSXColor.c (new):
	* macosx/tkMacOSXConfig.c (new):
	* macosx/tkMacOSXCursor.c (new):
	* macosx/tkMacOSXDefault.h (new):
	* macosx/tkMacOSXDialog.c (new):
	* macosx/tkMacOSXDraw.c (new):
	* macosx/tkMacOSXEmbed.c (new):
	* macosx/tkMacOSXFont.c (new):
	* macosx/tkMacOSXHLEvents.c (new):
	* macosx/tkMacOSXInt.h (new):
	* macosx/tkMacOSXKeyboard.c (new):
	* macosx/tkMacOSXMenu.c (new):
	* macosx/tkMacOSXMenubutton.c (new):
	* macosx/tkMacOSXMenus.c (new):
	* macosx/tkMacOSXPort.h (new):
	* macosx/tkMacOSXRegion.c (new):
	* macosx/tkMacOSXScale.c (new):
	* macosx/tkMacOSXScrlbr.c (new):
	* macosx/tkMacOSXSubwindows.c (new):
	* macosx/tkMacOSXTest.c (new):
	* macosx/tkMacOSXUtil.c (new):
	* macosx/tkMacOSXUtil.h (new):
	* macosx/tkMacOSXWm.c (new):
	* macosx/tkMacOSXWm.h (new):
	* macosx/tkMacOSXXStubs.c (new): macosx ports of classic mac Tk
	implementation in tk/mac.

	* macosx/tkMacOSXSend.c (new): only send to local interp
	implemented currently.

	* macosx/tkMacOSXDebug.h (new):
	* macosx/tkMacOSXDebug.c (new): new macosx specific functions for
	debugging MacOS events, regions, etc.

	* macosx/tkAboutDlg.r (new):
	* macosx/tkMacOSXApplication.r (new):
	* macosx/tkMacOSXCursors.r (new):
	* macosx/tkMacOSXLibrary.r (new):
	* macosx/tkMacOSXMenu.r (new):
	* macosx/tkMacOSXResource.r (new):
	* macosx/tkMacOSXXCursors.r (new):
	* macosx/tclets.r (new): sources for Rez resource compiler.

	* macosx/Wish.icns (new): Wish application icon.

	* generic/tk.h:
	* generic/default.h:
	* generic/tkBind.c:
	* generic/tkCmds.c:
	* generic/tkGrab.c:
	* generic/tkPointer.c:
	* generic/tkPort.h:
	* generic/tkSelect.c:
	* generic/tkStubLib.c:
	* generic/tkTest.c:
	* generic/tkText.c:
	* generic/tkWindow.c:
	* unix/tkUnix3d.c:
	* xlib/xgc.c:
	* xlib/X11/X.h:
	* xlib/X11/Xlib.h:
	* xlib/X11/Xutil.h: added #includes and #ifdefs for macosx

	* library/bgerror.tcl:
	* library/button.tcl:
	* library/console.tcl:
	* library/dialog.tcl:
	* library/entry.tcl:
	* library/listbox.tcl:
	* library/menu.tcl:
	* library/msgbox.tcl:
	* library/scrlbar.tcl:
	* library/spinbox.tcl:
	* library/text.tcl:
	* library/tk.tcl:
	* library/demos/menu.tcl:
	* library/demos/menubu.tcl:
	* library/demos/widget: check [tk windowingsystem] instead of
	and/or in addition to $tcl_platform(platform).

	* generic/tkInt.h:
	* mac/tkMacBitmap.c:
	* mac/tkMacWm.c: added missing CONSTification

	* generic/tkIntDecls.h:
	* generic/tkIntPlatDecls.h:
	* generic/tkIntXlibDecls.h:
	* generic/tkPlatDecls.h:
	* generic/tkStubInit.c: regen
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id$
d36 4
a39 4
#define DRAW_LABEL        0                /* Labels are treated genericly. */
#define DRAW_CONTROL        1                /* Draw using the Native control. */
#define DRAW_CUSTOM        2                /* Make our own button drawing. */
#define DRAW_BEVEL        3
d50 1
a50 1
    int    isBevel;
d57 5
a61 5
    int offset;                        /* 0 means this is a normal widget.  1 means
                                 * it is an image button, so we offset the
                                 * image to make the button appear to move
                                 * up and down as the relief changes. */
    GC  gc;
d204 1
a204 1
    int imageXOffset, imageYOffset, textXOffset, textYOffset;
d210 4
d298 3
a302 2
            imageXOffset = 0;
            imageYOffset = 0;
d374 2
a375 1
            
d380 1
a380 2
                            width, height, pixmap, x + imageXOffset,
                            y + imageYOffset);
d383 1
a383 2
                            height, pixmap, x + imageXOffset,
                            y + imageYOffset);
d386 2
a387 2
                XSetClipOrigin(butPtr->display, dpPtr->gc, x + imageXOffset,
                        y + imageYOffset);
d389 2
a390 3
                        0, 0, (unsigned int) width,
                        (unsigned int) height, x + imageXOffset,
                        y + imageYOffset, 1);
d393 2
a394 2
            
            if (macButtonPtr->useTkText ) {
d409 1
a409 1
                
d419 2
d425 1
a425 1
                                height,        pixmap, x, y);
a430 1

d460 1
a460 1
     * must temporarily modify the GC.
d467 3
a469 3
                && (butPtr->selectBorder != NULL)) {
                XSetForeground(butPtr->display, butPtr->disabledGC,
                Tk_3DBorderColor(butPtr->selectBorder)->pixel);
d471 13
a483 4
                XFillRectangle(butPtr->display, pixmap, butPtr->disabledGC,
                butPtr->inset, butPtr->inset,
                (unsigned) (Tk_Width(tkwin) - 2*butPtr->inset),
                (unsigned) (Tk_Height(tkwin) - 2*butPtr->inset));
d485 4
a488 4
                && (butPtr->selectBorder != NULL)) {
                    XSetForeground(butPtr->display, butPtr->disabledGC,
                    Tk_3DBorderColor(butPtr->normalBorder)->pixel);
                }
d490 1
a490 1
        
@


1.2.2.1
log
@	* generic/tkButton.h:                         Rewrote the handling
	* generic/tkButton.c (TkButtonWorldChanged):  of compound *buttons
	* mac/tkMacButton.c (TkpDisplayButton):       to correctly display
	* macosx/tkMacOSXButton.c (TkpDisplayButton): mixture of disabledfg,
	* unix/tkUnixButton.c (TkpDisplayButton):     selectcolor, indicator,
	* win/tkWinButton.c (TkpDisplayButton):       etc.  *buttons will
	now only stipple the image, unless no disabledfg is given, in which
	case it will stipple the whole button.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.2 2002/08/31 06:12:29 das Exp $
d36 4
a39 4
#define DRAW_LABEL	0	/* Labels are treated genericly. */
#define DRAW_CONTROL	1	/* Draw using the Native control. */
#define DRAW_CUSTOM	2	/* Make our own button drawing. */
#define DRAW_BEVEL	3
d50 1
a50 1
    int	   isBevel;
d57 5
a61 5
    int offset;			/* 0 means this is a normal widget.  1 means
				 * it is an image button, so we offset the
				 * image to make the button appear to move
				 * up and down as the relief changes. */
    GC	gc;
d204 1
a204 1
    int textXOffset, textYOffset;
a209 4
    int imageWidth, imageHeight;
    int imageXOffset = 0, imageYOffset = 0; /* image information that will
					     * be used to restrict disabled
					     * pixmap as well */
a293 3
	imageWidth  = width;
	imageHeight = height;

d296 2
d369 1
a369 2
	    imageXOffset += x;
	    imageYOffset += y;
d374 2
a375 1
                            width, height, pixmap, imageXOffset, imageYOffset);
d378 2
a379 1
                            height, pixmap, imageXOffset, imageYOffset);
d382 2
a383 2
                XSetClipOrigin(butPtr->display, dpPtr->gc,
			imageXOffset, imageYOffset);
d385 3
a387 2
                        0, 0, (unsigned int) width, (unsigned int) height,
			imageXOffset, imageYOffset, 1);
d390 2
a391 2

            if (macButtonPtr->useTkText) {
d406 1
a406 1

a415 2
		imageXOffset += x;
		imageXOffset += y;
d420 1
a420 1
                                height, pixmap, x, y);
d426 1
d456 1
a456 1
     * must temporarily modify the GC so the stippling is the right color.
d463 3
a465 3
		    && (butPtr->selectBorder != NULL)) {
                XSetForeground(butPtr->display, butPtr->stippledGC,
			Tk_3DBorderColor(butPtr->selectBorder)->pixel);
d467 4
a470 13
	    /*
	     * 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);
	    }
d472 4
a475 4
		    && (butPtr->selectBorder != NULL)) {
		XSetForeground(butPtr->display, butPtr->stippledGC,
			Tk_3DBorderColor(butPtr->normalBorder)->pixel);
	    }
d477 1
a477 1

@


1.2.2.2
log
@	* macosx/tkMacOSXButton.c (TkpDisplayButton): correct typo for
	stippleGC [Bug #730124].
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.4 2003/04/30 16:16:39 hobbs Exp $
d468 1
a468 1
                XSetForeground(butPtr->display, butPtr->stippleGC,
d486 1
a486 1
		XSetForeground(butPtr->display, butPtr->stippleGC,
@


1.2.2.3
log
@	* library/demos/widget: don't create iconwindow on aqua, but add
	about menu like on classic.
	* macosx/Makefile: pass MAKEOVERRIDES to pxbuild.
	* macosx/tkMacOSXButton.c: added -compound support for bevel buttons.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.2.2.2 2003/04/30 16:19:07 hobbs Exp $
a1173 20
    if (butPtr->compound != COMPOUND_NONE) {
        ControlButtonTextPlacement thePlacement = \
                kControlBevelButtonPlaceNormally;
        if (butPtr->compound == COMPOUND_TOP) {
            thePlacement = kControlBevelButtonPlaceBelowGraphic;
        } else if (butPtr->compound == COMPOUND_BOTTOM) {
            thePlacement = kControlBevelButtonPlaceAboveGraphic;
        } else if (butPtr->compound == COMPOUND_LEFT) {
            thePlacement = kControlBevelButtonPlaceToRightOfGraphic;
        } else if (butPtr->compound == COMPOUND_RIGHT) {
            thePlacement = kControlBevelButtonPlaceToLeftOfGraphic;
        }
        if ((err=SetControlData(controlHandle, kControlButtonPart,
                kControlBevelButtonTextPlaceTag,
                sizeof(ControlButtonTextPlacement),
                (char *) &thePlacement)) != noErr ) {
            fprintf(stderr,
                    "SetControlData BevelButtonTextPlace failed, %d\n", err );
        }
    }
@


1.2.2.4
log
@	* mac/tkMacButton.c (TkpDisplayButton):
	* macosx/tkMacOSXButton.c (TkpDisplayButton):
	* unix/tkUnixButton.c (TkpDisplayButton): correct imageYOffset for
	buttons with just images.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.2.2.3 2003/09/25 05:37:48 das Exp $
d420 1
a420 1
		imageYOffset += y;
d425 1
a425 1
                                height, pixmap, imageXOffset, imageYOffset);
d428 1
a428 1
                                pixmap, imageXOffset, imageYOffset);
@


1.2.2.5
log
@Backport Mac OS X specific fixes from TOT. See ChangeLog for details.

In tk_getOpenFile filters, handle the case where you have a Macintosh
file type and the files have no filetype.

Fix various formatting nits.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id$
d152 10
a161 10
    macButtonPtr->id = bCount++;
    macButtonPtr->usingControl = 0;
    macButtonPtr->flags = 0;
    macButtonPtr->userPaneBackground.red = 0;
    macButtonPtr->userPaneBackground.green = 0;
    macButtonPtr->userPaneBackground.blue = ~0;
    macButtonPtr->userPane = NULL;
    macButtonPtr->control = NULL;
    macButtonPtr->controlTitle[0] = 0;
    macButtonPtr->controlTitle[1] = 0;
d225 2
a226 6
        macButtonPtr->usingControl = 1;
        if (butPtr->type == TYPE_BUTTON) {
            macButtonPtr->useTkText = 0;
        } else {
            macButtonPtr->useTkText = 1;
        }
d228 2
a229 2
        macButtonPtr->usingControl = 0;
        macButtonPtr->useTkText = 1;
d820 2
a821 2
    initiallyVisible = false;
    initialValue = kControlSupportsEmbedding|   
d823 5
a827 5
    minValue = 0;
    maxValue = 1;
    procID = kControlUserPaneProc;
    controlReference = (SInt32)mbPtr;
    mbPtr->userPane = NewControl(mbPtr->windowRef,
d841 1
a841 1
    if ((status=EmbedControl(mbPtr->userPane,rootControl)) != noErr) {
d849 1
a849 1
    initiallyVisible = false;
d851 1
a851 1
    mbPtr->control = NewControl(mbPtr->windowRef,
d870 1
a870 1
    mbPtr->flags |= (1 + 2);
d908 2
d911 1
a911 1
    winPtr = (TkWindow *)butPtr->tkwin;
d918 1
a918 1
    cntrRect = paneRect;
d921 4
a924 4
    cntrRect.left += butPtr->inset;
    cntrRect.top += butPtr->inset;
    cntrRect.right -= butPtr->inset;
    cntrRect.bottom -= butPtr->inset;
d926 4
a929 4
    cntrRect.left += DEF_INSET_LEFT;
    cntrRect.top += DEF_INSET_TOP;
    cntrRect.right -= DEF_INSET_RIGHT;
    cntrRect.bottom -= DEF_INSET_BOTTOM;
d1138 1
a1138 1
    if ((err = SetControlData(controlHandle, kControlButtonPart,
d1166 1
a1166 1
    if ((err = SetControlData(controlHandle, kControlButtonPart,
d1186 1
a1186 1
        if ((err = SetControlData(controlHandle, kControlButtonPart,
@


1.2.2.6
log
@Fix for 1055023 from mikek@@muonics.com.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.2.2.5 2004/02/16 00:42:34 wolfsuit Exp $
d312 1
a312 1
            switch ((enum compound) butPtr->compound)
d327 1
d329 1
a329 1
                case COMPOUND_RIGHT:
d345 2
a346 1
                case COMPOUND_CENTER:
d360 2
a361 2
                case COMPOUND_NONE:
		  break;
d970 3
a972 9
        if (((mbPtr->info.image == NULL) && (mbPtr->info.bitmap == None))
               || (mbPtr->info.compound != COMPOUND_NONE)) {
            len = TkFontGetFirstTextLayout(butPtr->textLayout, 
                    &font, controlTitle);
            controlTitle[len] = 0;
        } else {
            len = 0;
            controlTitle[0] = 0;
        }
@


1.2.2.7
log
@	* generic/tkMain.c:
	* macosx/tkMacOSXAppInit.c (removed):
	* macosx/Wish.pbproj/project.pbxproj:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXInt.h: changes to make TkAqua dynamically loadable,
	enabling [package require Tk] from tclsh. Startup code from
	tkMacOSXAppInit.c moved into tkMacOSXInit.c, added code that
	notifies the window server that an unbundled executable is a full
	GUI application after loading Tk. [Patch 1035348]

	* doc/wm.n: documented [wm attributes] on Mac OS X. [Bug 606665]
	* macosx/tkMacOSXWm.c: implemented TIP 222 [wm attributes -alpha] on
	Mac OS X. [Patch 892194]
	WmIconbitmapCmd: adopted FSRef changes from [wm atttrs -titlepath].

	* macosx/tkMacOSXButton.c:
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXRegion.c:
	* macosx/tkMacOSXSubwindows.c: synced spacing/formatting with HEAD.

	* macosx/tkMacOSXMouseEvent.c: endianness fixes.

	* macosx/Wish.pbproj/project.pbxproj: corrected path to html help
	inside framework.

	* macosx/Makefile: prevent parallel make from building several
	targets at the same time.
	Ensure that xcodebuild will use Wish.pbproj project even if a .xcode
	project is also present.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.2.2.6 2004/11/10 17:29:45 wolfsuit Exp $
d312 1
a312 1
            switch ((enum compound) butPtr->compound) {
a326 1
                }
d328 1
a328 1
                case COMPOUND_RIGHT: {
d344 1
a344 2
                }
                case COMPOUND_CENTER: {
d358 2
a359 2
                }
                case COMPOUND_NONE: {break;}
d823 5
a827 4
    initialValue     = kControlSupportsEmbedding|kControlHasSpecialBackground;
    minValue         = 0;
    maxValue         = 1;
    procID           = kControlUserPaneProc;
d829 1
a829 1
    mbPtr->userPane  = NewControl(mbPtr->windowRef,
d843 1
a843 1
    if ((status = EmbedControl(mbPtr->userPane,rootControl)) != noErr) {
d913 3
a915 3
    paneRect.left   = winPtr->privatePtr->xOff;
    paneRect.top    = winPtr->privatePtr->yOff;
    paneRect.right  = paneRect.left + Tk_Width(butPtr->tkwin);
d921 3
a923 3
    cntrRect.left   += butPtr->inset;
    cntrRect.top    += butPtr->inset;
    cntrRect.right  -= butPtr->inset;
d926 3
a928 3
    cntrRect.left   += DEF_INSET_LEFT;
    cntrRect.top    += DEF_INSET_TOP;
    cntrRect.right  -= DEF_INSET_RIGHT;
d1147 1
a1147 1
            (char *) &mbPtr->bevelButtonContent)) != noErr) {
d1175 1
a1175 1
            (char *) &theAlignment)) != noErr) {
d1195 1
a1195 1
                (char *) &thePlacement)) != noErr) {
@


1.2.2.8
log
@Fix for 1124237 and the mysterious "sometimes buttons don't draw" bug.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.2.2.7 2004/11/11 01:26:42 das Exp $
d200 3
d237 1
a237 2
     * set up clipping region.  Make sure the we are using the port
     * for this button, or we will set the wrong window's clip. 
a239 2
    destPort = TkMacOSXGetDrawablePort(pixmap);
    SetGWorld(destPort, NULL);
a241 1

d265 7
a306 2
            int x;
            int y;
a409 3
                int x = 0;
                int y;

d443 1
a443 3
            } else if (macButtonPtr->useTkText) {
                int x = 0;
                int y;
d447 6
a452 3
                        butPtr->textHeight, &x, &y);                
                x += butPtr->indicatorSpace;                
                Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc,
d454 2
d1049 1
a1050 1
        ShowControl(mbPtr->control);
d1053 1
a1054 1
        Draw1Control(mbPtr->userPane);
@


1.2.2.9
log
@	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXNotify.c: introduction of new tcl notifier based on
	CFRunLoop allows replacement of the custom TkAqua notifier by a
	standard tcl event source. Removes requirement of threaded tcl core
	for TkAqua, allows to stub-link TkAqua against Tcl by removing use of
	the unstubbed TclInitNotifier & TclFinalizeNotifier. [Tcl Patch 1202052]

	* macosx/Wish.pbproj/project.pbxproj: stub-link TkAqua: build with
	USE_TCL_STUBS and link against libtclstub instead of Tcl.framework,
	unexport libtclstub symbols from Tk to avoid duplicate symbol warnings
	when linking with both Tcl and Tk, fixes for gcc4.0 warnings.

	* macosx/tkMacOSXBitmap.c:
	* macosx/tkMacOSXButton.c:
	* macosx/tkMacOSXDialog.c:
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXHLEvents.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXKeyboard.c:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXXStubs.c: fixed gcc 4.0 warnings.

	* unix/tcl.m4: sync with tcl
	* unix/configure: autoconf-2.13
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.2.2.8 2005/03/12 00:49:28 wolfsuit Exp $
d968 1
a968 1
                    &font, (char*) controlTitle);
d977 1
a977 1
                  (char*) controlTitle, kCFStringEncodingUTF8);
@


1.2.2.10
log
@	* macosx/tkMacOSXButton.c:
	* macosx/tkMacOSXDialog.c: fix warnings.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.2.2.9 2005/05/14 20:53:31 das Exp $
d207 1
a207 1
    int imageWidth = 0, imageHeight = 0;
@


1.2.2.11
log
@	* macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent): check if
	process is in front on MouseDown, otherwise request process activation
	from BringWindowForward() via new isFrontProcess param.

	* macosx/tkMacOSXCarbonEvents.c (TkMacOSXInitCarbonEvents): register our
	event handler on the dispatcher target for all carbon events of interest
	to TkAqua; this replaces event processing directly from the event queue
	and thus allows to capture events that are syntesized by Carbon and sent
	directly to the dispatcher and not to the event queue.

	* macosx/tkMacOSXEvent.c: remove TkMacOSXCountAndProcessMacEvents(),
	rename ReceiveAndProcessEvent() to TkMacOSXReceiveAndProcessEvent().
	(TkMacOSXReceiveAndProcessEvent): remove tk event processing before
	sending events to the dispatcher, all events of interest are now
	processed in our dispatcher target event handler.

	* macosx/tkMacOSXNotify.c (CarbonEventsCheckProc): dispatch events
	directly via TkMacOSXReceiveAndProcessEvent(), but dispatch no more than
	four carbon events at one time to avoid starving other event sources.

	* macosx/tkMacOSXEvent.c: formatting cleanup, move XSync() to XStubs,
	* macosx/tkMacOSXEvent.h: removed obsolete kEventClassWish handling.
	* macosx/tkMacOSXXStubs.c

	* macosx/tkMacOSXButton.c: conditionalize all debug message printing to
	* macosx/tkMacOSXCursor.c: stderr via TK_MAC_DEBUG define.
	* macosx/tkMacOSXDebug.c:
	* macosx/tkMacOSXDebug.h:
	* macosx/tkMacOSXDialog.c:
	* macosx/tkMacOSXEvent.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:

	* unix/configure.in: define TK_MAC_DEBUG on aqua when symbols enabled.
	* unix/configure: autoconf-2.13

	* library/listbox.tcl: corrected comments.
	* library/text.tcl:

	* xlib/xcolors.c: fixed warning
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.2.2.10 2005/08/22 11:55:15 das Exp $
a835 1
#ifdef TK_MAC_DEBUG
a836 1
#endif
a840 1
#ifdef TK_MAC_DEBUG
a841 1
#endif
a859 1
#ifdef TK_MAC_DEBUG
a860 1
#endif
a864 1
#ifdef TK_MAC_DEBUG
a865 1
#endif
a987 1
#ifdef TK_MAC_DEBUG
a988 1
#endif
a1115 1
#ifdef TK_MAC_DEBUG
a1116 1
#endif
a1144 1
#ifdef TK_MAC_DEBUG
a1146 1
#endif
a1172 1
#ifdef TK_MAC_DEBUG
a1174 1
#endif
a1192 1
#ifdef TK_MAC_DEBUG
a1194 1
#endif
@


1.2.2.12
log
@	* unix/tcl.m4 (Darwin): add 64bit support, check for Tiger copyfile(),
	add CFLAGS to SHLIB_LD to support passing -isysroot in env(CFLAGS) to
	configure (flag can't be present twice, so can't be in both CFLAGS and
	LDFLAGS during configure), don't use -prebind when deploying on 10.4,
	define TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING (rdar://3171542).
	(SC_ENABLE_LANGINFO, SC_TIME_HANDLER): add/fix caching, fix obsolete
	autoconf macros. Sync with tk/unix/tcl.m4, sync whitespace with HEAD.

	* unix/configure.in: fix obsolete autoconf macros, sync gratuitous
	formatting/ordering differences with tcl/unix/configure.in.

	* unix/Makefile.in: add CFLAGS to wish/tktest link to make executable
	linking the same as during configure (needed to avoid loosing any linker
	relevant flags in CFLAGS, in particular flags that can't be in LDFLAGS).
	Avoid concurrent linking of wish and compiling of tkTestInit.o during
	parallel make, fix dependencies and flags for building tkMacOSXInit.o
	(checkstubs, checkexports): dependency and Darwin fixes

	* macosx/tkMacOSXEvent.c (TkMacOSXProcessEvent):
	* macosx/tkMacOSXEvent.h:
	* macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent):
	* macosx/tkMacOSXCarbonEvents.c: install standard application event
	handler, add & call functions to start and stop carbon even timer that
	runs the tcl event loop periodically during a nested carbon event loop
	in the toolbox (e.g. during menutracking) to ensure tcl timers etc
	continue to fire, register app event handler for menu tracking and HI
	command carbon events, move menu event handling to new handlers for
	those carbon events, no longer register for/handle appleevent carbon
	event (now dealt with by standard application event handler), event
	debugging code dynamically acquires carbon event debugging functions to
	allow use on Tiger where they are no longer exported from HIToolbox.

	* macosx/tkMacOSXFont.c (TkMacOSXUseAntialiasedText):
	* macosx/tkMacOSXKeyEvent.c (GetKeyboardLayout):
	* macosx/tkMacOSXCarbonEvents.c (TkMacOSXInitCarbonEvents):
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXInt.h: abstract common code to dynamically acquire
	address of a named symbol (from a loaded dynamic library) into new
	function TkMacOSXGetNamedSymbol() and macro TkMacOSXInitNamedSymbol.

	* macosx/tkMacOSXMenu.c (TkpNewMenu):
	* macosx/tkMacOSXMenubutton.c (MenuButtonInitControl):
	* macosx/tkMacOSXMenus.c (TkMacOSXHandleMenuSelect): switch to  modern
	utf8 aware menu manager API, remove obsolete code, add error handling.

	* macosx/tkMacOSXMouseEvent.c: define OSX 10.3 or later only constants
	if necessary to allow compilation on OSX 10.2

	* macosx/tkMacOSXWm.c (UpdateSizeHints): remove code that is never
	executed.

	* generic/tk.h: add/correct location of version numbers in macosx files.

	* generic/tkInt.h: clarify fat compile comment.

	* macosx/Wish.pbproj/default.pbxuser (new file):
	* macosx/Wish.pbproj/jingham.pbxuser:
	* macosx/Wish.pbproj/project.pbxproj: sync with HEAD.

	* macosx/buildTkConfig.tcl (removed): remove obsolete build files.

	* macosx/README: clarification/cleanup, sync with HEAD, document
	universal (fat) builds via CFLAGS (i.e. ppc and i386 at the same time).

	* macosx/Makefile: add support for reusing configure cache, build target
	fixes.

	* generic/tkMenu.c:
	* macosx/tkMacOSXButton.c:
	* macosx/tkMacOSXDebug.c:
	* macosx/tkMacOSXDebug.h:
	* macosx/tkMacOSXDialog.c:
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXEntry.c:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXXStubs.c:
	* macosx/tkMacOSXSubwindows.c:
	* xlib/xgc.c: declare functions and globals used only in own file as
	static, #ifdef out a few Xlib and aqua functions that are never called
	(sync with HEAD).

	* macosx/tkMacOSXPort.h:
	* generic/tkInt.decls: correct signature of TkMacOSXHandleMenuSelect,
	add XSync to aqua Xlib stubs.

	* generic/tkTest.c: #ifdef unix only declarations.
	(TestmetricsCmd): unify win and mac implementation.

	* generic/tkTextDisp.c:
	* generic/tkTextBTree.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXXStubs.c: fix gcc 4 warnings.

	* macosx/tkMacOSXNotify.c:
	* macosx/tkMacOSXTest.c: sync with HEAD.

	* generic/tkIntPlatDecls.h:
	* generic/tkIntXlibDecls.h:
	* generic/tkStubInit.c:
	* unix/configure: regen.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.2.2.11 2005/09/10 14:54:17 das Exp $
d792 1
a792 1
static int
@


1.2.2.13
log
@	* macosx/tkMacOSX.h:             Cleaned up & rationalized order of
	* macosx/tkMacOSXBitmap.c:       #includes of tk and carbon headers;
	* macosx/tkMacOSXButton.c:       sync whitespace, comments & minor
	* macosx/tkMacOSXCarbonEvents.c: changes with HEAD.
	* macosx/tkMacOSXClipboard.c:
	* macosx/tkMacOSXColor.c:
	* macosx/tkMacOSXConfig.c:
	* macosx/tkMacOSXCursor.c:
	* macosx/tkMacOSXDialog.c:
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXEmbed.c:
	* macosx/tkMacOSXEntry.c:
	* macosx/tkMacOSXEvent.c:
	* macosx/tkMacOSXEvent.h:
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXFont.h (new file):
	* macosx/tkMacOSXHLEvents.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXInt.h:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXKeyboard.c:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXNotify.c:
	* macosx/tkMacOSXRegion.c:
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXSend.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXTest.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXWm.h:
	* macosx/tkMacOSXXStubs.c:
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.2.2.12 2005/11/27 02:36:46 das Exp $
d16 1
a17 2
#include "tkButton.h"
#include "tkMacOSXFont.h"
d30 2
d112 3
@


1.2.2.14
log
@	* macosx/tkMacOSXButton.c (TkMacOSXDrawControl): correct redraw
	for direct transition from disabled to active state. [Bug 706446]
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.2.2.13 2006/03/28 02:44:12 das Exp $
d1012 1
a1012 1

d1014 17
a1030 1
	HiliteControl(mbPtr->control, kControlInactivePart);
d1032 1
a1032 23
	/*
	 * Use NoPart for normal and to ensure correct direct transition from
	 * disabled to active -state. [Bug 706446]
	 */
	HiliteControl(mbPtr->control, kControlNoPart);

	if (butPtr->state == STATE_ACTIVE) {
	    if (mbPtr->params.isBevel) {
		HiliteControl(mbPtr->control, kControlButtonPart);
	    } else {
		switch (butPtr->type) {
		    case TYPE_BUTTON:
			HiliteControl(mbPtr->control,  kControlButtonPart);
			break;
		    case TYPE_RADIO_BUTTON:
			HiliteControl(mbPtr->control, kControlRadioButtonPart);
			break;
		    case TYPE_CHECK_BUTTON:
			HiliteControl(mbPtr->control, kControlCheckBoxPart);
			break;
		}
	    }
	}
d1035 2
a1036 2

    if (butPtr->type == TYPE_BUTTON) {
d1038 1
a1038 1

d1046 1
a1046 1
                sizeof(isDefault), (Ptr) &isDefault)) != noErr) {
d1058 1
a1058 1

d1061 1
a1061 1
    }
@


1.2.2.15
log
@	* macosx/tkMacOSXCarbonEvents.c: add window event target carbon event
	* macosx/tkMacOSXEvent.c:	 handler for all kEventClassWindow and
	* macosx/tkMacOSXEvent.h:	 kEventClassMouse events; move all
	* macosx/tkMacOSXNotify.c:	 remaining events except for
	* macosx/tkMacOSXWindowEvent.c:	 kEventClassKeyboard from dispatcher to
	application event handler; pass event handler callRef downstream; fix
	debug event tracing; process all tcl event types in carbon event timer;
	delay carbon event timer first fire; add TkMacOSXTrackingLoop() to mark
	enter/exit of event tracking loop during which all tcl events but only
	carbon update events should be processed by the timer (replaces various
	calls to Tcl_SetServiceMode()); rename TkMacOSXReceiveAndProcessEvent()
	to TkMacOSXReceiveAndDispatchEvent(), move it from tkMacOSXEvent.c to
	tkMacOSXCarbonEvents.c and modify it to dequeue only update events
	during a tracking loop; add TkMacOSXRunTclEventLoop() to standardize
	the various ways in use to run the tcl event loop; add handling of
	kEventClassAppearance events (for ScrollBarVariantChanged event).

	* macosx/tkMacOSXDialog.c:	use new TkMacOSXTrackingLoop() around
	* macosx/tkMacOSXEvent.c:	blocking API that puts up modal dialogs
	* macosx/tkMacOSXMenu.c:	or when entering/exiting menu/control
	* macosx/tkMacOSXMouseEvent.c:	tracking, window dragging and other
	* macosx/tkMacOSXScale.c:	mouse tracking loops.
	* macosx/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:

	* macosx/tkMacOSXDialog.c:	use new TkMacOSXRunTclEventLoop()
	* macosx/tkMacOSXScale.c:	instead of Tcl_DoOneEvent(),
	* macosx/tkMacOSXScrlbr.c:	Tcl_ServiceAll(), TclServiceIdle()
	* macosx/tkMacOSXWindowEvent.c:	and Tcl_GlobalEval("update idletasks").

	* macosx/tkMacOSXColor.c: make available as Tk system colors all
	* macosx/tkMacOSXPort.h:  appearance manager brushes, text colors and
	backgrounds with new and legacy names, as well as the fully transparent
	color "systemTransparent"; add TkMacOSXSetColorIn{Port,Context}() to
	directly set an X pixel color value in the current QD port resp. the
	given CG context without requiring passage through rgb representation
	(lossy for most system colors); modernize/remove Classic-era code;
	replace crufty strcmp() elseifs by Tcl_GetIndexFromObjStruct().

	* macosx/tkMacOSXButton.c:	use new TkMacOSXSetColorInPort()
	* macosx/tkMacOSXDraw.c:	instead of setting rgb color directly
	* macosx/tkMacOSXMenubutton.c:	to allow for non-rgb system colors.

	* macosx/tkMacOSXCursor.c: implement "none" cursor as on other
	platforms [Patch 1615427]; add all missing appearance manager cursors.

	* macosx/tkMacOSXDefault.h: set SELECT_FG_COLORs to None to match aqua
	L&F; use standard system color names; use new 'menu' system font;
	correct default scrollbar width.

	* macosx/tkMacOSXDraw.c:	standardize initialization, use and
	* macosx/tkMacOSXInt.h:		emptying of various static temp rgns
	* macosx/tkMacOSXRegion.c:	onto two global RgnHandles; in debug
	* macosx/tkMacOSXSubwindows.c:	builds, verify emptiness of these temp
	* macosx/tkMacOSXWindowEvent.c:	rgns before use.

	* macosx/tkMacOSXDraw.c: add TkMacOSX{Setup,Restore}DrawingContext() to
	* macosx/tkMacOSXInt.h:  abstract common setup & teardown of drawing
	environment (for both CG and QD); save/restore QD theme drawing state;
	handle GC clip region; add TkpClipDrawableToRect() to allow clipped
	drawing into drawable regardless of GC used; use new system color
	"systemWindowHeaderBackground" to setup background in themed toplevels;
	correct implementation of TkMacOSXMakeStippleMap().

	* macosx/tkMacOSXEntry.c: use new TkMacOSXSetupDrawingContext() and
	* macosx/tkMacOSXFont.c:  TkMacOSXRestoreDrawingContext() instead of
	various setup/teardown procs like TkMacOSX{SetUp,Release}CGContext(),
	TkMacOSXQuarz{Start,End}Draw(), TkMacOSXSetUpGraphicsPort() etc.

	* macosx/tkMacOSXEmbed.c: add CG context and drawable clip rgn fields
	* macosx/tkMacOSXInt.h:   to MacDrawable struct.
	* macosx/tkMacOSXSubwindows.c:

	* macosx/tkMacOSXDialog.c: make -parent option of tk_getOpenFile et al.
	use the sheet version of NavServices dialogs; ensure native parent win
	exists before using StandardSheet API for tk_messageBox [Bug 1677611];
	force sheets to behave like app-modal dialogs via WindowModality() API;
	use more modern ColorPicker API.

	* macosx/tkAboutDlg.r: use themed movable modal dialog, fix (c) year.

	* macosx/tkMacOSXEntry.c:  take xOff/yOff of MacDrawable into account
	when computing locations/bounds to ensure correct posititioning when
	not drawing into intermediate pixmap.

	* macosx/tkMacOSXFont.c: use appearance manager API to map system font
	* macosx/tkMacOSXFont.h: names to TkFonts; add "menu" system font for
	menu item text drawing from MDEF; disable broken QD stippling.

	* macosx/tkMacOSXMenu.c:		large-scale rewrite of custom
	* macosx/tkMacOSXMenu.r (removed):	MDEF and related code that
	* unix/Makefile.in:			restores many longtime-MIA
	features to working order (e.g. images, custom colors & fonts in menus
	etc); implement compound menu items; use Appearance Mgr and ThemeText
	APIs to mimic native MDEF as closely as possible when default "menu"
	system font is used; remove now obsolete SICN drawing code and
	resources.

	* macosx/tkMacOSXCarbonEvents.c: handle additional menu carbon events
	* macosx/tkMacOSXEvent.c:	 in order to support <<MenuSelect>> in
	* macosx/tkMacOSXMenu.c:	 the menubar and in menus that are not
	* macosx/tkMacOSXMenus.c:	 using the custom MDEF [Bug 1620826];
	fix early and missing clearing of current Tk active menu entry; fix
	extraneous sending of <<MenuSelect>> during active menu entry clearing.

	* macosx/tkMacOSXMouseEvent.c: add support for async window dragging by
	the window server; set the corresponding window attribute by default.

	* macosx/tkMacOSXMouseEvent.c: rationalized handling order of
	non-mousedown events; add TkMacOSXModifierState() to retrieve the
	current key modifiers in carbon format.

	* macosx/tkMacOSXScrlbr.c: use appearance manager API to retrieve
	scrollbar component metrics; add awareness of multiple possibilites for
	scrollbar arrow position in aqua and handle user changes to arrow
	position pref; handle difference in metrics of small & large scrollbar
	variants; handle aqua "jump to here" scrollbar behaviour; correct
	computation of scroll view size and position; enforce min scrollbar
	height to avoid scrollbar component overlap; erase scrollbar area
	outside of standard width; remove broken auto-adjust code; account for
	window class when leaving space for grow box; remove code to manually
	draw grow box; use modern API for thumb scroll proc; replace
	HiliteControl() by modern API; replace control mgr constants with
	appearance mgr equivalents.

	* macosx/tkMacOSXSubwindows.c: use SetWindowBounds() API instead of
	SizeWindow(); invalidate clip regions after X{Map,Unmap}Window as fix
	for [Bug 940117] made them dependent on mapping state; remove unneeded
	calls to TkMacOSXInvalClipRgns() and unnecessary setting of QD port;
	use native-endian pixmap on intel; remove obsolete pixmap pix locking.

	* macosx/tkMacOSXWindowEvent.c: handle only the first of a batch of
	kEventAppAvailableWindowBoundsChanged events sent per transaction;
	handle kEventWindowBoundsChanged event to support live window resizing
	and centralized sending of location/size changed ConfigureNotify
	events; ensure HIGrowBox is redrawn after bounds change; constrain
	window after dragging to ensure titlebar is not inacessible
	offscreen or under dock/menubar; handle kEventWindowGetRegion and
	kEventWindowDrawContent for transparent windows to mark resp. paint
	content region as transparent; handle kEventWindowConstrain for
	fullscreen windows to ensure bounds match new screen size; enter/exit
	fullscreen UIMode upon activation/deactivation of fullscreen window.

	* macosx/tkMacOSXWm.c: use live-resize and async-drag carbon window
	* macosx/tkMacOSXWm.h: attributes for toplevels by default; implement
	new [wm attributes] -topmost, -transparent and -fullscreen; refactor
	WmAttributesCmd() parallelling the tkUnixWm.c implementation, use thus
	factored proc to set proxy icon from [wm iconbitmap]; dynamically
	determine default values for toplevel min and max sizes (similar to
	tkWinWm.c impl): min sizes depend on window class & attributes to
	ensure visibility of all titlebar widgets and grow box, max sizes
	depend on maximal window bounds for all active displays; factor out
	code that puts into effect changes to master or override_redirect; use
	RepositionWindow() API to determine staggered initial window bounds;
	correct resize limit calculations, handle gridding and use modern
	resize API in TkMacOSXGrowToplevel(); remove sending of ConfigureNotify
	after resize or zoom (now handled by BoundsChanged handler); correct
	composite carbon window attribute handling, remove currently unusable
	attributes and add new attributes in [tk::unsupported::MacWindowStyle];
	ensure validity of window class and attributes before use; apply
	changes to window class when handling carbon window attribute changes
	(if HIWindowChangeClass() API available); add debug build warning
	message when deprecated window style is used instead of window class;
	use transparent HIGrowBox for resizable windows; avoid unnecessary
	calls to window structure width API; use tcl time API in TkpGetMS();
	add TkMacOSXEnterExitFullscreen() to enter/exit UIMode with dock and
	menubar hidden; restrict wmTracing output to debug builds; remove
	unneeded calls to TkMacOSXInvalClipRgns() and unnecessary setting of QD
	port; workaround GetWindowStructureWidths() Carbon bug (bogus results
	for never-mapped floating windows).

	* macosx/tkMacOSXXStubs.c (TkMacOSXDisplayChanged): add maximal window
	bounds field to Screen record (in ext_data), computed as the union of
	available window positioning bounds of all graphics devices (displays).

	* macosx/tkMacOSXBitmap.c: fix macRoman encoding leak.
	* macosx/tkMacOSXCursor.c:

	* macosx/tkMacOSXDebug.c (TkMacOSXCarbonEventToAscii): use static
	* macosx/tkMacOSXDebug.h: buffer to simplify callers; const fixes.

	* macosx/tkMacOSXBitmap.c: use more efficient QDSwapPort() instead of
	* macosx/tkMacOSXButton.c: GetPort()/SetPort()/GetGWorld()/SetGWorld().
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXXStubs.c:

	* macosx/tkMacOSXColor.c: use kHIToolboxVersionNumber for runtime OS
	* macosx/tkMacOSXEntry.c: version check rather than Gestalt() etc.
	* macosx/tkMacOSXInt.h:
	* macosx/tkMacOSXWm.c:

	* macosx/tkMacOSXDraw.c: remove obsolete and now incorrect
	* macosx/tkMacOSXInt.h:  tkMenuCascadeRgn clipping code.
	* macosx/tkMacOSXMenu.c:

	* macosx/tkMacOSXHLEvents.c: replace Tcl_GlobalEval() resp. Tcl_Eval()
	* macosx/tkMacOSXScrlbr.c:   by Tcl_EvalEx().
	* macosx/tkMacOSXInit.c:

	* macosx/tkMacOSXInit.c (TkpInit): reorder initialization steps.

	* macosx/tkMacOSXKeyEvent.c: remove pre-10.2 support.

	* macosx/tkMacOSXMenus.c: remove now useless call to
	TkMacOSXHandleTearoffMenu(); use \x.. quoting for non-latin1 macroman
	literar chars to allow file to be edited as utf-8.

	* macosx/tkMacOSXScale.c: replace TrackControl() by modern
	* macosx/tkMacOSXScrlbr.c: HandleControlClick() API (using new
	TkMacOSXModifierState()).

	* macosx/tkMacOSXInt.h:		move all constant #defines needed to
	* macosx/tkMacOSXColor.c:	support building on older OS X releases
	* macosx/tkMacOSXEvent.h:	to a central location in tkMacOSXInt.h.
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXWm.c:

	* macosx/tkMacOSXInt.h:		 add ChkErr() macro to factor out
	* macosx/tkMacOSXButton.c:	 Carbon OSStatus return value checking
	* macosx/tkMacOSXCarbonEvents.c: and TkMacOSXDbgMsg() macro to factour
	* macosx/tkMacOSXClipboard.c:	 out debug message output; use these
	* macosx/tkMacOSXColor.c:	 macros to replace #ifdef TK_MAC_DEBUG
	* macosx/tkMacOSXCursor.c:	 blocks & direct printing to stderr,
	* macosx/tkMacOSXDebug.c:	 and to do additional OSStatus return
	* macosx/tkMacOSXDialog.c:	 checking, and to standardize OSStatus
	* macosx/tkMacOSXDraw.c:	 usage.
	* macosx/tkMacOSXEntry.c:
	* macosx/tkMacOSXEvent.c:
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXHLEvents.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXXStubs.c:

	* macosx/tkMacOSXSend.c:	remove duplicate/unused declarations.
	* macosx/tkMacOSXXStubs.c:

	* macosx/tkMacOSXDebug.c:	const fixes.
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXTest.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXXStubs.c:

	* macosx/Wish-Info.plist.in: add tcl document extensions/mime types and
	LSMinimumSystemVersion, LSRequiresCarbon & NSAppleScriptEnabled keys.

	* macosx/tkMacOSXAETE.r:	fix whitespace.
	* macosx/tkMacOSXConfig.c:
	* macosx/tkMacOSXCursors.r:
	* macosx/tkMacOSXKeyboard.c:
	* macosx/tkMacOSXSend.c:
	* macosx/tkMacOSXXCursors.r:
	* macosx/README:

	* macosx/Makefile:		fix/add copyright and license refs.
	* macosx/Tk-Info.plist.in:
	* macosx/Wish-Info.plist.in:
	* macosx/tkMacOSX.h:
@
text
@d1 1
a1 1
/*
d4 2
a5 2
 *	This file implements the Macintosh specific portion of the
 *	button widgets.
a8 1
 * Copyright (c) 2006-2007 Daniel A. Steffen <das@@users.sourceforge.net>
d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.2.2.14 2006/05/26 21:43:05 hobbs Exp $
a25 1

d40 1
a40 1
/*
d49 1
a49 1
    int isBevel;
d56 1
a56 1
    int offset;			/* 0 means this is a normal widget. 1 means
d60 1
a60 1
    GC gc;
d64 1
d66 15
a80 15
    TkButton info;		/* Generic button info */
    int id;
    int usingControl;
    int useTkText;
    int flags;			/* Initialisation status */
    MacControlParams params;
    WindowRef windowRef;
    unsigned long userPaneBackground;
    ControlRef userPane;	/* Carbon control */
    ControlRef control;		/* Carbon control */
    Str255 controlTitle;
    ControlFontStyleRec fontStyle;
    /*
     * The following are used to store the image content for
     * beveled buttons, i.e. buttons with images.
d82 1
a82 2
    CCTabHandle tabHandle;
    Pixmap picPixmap;
d84 2
a85 1
    OpenCPicParams picParams;
d93 4
a96 4
static OSStatus SetUserPaneDrawProc(ControlRef control,
	ControlUserPaneDrawProcPtr upp);
static OSStatus SetUserPaneSetUpSpecialBackgroundProc(ControlRef control,
	ControlUserPaneBackgroundProcPtr upp);
d99 1
a99 1
	ControlBackgroundPtr info);
d101 9
a109 9
static void ButtonEventProc(ClientData clientData, XEvent *eventPtr);
static int UpdateControlColors(MacButton *mbPtr);
static void TkMacOSXComputeControlParams(TkButton *butPtr,
	MacControlParams *paramsPtr);
static int TkMacOSXComputeDrawParams(TkButton *butPtr, DrawParams *dpPtr);
static void TkMacOSXDrawControl(MacButton *butPtr, GWorldPtr destPort, GC gc,
	Pixmap pixmap);
static void SetupBevelButton(MacButton *butPtr, ControlRef controlHandle,
	GWorldPtr destPort, GC gc, Pixmap pixmap);
d115 3
a117 3
Tk_ClassProcs tkpButtonProcs = {
    sizeof(Tk_ClassProcs),	/* size */
    TkButtonWorldChanged,	/* worldChangedProc */
d129 1
a129 1
 *	Allocate a new TkButton structure.
d132 1
a132 1
 *	Returns a newly allocated TkButton structure.
d135 1
a135 1
 *	Registers an event handler for the widget.
d144 2
a145 2
    MacButton *macButtonPtr = (MacButton *) ckalloc(sizeof(MacButton));

d147 1
a147 1
	    ButtonEventProc, (ClientData) macButtonPtr);
d151 3
a153 1
    macButtonPtr->userPaneBackground = PIXEL_MAGIC << 24;
a167 1

d176 2
a177 2
 *	This procedure is invoked to display a button widget. It is
 *	normally invoked as an idle handler.
d180 1
a180 1
 *	None.
d183 2
a184 2
 *	Commands are output to X to display the button in its
 *	current mode. The REDRAW_PENDING flag is cleared.
d191 1
a191 1
    ClientData clientData)	/* Information about widget. */
d194 7
a200 4
    TkButton *butPtr = (TkButton *) clientData;
    Tk_Window tkwin = butPtr->tkwin;
    CGrafPtr destPort, savePort;
    Boolean portChanged;
d202 2
a203 3
    int width, height, fullWidth, fullHeight, textXOffset, textYOffset;
    int borderWidth, wasUsingControl;
    int haveImage = 0, haveText = 0, imageWidth = 0, imageHeight = 0;
d207 1
a207 1
    DrawParams drawParams, *dpPtr = &drawParams;
d211 1
a211 1
	return;
d218 6
a223 6
	macButtonPtr->usingControl = 1;
	if (butPtr->type == TYPE_BUTTON) {
	    macButtonPtr->useTkText = 0;
	} else {
	    macButtonPtr->useTkText = 1;
	}
d225 2
a226 2
	macButtonPtr->usingControl = 0;
	macButtonPtr->useTkText = 1;
d228 4
a231 4

    /*
     * Set up clipping region. Make sure the we are using the port
     * for this button, or we will set the wrong window's clip.
d233 1
a233 1

d235 1
a235 1
    portChanged = QDSwapPort(destPort, &savePort);
d238 1
d240 1
a240 1
     * See the comment in UpdateControlColors as to why we use the
d245 7
a251 7
	if (butPtr->type == TYPE_BUTTON) {
	    Tk_Fill3DRectangle(tkwin, pixmap, butPtr->highlightBorder, 0, 0,
		    Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
	} else {
	    Tk_Fill3DRectangle(tkwin, pixmap, butPtr->normalBorder, 0, 0,
		    Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
	}
d256 2
a257 2
     * if it doesn't already exist. Then configure the Macintosh control from
     * the Tk info. Finally, we call Draw1Control to draw to the screen.
d261 9
a269 7
	borderWidth = 0;
	TkMacOSXDrawControl(macButtonPtr, destPort, dpPtr->gc, pixmap);
    } else if (wasUsingControl && macButtonPtr->userPane) {
	DisposeControl(macButtonPtr->userPane);
	macButtonPtr->userPane = NULL;
	macButtonPtr->control = NULL;
	macButtonPtr->flags = 0;
d273 1
a273 1
	borderWidth = butPtr->borderWidth;
d277 1
a277 1
     * Display image or bitmap or text for button. This has
d283 167
a449 160
	goto applyStipple;
    }

    if (butPtr->image != None) {
	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) {
	int x, y;

	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;

	x += dpPtr->offset;
	y += dpPtr->offset;
	if (dpPtr->relief == TK_RELIEF_RAISED) {
	    x -= dpPtr->offset;
	    y -= dpPtr->offset;
	} else if (dpPtr->relief == TK_RELIEF_SUNKEN) {
	    x += dpPtr->offset;
	    y += dpPtr->offset;
	}
	imageXOffset += x;
	imageYOffset += y;
	if (butPtr->image != NULL) {
	    if ((butPtr->selectImage != NULL) && (butPtr->flags & SELECTED)) {
		Tk_RedrawImage(butPtr->selectImage, 0, 0, width, height,
			pixmap, imageXOffset, imageYOffset);
	    } else {
		Tk_RedrawImage(butPtr->image, 0, 0, width, height,
			pixmap, imageXOffset, imageYOffset);
	    }
	} else {
	    XSetClipOrigin(butPtr->display, dpPtr->gc, imageXOffset,
		    imageYOffset);
	    XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, dpPtr->gc,
		    0, 0, width, height, imageXOffset, imageYOffset, 1);
	    XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0);
	}

	if (macButtonPtr->useTkText) {
	    Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc,
		    butPtr->textLayout, x + textXOffset, y + textYOffset, 0,
		    -1);
	    Tk_UnderlineTextLayout(butPtr->display, pixmap, dpPtr->gc,
		    butPtr->textLayout, x + textXOffset, y + textYOffset,
		    butPtr->underline);
	}
	y += fullHeight/2;
    } else if (haveImage) {
	int x = 0, y;

	TkComputeAnchor(butPtr->anchor, tkwin, 0, 0,
		butPtr->indicatorSpace + width, height, &x, &y);
	x += butPtr->indicatorSpace;

	x += dpPtr->offset;
	y += dpPtr->offset;
	if (dpPtr->relief == TK_RELIEF_RAISED) {
	    x -= dpPtr->offset;
	    y -= dpPtr->offset;
	} else if (dpPtr->relief == TK_RELIEF_SUNKEN) {
	    x += dpPtr->offset;
	    y += dpPtr->offset;
	}
	imageXOffset += x;
	imageYOffset += y;
	if (butPtr->image != NULL) {
	    if ((butPtr->selectImage != NULL) && (butPtr->flags & SELECTED)) {
		Tk_RedrawImage(butPtr->selectImage, 0, 0, width, height,
			pixmap, imageXOffset, imageYOffset);
	    } else {
		Tk_RedrawImage(butPtr->image, 0, 0, width, height,
			pixmap, imageXOffset, imageYOffset);
	    }
	} else {
	    XSetClipOrigin(butPtr->display, dpPtr->gc, x, y);
	    XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, dpPtr->gc,
		    0, 0, width, height, x, y, 1);
	    XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0);
	}
	y += height/2;
    } else if (macButtonPtr->useTkText) {
	int x = 0, y;

	TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY,
		butPtr->indicatorSpace + butPtr->textWidth,
		butPtr->textHeight, &x, &y);
	x += butPtr->indicatorSpace;
	Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc,
		butPtr->textLayout, x, y, 0, -1);
d454 1
a454 1
     * foreground color, generate the stippled effect. If the widget
a458 1
  applyStipple:
d460 3
a462 3
	if ((butPtr->state == STATE_DISABLED)
		&& ((butPtr->disabledFg == NULL) || (butPtr->image != NULL))) {
	    if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn
d464 1
a464 1
		XSetForeground(butPtr->display, butPtr->stippleGC,
d466 1
a466 2
	    }

a470 1

d480 1
a480 1
	    if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn
d485 1
a485 9
	}

	/*
	 * Draw the border and traversal highlight last. This way, if the
	 * button's contents overflow they'll be covered up by the border.
	 */

	if (dpPtr->relief != TK_RELIEF_FLAT) {
	    int inset = butPtr->highlightWidth;
d487 11
a497 7
	    Tk_Draw3DRectangle(tkwin, pixmap, dpPtr->border, inset, inset,
		    Tk_Width(tkwin) - 2*inset, Tk_Height(tkwin) - 2*inset,
		    butPtr->borderWidth, dpPtr->relief);
	}
    }
    if (portChanged) {
	QDSwapPort(savePort, NULL);
d506 3
a508 3
 *	After changes in a button's text or bitmap, this procedure
 *	recomputes the button's geometry and passes this information
 *	along to the geometry manager for the window.
d511 1
a511 1
 *	None.
d514 1
a514 1
 *	The button's window may change size.
d521 1
a521 1
    TkButton *butPtr)		/* Button whose geometry may have changed. */
d524 2
a525 1
    int xInset, yInset, txtWidth, txtHeight;
d532 1
a532 1

d539 1
d542 2
a543 2
	Tk_SizeOfImage(butPtr->image, &width, &height);
	haveImage = 1;
d545 2
a546 2
	Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
	haveImage = 1;
d550 10
a559 10
	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);
d570 47
a616 36
	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;
	}
d618 2
a619 8
	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;
	    }
	}
a620 17
	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;
	    }
	}
d622 33
a654 16
	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;
	}
d660 1
a660 1

d662 1
a662 1
	butPtr->highlightWidth = 0;
d664 1
a664 1

d666 2
a667 2
     * The width and height calculation for Appearance buttons with images &
     * non-Appearance buttons with images is different. In the latter case,
d669 1
a669 1
     * 3-D border over the image. In the former, we add it to the height,
d673 1
a673 1
     * if any, and for the border and padding, plus if this is an image two
d679 1
a679 1
     * button. The actual width of the default ring is one less than the
d681 1
a681 1
     * Appearance buttons with images do not have a highlight ring, because the
d686 2
a687 2
	width += 2*butPtr->padX;
	height += 2*butPtr->padY;
d689 1
a689 1

d691 35
a725 14
	if ((butPtr->image == None) && (butPtr->bitmap == None)) {
	    butPtr->inset = 0;
	    if (butPtr->defaultState != STATE_DISABLED) {
		butPtr->inset += butPtr->highlightWidth;
	    }
	} else {
	    butPtr->inset = 0;
	    width += (2 * butPtr->borderWidth + 4);
	    height += (2 * butPtr->borderWidth + 4);
	}
    } else if (butPtr->type == TYPE_LABEL) {
	butPtr->inset = butPtr->borderWidth;
    } else if (butPtr->indicatorOn) {
	butPtr->inset = 0;
d727 1
a727 21
	/*
	 * Under Appearance, the Checkbutton or radiobutton with an image
	 * is represented by a BevelButton with the Sticky defProc...
	 * So we must set its height in the same way as the Button
	 * with an image or bitmap.
	 */

	if (butPtr->image != None || butPtr->bitmap != None) {
	    int border;

	    butPtr->inset = 0;
	    if (butPtr->borderWidth <= 2) {
		border = 6;
	    } else {
		border = 2 * butPtr->borderWidth + 2;
	    }
	    width += border;
	    height += border;
	} else {
	    butPtr->inset = butPtr->borderWidth;
	}
d731 2
a732 2
	xInset = butPtr->indicatorSpace + DEF_INSET_LEFT + DEF_INSET_RIGHT;
	yInset = DEF_INSET_TOP + DEF_INSET_BOTTOM;
d734 2
a735 2
	xInset = butPtr->indicatorSpace+butPtr->inset*2;
	yInset = butPtr->inset*2;
d746 1
a746 1
 *	Free data structures associated with the button control.
d749 1
a749 1
 *	None.
d752 1
a752 1
 *	Restores the default control state.
d761 1
a761 2
    MacButton *mbPtr = (MacButton *) butPtr; /* Mac button. */

d763 2
a764 2
	DisposeControl(mbPtr->userPane);
	mbPtr->userPane = NULL;
d773 1
a773 1
 *	This procedure initialises a Carbon control.
d776 1
a776 1
 *	0 on success, 1 on failure.
d779 5
a783 5
 *	A background pane control and the control itself is created
 *	The contol is embedded in the background control
 *	The background control is embedded in the root control
 *	of the containing window
 *	The creation parameters for the control are also computed
d789 8
a796 7
TkMacOSXInitControl(
    MacButton *mbPtr,		/* Mac button. */
    GWorldPtr destPort,
    GC gc,
    Pixmap pixmap,
    Rect *paneRect,
    Rect *cntrRect)
d798 2
a799 1
    TkButton *butPtr = (TkButton *) mbPtr;
d801 6
a806 3
    SInt16 procID, initialValue, minValue, maxValue;
    Boolean initiallyVisible;
    SInt32 controlReference;
d809 2
a810 2
    mbPtr->windowRef = GetWindowFromPort(
	    TkMacOSXGetDrawablePort(Tk_WindowId(butPtr->tkwin)));
d812 2
a813 2
    /*
     * Set up the user pane.
d817 4
a820 4
    initialValue = kControlSupportsEmbedding|kControlHasSpecialBackground;
    minValue = 0;
    maxValue = 1;
    procID = kControlUserPaneProc;
d822 9
a830 4
    mbPtr->userPane = NewControl(mbPtr->windowRef, paneRect, "\p",
	    initiallyVisible, initialValue, minValue, maxValue, procID,
	    controlReference);

d832 11
a842 5
	TkMacOSXDbgMsg("Failed to create user pane control");
	return 1;
    }
    if (ChkErr(EmbedControl, mbPtr->userPane,rootControl) != noErr) {
	return 1;
d844 1
a844 1

d846 1
a846 1
	    UserPaneBackgroundProc);
d850 9
a858 5
    mbPtr->control = NewControl(mbPtr->windowRef, cntrRect, "\p",
	    initiallyVisible, mbPtr->params.initialValue,
	    mbPtr->params.minValue, mbPtr->params.maxValue,
	    mbPtr->params.procID, controlReference);

d860 11
a870 5
	TkMacOSXDbgMsg("failed to create control of type %d\n", procID);
	return 1;
    }
    if (ChkErr(EmbedControl, mbPtr->control,mbPtr->userPane) != noErr ) {
	return 1;
d872 1
a872 1

d876 1
a876 1

d882 3
a884 3
 *	This function draws the tk button using Mac controls
 *	In addition, this code may apply custom colors passed
 *	in the TkButton.
d887 1
a887 1
 *	None.
d890 2
a891 1
 *	The control is created, or reinitialised as needed.
d898 7
a904 6
    MacButton *mbPtr,		/* Mac button. */
    GWorldPtr destPort,		/* Off screen GWorld. */
    GC gc,			/* The GC we are drawing into - needed for the
				 * bevel button */
    Pixmap pixmap)		/* The pixmap we are drawing into - needed for
				 * the bevel button */
d906 11
a916 9
    TkButton *butPtr = (TkButton *) mbPtr;
    TkWindow *winPtr;
    Rect paneRect, cntrRect;

    winPtr = (TkWindow *) butPtr->tkwin;

    paneRect.left = winPtr->privatePtr->xOff;
    paneRect.top = winPtr->privatePtr->yOff;
    paneRect.right = paneRect.left + Tk_Width(butPtr->tkwin);
d922 3
a924 3
    cntrRect.left += butPtr->inset;
    cntrRect.top += butPtr->inset;
    cntrRect.right -= butPtr->inset;
d927 3
a929 3
    cntrRect.left += DEF_INSET_LEFT;
    cntrRect.top += DEF_INSET_TOP;
    cntrRect.right -= DEF_INSET_RIGHT;
d932 3
a934 3
    /*
     * The control has been previously initialised.
     * It may need to be re-initialised
d936 1
a936 1

d938 15
a952 16
	MacControlParams params;

	TkMacOSXComputeControlParams(butPtr, &params);
	if (bcmp(&params, &mbPtr->params, sizeof(params))) {
	    /*
	     * The type of control has changed.
	     * Clean it up and clear the flag.
	     */

	    if (mbPtr->userPane) {
		DisposeControl(mbPtr->userPane);
		mbPtr->userPane = NULL;
		mbPtr->control = NULL;
	    }
	    mbPtr->flags = 0;
	}
d955 4
a958 4
	if (TkMacOSXInitControl(mbPtr, destPort, gc, pixmap, &paneRect,
		&cntrRect)) {
	    return;
	}
d964 36
a999 31
	Str255 controlTitle;
	ControlFontStyleRec fontStyle;
	Tk_Font font;
	int len;

	if (((mbPtr->info.image == NULL) && (mbPtr->info.bitmap == None))
		|| (mbPtr->info.compound != COMPOUND_NONE)) {
	    len = TkFontGetFirstTextLayout(butPtr->textLayout,
		    &font, (char*) controlTitle);
	    controlTitle[len] = 0;
	} else {
	    len = 0;
	    controlTitle[0] = 0;
	}
	if (bcmp(mbPtr->controlTitle, controlTitle, len+1)) {
	    CFStringRef cf = CFStringCreateWithCString(NULL,
		    (char*) controlTitle, kCFStringEncodingUTF8);

	    if (cf != NULL) {
		SetControlTitleWithCFString(mbPtr->control, cf);
		CFRelease(cf);
	    }
	    bcopy(controlTitle, mbPtr->controlTitle, len+1);
	}
	if (len) {
	    TkMacOSXInitControlFontStyle(font, &fontStyle);
	    if (bcmp(&mbPtr->fontStyle, &fontStyle, sizeof(fontStyle)) ) {
		ChkErr(SetControlFontStyle, mbPtr->control, &fontStyle);
		bcopy(&fontStyle, &mbPtr->fontStyle, sizeof(fontStyle));
	    }
	}
d1002 3
a1004 5
	/*
	 * Initialiase the image/button parameters.
	 */

	SetupBevelButton(mbPtr, mbPtr->control, destPort, gc, pixmap);
d1008 1
a1008 1
	SetControlValue(mbPtr->control, 1);
d1010 1
a1010 1
	SetControlValue(mbPtr->control, 0);
a1019 1

d1028 1
a1028 1
			HiliteControl(mbPtr->control, kControlButtonPart);
d1042 2
a1043 11
    if (butPtr->type == TYPE_BUTTON && !mbPtr->params.isBevel) {
	Boolean isDefault;

	if (butPtr->defaultState == STATE_ACTIVE) {
	    isDefault = true;
	} else {
	    isDefault = false;
	}
	ChkErr(SetControlData, mbPtr->control, kControlNoPart,
		kControlPushButtonDefaultTag, sizeof(isDefault), &isDefault);
    }
d1045 15
a1059 4
    if (mbPtr->flags & 2) {
	ShowControl(mbPtr->userPane);
	ShowControl(mbPtr->control);
	mbPtr->flags ^= 2;
d1061 2
a1062 2
	SetControlVisibility(mbPtr->control, true, true);
	Draw1Control(mbPtr->userPane);
d1066 1
a1066 1
	KillPicture(mbPtr->bevelButtonContent.u.picture);
d1075 2
a1076 2
 *	Sets up the Bevel Button with image by copying the
 *	source image onto the PicHandle for the button.
d1079 1
a1079 1
 *	None
d1082 1
a1082 1
 *	The image or bitmap for the button is copied over to a picture.
a1085 1

d1088 8
a1095 7
    MacButton *mbPtr,		/* Mac button. */
    ControlRef controlHandle,	/* The control to set this picture to. */
    GWorldPtr destPort,		/* Off screen GWorld. */
    GC gc,			/* The GC we are drawing into - needed for the
				 * bevel button. */
    Pixmap pixmap)		/* The pixmap we are drawing into - needed for
				 * the bevel button. */
d1097 2
a1098 1
    TkButton *butPtr = (TkButton *) mbPtr;
d1101 2
a1102 4
    CGrafPtr savePort;
    Boolean portChanged;

    portChanged = QDSwapPort(destPort, &savePort);
d1105 2
a1106 1
	Tk_SizeOfImage(butPtr->image, &width, &height);
d1108 2
a1109 1
	Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
d1111 1
a1111 1

d1113 1
a1113 1
	width = butPtr->width;
d1116 1
a1116 1
	height = butPtr->height;
d1122 2
a1123 2
    /*
     * Set the flag to circumvent clipping and bounds problems with OS 10.0.4
d1125 6
a1130 4

    mbPtr->bevelButtonContent.u.picture = OpenCPicture(&mbPtr->picParams);
    if (!mbPtr->bevelButtonContent.u.picture) {
	TkMacOSXDbgMsg("OpenCPicture failed");
d1133 1
a1133 1

d1136 1
a1136 1
     * which does not get recorded in the picture. So the bitmap code
d1139 4
a1142 3

    if (butPtr->selectImage != NULL && (butPtr->flags & SELECTED)) {
	Tk_RedrawImage(butPtr->selectImage, 0, 0, width, height, pixmap, 0, 0);
d1144 6
a1149 5
	Tk_RedrawImage(butPtr->image, 0, 0, width, height, pixmap, 0, 0);
    } else {
	XSetClipOrigin(butPtr->display, gc, 0, 0);
	XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, gc, 0, 0, width,
		height, 0, 0, 1);
d1151 1
a1151 1

d1154 11
a1164 5

    ChkErr(SetControlData, controlHandle, kControlButtonPart,
	    kControlBevelButtonContentTag, sizeof(ControlButtonContentInfo),
	    (char *) &mbPtr->bevelButtonContent);

d1166 5
a1170 5
	theAlignment = kControlBevelButtonAlignTop;
    } else if (butPtr->anchor == TK_ANCHOR_NE) {
	theAlignment = kControlBevelButtonAlignTopRight;
    } else if (butPtr->anchor == TK_ANCHOR_E) {
	theAlignment = kControlBevelButtonAlignRight;
d1172 1
a1172 1
	theAlignment = kControlBevelButtonAlignBottomRight;
d1174 1
a1174 1
	theAlignment = kControlBevelButtonAlignBottom;
d1176 1
a1176 1
	theAlignment = kControlBevelButtonAlignBottomLeft;
d1178 1
a1178 1
	theAlignment = kControlBevelButtonAlignLeft;
d1180 1
a1180 1
	theAlignment = kControlBevelButtonAlignTopLeft;
d1182 1
a1182 1
	theAlignment = kControlBevelButtonAlignCenter;
d1185 9
a1193 3
    ChkErr(SetControlData, controlHandle, kControlButtonPart,
	    kControlBevelButtonGraphicAlignTag,
	    sizeof(ControlButtonGraphicAlignment), (char *) &theAlignment);
d1196 20
a1215 18
	ControlButtonTextPlacement thePlacement =
		kControlBevelButtonPlaceNormally;

	if (butPtr->compound == COMPOUND_TOP) {
	    thePlacement = kControlBevelButtonPlaceBelowGraphic;
	} else if (butPtr->compound == COMPOUND_BOTTOM) {
	    thePlacement = kControlBevelButtonPlaceAboveGraphic;
	} else if (butPtr->compound == COMPOUND_LEFT) {
	    thePlacement = kControlBevelButtonPlaceToRightOfGraphic;
	} else if (butPtr->compound == COMPOUND_RIGHT) {
	    thePlacement = kControlBevelButtonPlaceToLeftOfGraphic;
	}
	ChkErr(SetControlData, controlHandle, kControlButtonPart,
		kControlBevelButtonTextPlaceTag,
		sizeof(ControlButtonTextPlacement), (char *) &thePlacement);
    }
    if (portChanged) {
	QDSwapPort(savePort, NULL);
d1224 3
a1226 3
 *	Utility function to add a UserPaneDrawProc
 *	to a userPane control. From MoreControls code
 *	from Apple DTS.
d1229 1
a1229 1
 *	MacOS system error.
d1232 1
a1232 1
 *	The user pane gets a new UserPaneDrawProc.
d1236 1
a1236 3

OSStatus
SetUserPaneDrawProc(
d1241 5
a1245 5

    myControlUserPaneDrawUPP = NewControlUserPaneDrawUPP(upp);
    return SetControlData(control, kControlNoPart,
	    kControlUserPaneDrawProcTag, sizeof(myControlUserPaneDrawUPP),
	    (Ptr) &myControlUserPaneDrawUPP);
d1253 2
a1254 2
 *	Utility function to add a UserPaneBackgroundProc
 *	to a userPane control
d1257 1
a1257 1
 *	MacOS system error.
d1260 1
a1260 1
 *	The user pane gets a new UserPaneBackgroundProc.
d1264 1
a1264 2

OSStatus
d1266 1
a1266 1
    ControlRef control,
a1269 1

d1271 4
a1274 4
    return SetControlData(control, kControlNoPart,
	    kControlUserPaneBackgroundProcTag,
	    sizeof(myControlUserPaneBackgroundUPP),
	    (Ptr) &myControlUserPaneBackgroundUPP);
d1282 2
a1283 2
 *	This function draws the background of the user pane that will
 *	lie under checkboxes and radiobuttons.
d1286 1
a1286 1
 *	None.
d1289 1
a1289 1
 *	The user pane gets updated to the current color.
a1292 1

a1297 1
    MacButton *mbPtr = (MacButton *)(intptr_t)GetControlReference(control);
d1299 2
a1300 1

d1302 2
a1303 2
    TkMacOSXSetColorInPort(mbPtr->userPaneBackground, 0, NULL);
    EraseRect(&contrlRect);
d1311 2
a1312 2
 *	This function sets up the background of the user pane that will
 *	lie under checkboxes and radiobuttons.
d1315 1
a1315 1
 *	None.
d1318 1
a1318 1
 *	The user pane background gets set to the current color.
d1328 2
a1329 2
    MacButton * mbPtr = (MacButton *)(intptr_t)GetControlReference(control);

d1331 1
a1331 1
	TkMacOSXSetColorInPort(mbPtr->userPaneBackground, 0, NULL);
d1340 4
a1343 4
 *	This function will review the colors used to display
 *	a Macintosh button. If any non-standard colors are
 *	used we create a custom palette for the button, populate
 *	with the colors for the button and install the palette.
d1345 2
a1346 2
 *	Under Appearance, we just set the pointer that will be
 *	used by the UserPaneDrawProc.
d1349 1
a1349 1
 *	None.
d1352 1
a1352 1
 *	The Macintosh control may get a custom palette installed.
d1358 1
a1358 2
UpdateControlColors(
    MacButton *mbPtr)
d1361 2
a1362 2
    TkButton *butPtr = (TkButton *) mbPtr;

d1365 3
a1367 3
     * button itself. However, the color we are setting is the color
     * of the containing userPane. This will be the color that peeks
     * around the rounded corners of the button.
d1373 1
a1373 1

d1375 1
a1375 1
	xcolor = Tk_3DBorderColor(butPtr->highlightBorder);
d1377 1
a1377 1
	xcolor = Tk_3DBorderColor(butPtr->normalBorder);
d1379 2
a1380 2
    mbPtr->userPaneBackground = xcolor->pixel;

d1382 1
a1382 2
}

d1388 2
a1389 2
 *	This procedure is invoked by the Tk dispatcher for various
 *	events on buttons.
d1392 1
a1392 1
 *	None.
d1395 1
a1395 1
 *	When it gets exposed, it is redisplayed.
d1402 2
a1403 2
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
a1405 1

d1407 9
a1415 8
	    || eventPtr->type == DeactivateNotify) {
	if ((buttonPtr->tkwin == NULL) || (!Tk_IsMapped(buttonPtr->tkwin))) {
	    return;
	}
	if ((buttonPtr->flags & REDRAW_PENDING) == 0) {
	    Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) buttonPtr);
	    buttonPtr->flags |= REDRAW_PENDING;
	}
d1424 3
a1426 3
 *	This procedure computes the various parameters used
 *	when creating a Carbon control (NewControl).
 *	These are determined by the various tk button parameters
d1429 1
a1429 1
 *	None.
d1432 1
a1432 1
 *	Sets the control initialisation parameters
d1438 1
a1438 3
TkMacOSXComputeControlParams(
    TkButton *butPtr,
    MacControlParams *paramsPtr)
d1441 3
a1443 3

    /*
     * Determine ProcID based on button type and dimensions.
d1445 1
a1445 1

d1447 68
a1514 65
	case TYPE_BUTTON:
	    if ((butPtr->image == None) && (butPtr->bitmap == None)) {
		paramsPtr->initialValue = 1;
		paramsPtr->minValue = 0;
		paramsPtr->maxValue = 1;
		paramsPtr->procID = kControlPushButtonProc;
	    } else {
		paramsPtr->initialValue = 0;
		paramsPtr->minValue = kControlBehaviorOffsetContents |
			kControlContentPictHandle;
		paramsPtr->maxValue = 1;
		if (butPtr->borderWidth <= 2) {
		    paramsPtr->procID = kControlBevelButtonSmallBevelProc;
		} else if (butPtr->borderWidth == 3) {
		    paramsPtr->procID = kControlBevelButtonNormalBevelProc;
		} else {
		    paramsPtr->procID = kControlBevelButtonLargeBevelProc;
		}
		paramsPtr->isBevel = 1;
	    }
	    break;
	case TYPE_RADIO_BUTTON:
	    if (((butPtr->image == None) && (butPtr->bitmap == None))
		|| (butPtr->indicatorOn)) {
		paramsPtr->initialValue = 1;
		paramsPtr->minValue = 0;
		paramsPtr->maxValue = 1;
		paramsPtr->procID = kControlRadioButtonProc;
	    } else {
		paramsPtr->initialValue = 0;
		paramsPtr->minValue = kControlBehaviorOffsetContents |
			kControlBehaviorSticky | kControlContentPictHandle;
		paramsPtr->maxValue = 1;
		if (butPtr->borderWidth <= 2) {
		    paramsPtr->procID = kControlBevelButtonSmallBevelProc;
		} else if (butPtr->borderWidth == 3) {
		    paramsPtr->procID = kControlBevelButtonNormalBevelProc;
		} else {
		    paramsPtr->procID = kControlBevelButtonLargeBevelProc;
		}
		paramsPtr->isBevel = 1;
	    }
	    break;
	case TYPE_CHECK_BUTTON:
	    if (((butPtr->image == None) && (butPtr->bitmap == None))
		    || (butPtr->indicatorOn)) {
		paramsPtr->initialValue = 1;
		paramsPtr->minValue = 0;
		paramsPtr->maxValue = 1;
		paramsPtr->procID = kControlCheckBoxProc;
	    } else {
		paramsPtr->initialValue = 0;
		paramsPtr->minValue = kControlBehaviorOffsetContents |
			kControlBehaviorSticky | kControlContentPictHandle;
		paramsPtr->maxValue = 1;
		if (butPtr->borderWidth <= 2) {
		    paramsPtr->procID = kControlBevelButtonSmallBevelProc;
		} else if (butPtr->borderWidth == 3) {
		    paramsPtr->procID = kControlBevelButtonNormalBevelProc;
		} else {
		    paramsPtr->procID = kControlBevelButtonLargeBevelProc;
		}
		paramsPtr->isBevel = 1;
	    }
	    break;
d1516 1
a1516 2
}

d1522 3
a1524 3
 *	This procedure computes the various parameters used
 *	when drawing a button
 *	These are determined by the various tk button parameters
d1527 1
a1527 1
 *	1 if control will be used, 0 otherwise.
d1530 1
a1530 1
 *	Sets the button draw parameters
d1536 1
a1536 3
TkMacOSXComputeDrawParams(
    TkButton *butPtr,
    DrawParams *dpPtr)
d1538 4
a1541 4
    dpPtr->hasImageOrBitmap = ((butPtr->image != NULL)
	    || (butPtr->bitmap != None));
    dpPtr->offset = (butPtr->type == TYPE_BUTTON)
	    && dpPtr->hasImageOrBitmap;
d1543 7
a1549 5
    if ((butPtr->state == STATE_DISABLED) && (butPtr->disabledFg != NULL)) {
	dpPtr->gc = butPtr->disabledGC;
    } else if (butPtr->type == TYPE_BUTTON && butPtr->state == STATE_ACTIVE) {
	dpPtr->gc = butPtr->activeTextGC;
	dpPtr->border = butPtr->activeBorder;
d1551 1
a1551 1
	dpPtr->gc = butPtr->normalTextGC;
d1554 5
a1558 3
    if ((butPtr->flags & SELECTED) && (butPtr->state != STATE_ACTIVE)
	    && (butPtr->selectBorder != NULL) && !butPtr->indicatorOn) {
	dpPtr->border = butPtr->selectBorder;
d1560 1
a1560 1

d1571 4
a1574 4
	if (!dpPtr->hasImageOrBitmap) {
	    dpPtr->relief = (butPtr->flags & SELECTED) ? TK_RELIEF_SUNKEN
		    : TK_RELIEF_RAISED;
	}
a1579 1

d1581 1
a1581 1
	dpPtr->drawType = DRAW_LABEL;
d1583 28
a1610 44
	if (!dpPtr->hasImageOrBitmap) {
	    dpPtr->drawType = DRAW_CONTROL;
	} else if (butPtr->image != None) {
	    dpPtr->drawType = DRAW_BEVEL;
	} else {
	    /*
	     * TO DO - The current way the we draw bitmaps (XCopyPlane)
	     * uses CopyDeepMask in this one case. The Picture recording
	     * does not record this call, and so we can't use the
	     * Appearance bevel button here. The only case that would
	     * exercise this is if you use a bitmap, with
	     * -data & -mask specified. We should probably draw the
	     * appearance button and overprint the image in this case.
	     * This just punts and draws the old-style, ugly, button.
	     */

	    if (dpPtr->gc->clip_mask == 0) {
		dpPtr->drawType = DRAW_BEVEL;
	    } else {
		TkpClipMask *clipPtr = (TkpClipMask *) dpPtr->gc->clip_mask;

		if ((clipPtr->type == TKP_CLIP_PIXMAP) &&
			(clipPtr->value.pixmap != butPtr->bitmap)) {
		    dpPtr->drawType = DRAW_CUSTOM;
		} else {
		    dpPtr->drawType = DRAW_BEVEL;
		}
	    }
	}
    } else if (butPtr->indicatorOn) {
	dpPtr->drawType = DRAW_CONTROL;
    } else if (dpPtr->hasImageOrBitmap) {
	if (dpPtr->gc->clip_mask == 0) {
	    dpPtr->drawType = DRAW_BEVEL;
	} else {
	    TkpClipMask *clipPtr = (TkpClipMask*) dpPtr->gc->clip_mask;

	    if ((clipPtr->type == TKP_CLIP_PIXMAP) &&
		    (clipPtr->value.pixmap != butPtr->bitmap)) {
		dpPtr->drawType = DRAW_CUSTOM;
	    } else {
		dpPtr->drawType = DRAW_BEVEL;
	    }
	}
d1612 17
a1628 1
	dpPtr->drawType = DRAW_CUSTOM;
d1632 1
a1632 1
	return 1;
d1634 1
a1634 1
	return 0;
@


1.2.2.16
log
@	* macosx/tkMacOSXWindowEvent.c:	ensure window is brought to the front
	* macosx/tkMacOSXMouseEvent.c:	at the start of a window drag (except
	* macosx/tkMacOSXInt.h:		when cmd key is down); formatting and
					whitespace fixes.

	* macosx/tkMacOSXDialog.c (Tk_GetSaveFileObjCmd): add -filetypes option
	processing.

	* macosx/tkMacOSXEmbed.c (TkpMakeWindow, TkpUseWindow): fix sending of
	Visibility event for embedded windows (fixes frame-3.9 hang).

	* macosx/tkMacOSXScrlbr.c (ScrollbarBindProc):		fix testsuite
	* macosx/tkMacOSXSubwindows.c (TkMacOSXUpdateClipRgn):	crashes by
	adding sanity checks.

	* macosx/tkMacOSXButton.c: fix debug msg typo.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.2.2.15 2007/04/29 02:26:47 das Exp $
d828 1
a828 1
	TkMacOSXDbgMsg("Failed to create control of type %d\n", procID);
@


1.2.2.17
log
@	* macosx/tkMacOSXWindowEvent.c (GenerateUpdateEvent): complete all
	pending idle-time redraws before newly posted Expose events are
	processed; add bounds of redrawn windows to update region to ensure all
	child windows overdrawn by parents are redrawn.

	* macosx/tkMacOSXWindowEvent.c:	centralize clip and window invalidation
	* macosx/tkMacOSXSubwindows.c:	after location/size changes in the
	* macosx/tkMacOSXWm.c:		BoundsChanged carbon event handler;
	correct/add window invalidation after window attribute changes.

	* macosx/tkMacOSXSubwindows.c (XResizeWindow, XMoveResizeWindow,
	XMoveWindow): factor out common code dealing with embedded and
	non-toplevel windows; remove unnecessary clip and window invalidation.

	* macosx/tkMacOSXButton.c (TkpDisplayButton): move clip setup closer to
	native button drawing calls.

	* macosx/tkMacOSXWm.c (TkMacOSXIsWindowZoomed, TkMacOSXZoomToplevel):
	correct handle gridded windows in max size calculations.

	* macosx/tkMacOSXEvent.c (TkMacOSXFlushWindows): use HIWindowFlush API
	when available.

	* macosx/tkMacOSXColor.c:	cleanup whitespace and formatting.
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWm.c:
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.2.2.16 2007/05/09 12:57:45 das Exp $
d228 9
a251 9
     * Set up clipping region. Make sure the we are using the port
     * for this button, or we will set the wrong window's clip.
     */

    destPort = TkMacOSXGetDrawablePort(pixmap);
    portChanged = QDSwapPort(destPort, &savePort);
    TkMacOSXSetUpClippingRgn(pixmap);

    /*
@


1.2.2.18
log
@	* macosx/tkMacOSXScrlbr.c: correct int <-> dobule conversion issues
	that could lead to Carbon getting confused about scrollbar thumb size.

	* macosx/tkMacOSXDraw.c (XCopyArea, XCopyPlane, TkPutImage) use
	TkMacOSX{Setup,Restore}DrawingContext() to setup/restore clip & colors.
	(TkMacOSXSetupDrawingContext, TkMacOSXRestoreDrawingContext): add save
	and restore of QD port clip region; factor out clip region code common
	to CG and QD branches; check for port and context validity; handle
	tkPictureIsOpen flag during QD port setup.
	(TkScrollWindow): remove unnecessary scroll region manipulation

	* macosx/tkMacOSXDraw.c:	remove second global QD temp region
	* macosx/tkMacOSXInt.h:		(no longer necessary) and rename
	* macosx/tkMacOSXRegion.c:	remaining global QD temp region.
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWindowEvent.c:

	* macosx/tkMacOSXDraw.c:	make useCGDrawing variable MODULE_SCOPE
	* macosx/tkMacOSXFont.c:	and sync formatting with HEAD.

	* macosx/tkMacOSXButton.c:	reduce reliance on current QD port
	* macosx/tkMacOSXColor.c:	setting and remove unnecessary
	* macosx/tkMacOSXDebug.c:	references to a drawable's QD port,
	* macosx/tkMacOSXDebug.h:	notably replace GetWindowFromPort(
	* macosx/tkMacOSXDialog.c:	TkMacOSXGetDrawablePort()) idiom by new
	* macosx/tkMacOSXDraw.c:	TkMacOSXDrawableWindow() and change
	* macosx/tkMacOSXKeyEvent.c:	TkMacOSXSetColorInPort() to take a port
	* macosx/tkMacOSXMenu.c:	argument.
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:

	* macosx/tkMacOSXInt.h:			factor out macros, declarations
	* macosx/tkMacOSXPrivate.h (new):	and prototypes that are purely
	internal and private to the 'macosx' sources into a new internal header
	file that does _not_ get installed into Tk.framework/PrivateHeaders.

	* macosx/tkMacOSXButton.c:		#include new tkMacOSXPrivate.h
	* macosx/tkMacOSXCarbonEvents.c:	instead of tkMacOSXInt.h.
	* macosx/tkMacOSXClipboard.c:
	* macosx/tkMacOSXColor.c:
	* macosx/tkMacOSXCursor.c:
	* macosx/tkMacOSXDebug.c:
	* macosx/tkMacOSXDialog.c:
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXEntry.c:
	* macosx/tkMacOSXEvent.c:
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXHLEvents.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXNotify.c:
	* macosx/tkMacOSXRegion.c:
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXXStubs.c:
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.2.2.17 2007/05/31 13:42:11 das Exp $
d17 1
a17 1
#include "tkMacOSXPrivate.h"
d792 2
a793 1
    mbPtr->windowRef = TkMacOSXDrawableWindow(Tk_WindowId(butPtr->tkwin));
d1241 1
a1241 3
    CGrafPtr port;
    
    GetPort(&port);
d1243 1
a1243 1
    TkMacOSXSetColorInPort(mbPtr->userPaneBackground, 0, NULL, port);
d1272 1
a1272 4
	CGrafPtr port;
	
	GetPort(&port);
	TkMacOSXSetColorInPort(mbPtr->userPaneBackground, 0, NULL, port);
@


1.2.2.19
log
@	Backport from HEAD of Aqua changes from 2007-10-12 to 2007-11-09
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.2.2.18 2007/06/29 03:22:00 das Exp $
a23 6
#define CONTROL_INITIALIZED 1
#define FIRST_DRAW	    2
#define ACTIVE		    4

#define MAX_VALUE	    1

d83 2
d93 1
d123 1
d157 8
d166 1
a166 1
    bzero(&macButtonPtr->fontStyle, sizeof(macButtonPtr->fontStyle));
d193 1
a193 1
    MacButton *macButtonPtr = (MacButton *) clientData;
d211 1
a374 6
#if 0
	    } else if ((butPtr->tristateImage != NULL) &&
		    (butPtr->flags & TRISTATED)) {
		Tk_RedrawImage(butPtr->tristateImage, 0, 0, width, height,
			pixmap, imageXOffset, imageYOffset);
#endif
a417 6
#if 0
	    } else if ((butPtr->tristateImage != NULL) &&
		    (butPtr->flags & TRISTATED)) {
		Tk_RedrawImage(butPtr->tristateImage, 0, 0, width, height,
			pixmap, imageXOffset, imageYOffset);
#endif
d717 1
a717 1
    if (TkMacOSXComputeDrawParams(butPtr, &drawParams)) {
d834 1
a834 4
    mbPtr->flags |= (CONTROL_INITIALIZED | FIRST_DRAW);
    if (IsWindowActive(mbPtr->windowRef)) {
	mbPtr->flags |= ACTIVE;
    }
a867 2
    int active, enabled;
    int rebuild;
d893 1
a893 6
#ifdef TK_REBUILD_TOPLEVEL
    rebuild = (winPtr->flags & TK_REBUILD_TOPLEVEL);
    winPtr->flags &= ~TK_REBUILD_TOPLEVEL;
#else
    rebuild = 0;
#endif
d898 1
a898 1
	if (rebuild || bcmp(&params, &mbPtr->params, sizeof(params))) {
d912 1
a912 1
    if (!(mbPtr->flags & CONTROL_INITIALIZED)) {
d936 1
a936 1
	if (rebuild || bcmp(mbPtr->controlTitle, controlTitle, len+1)) {
a963 4
#if 0
    } else if (butPtr->flags & TRISTATED) {
	SetControlValue(mbPtr->control, 2);
#endif
d968 10
a977 17
    active = ((mbPtr->flags & ACTIVE) != 0);
    if (active != IsControlActive(mbPtr->control)) {
	if (active) {
	    ChkErr(ActivateControl, mbPtr->control);
	} else {
	    ChkErr(DeactivateControl, mbPtr->control);
	}
    }
    enabled = !(butPtr->state == STATE_DISABLED);
    if (enabled != IsControlEnabled(mbPtr->control)) {
	if (enabled) {
	    ChkErr(EnableControl, mbPtr->control);
	} else {
	    ChkErr(DisableControl, mbPtr->control);
	}
    }
    if (active && enabled) {
a993 2
	} else {
	    HiliteControl(mbPtr->control, kControlNoPart);
d1010 1
a1010 1
    if (mbPtr->flags & FIRST_DRAW) {
d1013 1
a1013 1
	mbPtr->flags ^= FIRST_DRAW;
d1020 1
a1020 4
	if (mbPtr->bevelButtonContent.contentType ==
		kControlContentPictHandle) {
	    KillPicture(mbPtr->bevelButtonContent.u.picture);
	}
d1055 3
a1057 1
    Boolean portChanged = false;
d1072 12
a1083 17
    {
	portChanged = QDSwapPort(destPort, &savePort);
	mbPtr->picParams.version = -2;
	mbPtr->picParams.hRes = 0x00480000;
	mbPtr->picParams.vRes = 0x00480000;
	mbPtr->picParams.srcRect.top = 0;
	mbPtr->picParams.srcRect.left = 0;
	mbPtr->picParams.srcRect.bottom = height;
	mbPtr->picParams.srcRect.right = width;
	mbPtr->picParams.reserved1 = 0;
	mbPtr->picParams.reserved2 = 0;
	mbPtr->bevelButtonContent.contentType = kControlContentPictHandle;
	mbPtr->bevelButtonContent.u.picture = OpenCPicture(&mbPtr->picParams);
	if (!mbPtr->bevelButtonContent.u.picture) {
	    TkMacOSXDbgMsg("OpenCPicture failed");
	}
	tkPictureIsOpen = 1;
d1085 5
a1089 6
	/*
	 * TO DO - There is one case where XCopyPlane calls CopyDeepMask,
	 * which does not get recorded in the picture. So the bitmap code
	 * will fail in that case.
	 */
     }
a1092 5
#if 0
    } else if (butPtr->tristateImage != NULL && (butPtr->flags & TRISTATED)) {
	Tk_RedrawImage(butPtr->tristateImage, 0, 0, width, height, pixmap, 0,
		0);
#endif
d1101 3
a1103 7
    {
	ClosePicture();
	tkPictureIsOpen = 0;
	if (portChanged) {
	    QDSwapPort(savePort, NULL);
	}
    }
d1105 1
a1105 2
	    kControlBevelButtonContentTag,
	    sizeof(ControlButtonContentInfo),
d1127 1
d1149 3
a1352 1
    MacButton *mbPtr = (MacButton *) clientData;
a1358 5
	if (eventPtr->type == ActivateNotify) {
	    mbPtr->flags |= ACTIVE;
	} else {
	    mbPtr->flags &= ~ACTIVE;
	}
d1422 1
a1422 1
		paramsPtr->maxValue = MAX_VALUE;
d1428 1
a1428 1
		paramsPtr->maxValue = MAX_VALUE;
d1444 1
a1444 1
		paramsPtr->maxValue = MAX_VALUE;
d1450 1
a1450 1
		paramsPtr->maxValue = MAX_VALUE;
@


1.2.2.20
log
@	Backport from HEAD of Aqua changes from 2007-10-12 to 2007-11-09
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.2.2.19 2007/11/09 06:26:54 das Exp $
d903 1
a903 1
#if 0
@


1.2.2.21
log
@TkpDisplayButton: use computed borderWidth
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.2.2.20 2007/11/09 07:36:45 das Exp $
d493 1
a493 1
		    borderWidth, dpPtr->relief);
@


1.1
log
@file tkMacOSXButton.c was initially added on branch macosx-8-4-branch.
@
text
@d1 1580
@


1.1.2.1
log
@First checkin of support for Tk on Mac OS X.
@
text
@a0 1575
/* 
 * tkMacOSXButton.c --
 *
 *        This file implements the Macintosh specific portion of the
 *        button widgets.
 *
 * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
 * Copyright 2001, Apple Computer, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @@(#) $Id$
 */

#include "tkButton.h"
#include "tkMacOSXInt.h"
#include "tkMacOSXDebug.h"

#define DEFAULT_USE_TK_TEXT 0

/*
 * Default insets for controls
 */
#define DEF_INSET_LEFT 2
#define DEF_INSET_RIGHT 2
#define DEF_INSET_TOP 2
#define DEF_INSET_BOTTOM 4

#include <Carbon/Carbon.h>

/*
 * Some defines used to control what type of control is drawn.
 */

#define DRAW_LABEL        0                /* Labels are treated genericly. */
#define DRAW_CONTROL        1                /* Draw using the Native control. */
#define DRAW_CUSTOM        2                /* Make our own button drawing. */
#define DRAW_BEVEL        3

/*  
 * Declaration of Mac specific button structure.
 */

typedef struct {
    SInt16 initialValue;
    SInt16 minValue;
    SInt16 maxValue;
    SInt16 procID;
    int    isBevel;
} MacControlParams;

typedef struct {
    int drawType;
    Tk_3DBorder border;
    int relief;
    int offset;                        /* 0 means this is a normal widget.  1 means
                                 * it is an image button, so we offset the
                                 * image to make the button appear to move
                                 * up and down as the relief changes. */
    GC  gc;
    int hasImageOrBitmap;
} DrawParams;


typedef struct {
    TkButton                 info;       /* generic button info */
    int                      id;
    int                      usingControl;
    int                      useTkText;
    int                      flags;     /* initialisation status */
    MacControlParams         params;
    WindowRef                windowRef;
    RGBColor                 userPaneBackground;
    ControlRef               userPane;  /* Carbon control */
    ControlRef               control;   /* Carbon control */
    Str255                   controlTitle;
    ControlFontStyleRec      fontStyle;
    /* 
     * the following are used to store the image content for
     * beveled buttons - i.e. buttons with images.
     */
    CCTabHandle              tabHandle;
    ControlButtonContentInfo bevelButtonContent;
    OpenCPicParams           picParams;
    Pixmap                   picPixmap;
} MacButton;

/*
 * Forward declarations for procedures defined later in this file:
 */


static OSErr SetUserPaneDrawProc(ControlRef control,
        ControlUserPaneDrawProcPtr upp);
static OSErr SetUserPaneSetUpSpecialBackgroundProc(ControlRef control,
        ControlUserPaneBackgroundProcPtr upp);
static void UserPaneDraw(ControlRef control, ControlPartCode cpc);
static void UserPaneBackgroundProc(ControlHandle,
        ControlBackgroundPtr info);

static void ButtonEventProc _ANSI_ARGS_(( ClientData clientData, XEvent *eventPtr));
static int UpdateControlColors _ANSI_ARGS_((MacButton *mbPtr ));
static void TkMacOSXComputeControlParams _ANSI_ARGS_((TkButton * butPtr, MacControlParams * paramsPtr));
static int TkMacOSXComputeDrawParams _ANSI_ARGS_((TkButton * butPtr, DrawParams * dpPtr));
static void TkMacOSXDrawControl _ANSI_ARGS_((MacButton *butPtr,
        GWorldPtr destPort, GC gc, Pixmap pixmap));
static void SetupBevelButton _ANSI_ARGS_((MacButton *butPtr,
        ControlRef controlHandle, 
        GWorldPtr destPort, GC gc, Pixmap pixmap));
int Tk_GetFirstTextLayout( Tk_TextLayout layout, Tk_Font * font, char * dst ); 
void TkMacOSXInitControlFontStyle(Tk_Font tkfont,ControlFontStylePtr fsPtr);


/*
 * The class procedure table for the button widgets.
 */

Tk_ClassProcs tkpButtonProcs = { 
    sizeof(Tk_ClassProcs),        /* size */
    TkButtonWorldChanged,        /* worldChangedProc */
};

static int bCount;

int tkPictureIsOpen;

/*
 *----------------------------------------------------------------------
 *
 * 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)
{
    MacButton *macButtonPtr;
    macButtonPtr = (MacButton *) ckalloc(sizeof(MacButton));
    Tk_CreateEventHandler(tkwin, ActivateMask,
            ButtonEventProc, (ClientData) macButtonPtr);
    macButtonPtr->id=bCount++;
    macButtonPtr->usingControl=0;
    macButtonPtr->flags=0;
    macButtonPtr->userPaneBackground.red=0;
    macButtonPtr->userPaneBackground.green=0;
    macButtonPtr->userPaneBackground.blue=~0;
    macButtonPtr->userPane=NULL;
    macButtonPtr->control=NULL;
    macButtonPtr->controlTitle[0]=
    macButtonPtr->controlTitle[1]=0;
    macButtonPtr->picParams.version = -2;
    macButtonPtr->picParams.hRes = 0x00480000;
    macButtonPtr->picParams.vRes = 0x00480000;
    macButtonPtr->picParams.srcRect.top = 0;
    macButtonPtr->picParams.srcRect.left = 0;
    macButtonPtr->picParams.reserved1 = 0;
    macButtonPtr->picParams.reserved2 = 0;
    macButtonPtr->bevelButtonContent.contentType = kControlContentPictHandle;
    bzero(&macButtonPtr->params, sizeof(macButtonPtr->params));
    bzero(&macButtonPtr->fontStyle,sizeof(macButtonPtr->fontStyle));
    return (TkButton *)macButtonPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayButton --
 *
 *        This procedure 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.
 *
 *----------------------------------------------------------------------
 */

void
TkpDisplayButton(
    ClientData clientData)        /* Information about widget. */
{
    MacButton *macButtonPtr = (MacButton *)clientData;
    TkButton  *butPtr       = (TkButton *) clientData;
    Tk_Window tkwin         = butPtr->tkwin;
    int x = 0;                  /* Initialization only needed to stop
                                 * compiler warning. */
    int y;
    int width, height, fullWidth, fullHeight;
    int imageXOffset, imageYOffset, textXOffset, textYOffset;
    int haveImage = 0, haveText = 0;
    GWorldPtr destPort;
    int borderWidth;
    Pixmap pixmap;
    int wasUsingControl;
    DrawParams drawParams, * dpPtr = &drawParams;

    butPtr->flags &= ~REDRAW_PENDING;
    if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
        return;
    }

    pixmap = (Pixmap) Tk_WindowId(tkwin);
    wasUsingControl = macButtonPtr->usingControl;

    if (TkMacOSXComputeDrawParams(butPtr, &drawParams) ) {
        macButtonPtr->usingControl=1;
        macButtonPtr->useTkText=DEFAULT_USE_TK_TEXT;
    } else {
        macButtonPtr->usingControl=0;
        macButtonPtr->useTkText=1;
    }
   
    /* 
     * set up clipping region 
     */
    
    TkMacOSXSetUpClippingRgn(pixmap);

    /*
     * See the comment in UpdateControlColors as to why we use the 
     * highlightbackground for the border of Macintosh buttons.
     */

    if (macButtonPtr->useTkText) {
        if (butPtr->type == TYPE_BUTTON) {
            Tk_Fill3DRectangle(tkwin, pixmap, butPtr->highlightBorder, 0, 0,
                Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
        } else {
            Tk_Fill3DRectangle(tkwin, pixmap, butPtr->normalBorder, 0, 0,
                Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
        }
    }

    /*
     * Draw the native portion of the buttons. Start by creating the control
     * if it doesn't already exist.  Then configure the Macintosh control from
     * the Tk info.  Finally, we call Draw1Control to draw to the screen.
     */

    if (macButtonPtr->usingControl) {
        borderWidth = 0;
        /*
         * This part uses Macintosh rather than Tk calls to draw
         * to the screen.  Make sure the ports etc. are set correctly.
         */
         
        destPort = TkMacOSXGetDrawablePort(pixmap);
        SetGWorld(destPort, NULL);
        TkMacOSXDrawControl(macButtonPtr, destPort, dpPtr->gc, pixmap);
    } else {
       if (wasUsingControl && macButtonPtr->userPane) {
           DisposeControl(macButtonPtr->userPane);
           macButtonPtr->userPane = NULL;
           macButtonPtr->control  = NULL;
           macButtonPtr->flags = 0;
       }
    }

    if ((dpPtr->drawType == DRAW_CUSTOM) || (dpPtr->drawType == DRAW_LABEL)) {
        borderWidth = butPtr->borderWidth;
    }

    /*
     * Display image or bitmap or text for button.  This has
     * already been done under Appearance with the Bevel
     * button types.
     */

    if (dpPtr->drawType == DRAW_BEVEL) {
        /* Empty Body */
    } else {
        if (butPtr->image != None) {
            Tk_SizeOfImage(butPtr->image, &width, &height);
            haveImage = 1;
        } else if (butPtr->bitmap != None) {
            Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
            haveImage = 1;
        }
        haveText = (butPtr->textWidth != 0 && butPtr->textHeight != 0);
        if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) {
            imageXOffset = 0;
            imageYOffset = 0;
            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;
            
            x += dpPtr->offset;
            y += dpPtr->offset;
            if (dpPtr->relief == TK_RELIEF_RAISED) {
                x -= dpPtr->offset;
                y -= dpPtr->offset;
            } else if (dpPtr->relief == TK_RELIEF_SUNKEN) {
                x += dpPtr->offset;
                y += dpPtr->offset;
            }
            
            if (butPtr->image != NULL) {
                if ((butPtr->selectImage != NULL) &&
                        (butPtr->flags & SELECTED)) {
                    Tk_RedrawImage(butPtr->selectImage, 0, 0,
                            width, height, pixmap, x + imageXOffset,
                            y + imageYOffset);
                } else {
                    Tk_RedrawImage(butPtr->image, 0, 0, width,
                            height, pixmap, x + imageXOffset,
                            y + imageYOffset);
                }
            } else {
                XSetClipOrigin(butPtr->display, dpPtr->gc, x + imageXOffset,
                        y + imageYOffset);
                XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, dpPtr->gc,
                        0, 0, (unsigned int) width,
                        (unsigned int) height, x + imageXOffset,
                        y + imageYOffset, 1);
                XSetClipOrigin(butPtr->display, dpPtr->gc, 0, 0);
            }
            
            if (macButtonPtr->useTkText ) {
                Tk_DrawTextLayout(butPtr->display, pixmap, 
                        dpPtr->gc, butPtr->textLayout,
                        x + textXOffset, y + textYOffset, 0, -1);
                Tk_UnderlineTextLayout(butPtr->display, pixmap, dpPtr->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;
                
                x += dpPtr->offset;
                y += dpPtr->offset;
                if (dpPtr->relief == TK_RELIEF_RAISED) {
                    x -= dpPtr->offset;
                    y -= dpPtr->offset;
                } else if (dpPtr->relief == TK_RELIEF_SUNKEN) {
                    x += dpPtr->offset;
                    y += dpPtr->offset;
                }
                if (butPtr->image != NULL) {
                    if ((butPtr->selectImage != NULL) &&
                            (butPtr->flags & SELECTED)) {
                        Tk_RedrawImage(butPtr->selectImage, 0, 0, width,
                                height,        pixmap, x, y);
                    } else {
                        Tk_RedrawImage(butPtr->image, 0, 0, width, height,
                                pixmap, x, y);
                    }
                } else {

                    XSetClipOrigin(butPtr->display, dpPtr->gc, x, y);
                    XCopyPlane(butPtr->display, butPtr->bitmap, 
                            pixmap, dpPtr->gc,
                            0, 0, (unsigned int) width,
                            (unsigned int) height, x, y, 1);
                    XSetClipOrigin(butPtr->display, dpPtr->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;
                
                if (macButtonPtr->useTkText) {
                    Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc,
                        butPtr->textLayout, x, y, 0, -1);
                }
                y += butPtr->textHeight/2;
            }
        }
    }

    /*
     * 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.
     */

    if (macButtonPtr->useTkText) {
        if ((butPtr->state == STATE_DISABLED)
                && ((butPtr->disabledFg == NULL) || (butPtr->image != NULL))) {
            if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn
                && (butPtr->selectBorder != NULL)) {
                XSetForeground(butPtr->display, butPtr->disabledGC,
                Tk_3DBorderColor(butPtr->selectBorder)->pixel);
            }
                XFillRectangle(butPtr->display, pixmap, butPtr->disabledGC,
                butPtr->inset, butPtr->inset,
                (unsigned) (Tk_Width(tkwin) - 2*butPtr->inset),
                (unsigned) (Tk_Height(tkwin) - 2*butPtr->inset));
            if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn
                && (butPtr->selectBorder != NULL)) {
                    XSetForeground(butPtr->display, butPtr->disabledGC,
                    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.
         */
         
        if (dpPtr->relief != TK_RELIEF_FLAT) {
            int inset = butPtr->highlightWidth;
            Tk_Draw3DRectangle(tkwin, pixmap, dpPtr->border, inset, inset,
                Tk_Width(tkwin) - 2*inset, Tk_Height(tkwin) - 2*inset,
                butPtr->borderWidth, dpPtr->relief);
        }
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpComputeButtonGeometry --
 *
 *        After changes in a button's text or bitmap, this procedure
 *        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(
    TkButton *butPtr)        /* Button whose geometry may have changed. */
{
    int width, height, avgWidth, haveImage = 0, haveText;
    int xInset, yInset;
    int txtWidth, txtHeight;
    Tk_FontMetrics fm;
    DrawParams drawParams;

    /*
     * First figure out the size of the contents of the button.
     */
     
    width = 0;
    height = 0;
    txtWidth = 0;
    txtHeight = 0;
    avgWidth = 0;

     
    butPtr->indicatorSpace = 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 (ie, 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;
            }
        }
    }

    /*
     * Now figure out the size of the border decorations for the button.
     */
     
    if (butPtr->highlightWidth < 0) {
        butPtr->highlightWidth = 0;
    }
    
    /*
     * The width and height calculation for Appearance buttons with images & 
     * non-Appearance buttons with images is different.         In the latter case, 
     * we add the borderwidth to the inset, since we are going to stamp a
     * 3-D border over the image.  In the former, we add it to the height,
     * directly, since Appearance will draw the border as part of our control.
     *
     * When issuing the geometry request, add extra space for the indicator,
     * if any, and for the border and padding, plus if this is an image two 
     * extra pixels so the display can be offset by 1 pixel in either
     * direction for the raised or lowered effect.
     *
     * The highlight width corresponds to the default ring on the Macintosh.
     * As such, the highlight width is only added if the button is the default
     * button.        The actual width of the default ring is one less than the
     * highlight width as there is also one pixel of spacing.
     * Appearance buttons with images do not have a highlight ring, because the 
     * Bevel button type does not support one.
     */

    if ((butPtr->image == None) && (butPtr->bitmap == None)) {
        width += 2*butPtr->padX;
        height += 2*butPtr->padY;
    }
    
    if ((butPtr->type == TYPE_BUTTON)) {
        if ((butPtr->image == None) && (butPtr->bitmap == None)) {
            butPtr->inset = 0;
            if (butPtr->defaultState != STATE_DISABLED) {
                butPtr->inset += butPtr->highlightWidth;
            }
        } else  {
            butPtr->inset = 0;
            width += (2 * butPtr->borderWidth + 4);
            height += (2 * butPtr->borderWidth + 4);
        }
    } else if ((butPtr->type != TYPE_LABEL)) {
        if (butPtr->indicatorOn) {
            butPtr->inset = 0;
        } else {
            /*
             * Under Appearance, the Checkbutton or radiobutton with an image
             * is represented by a BevelButton with the Sticky defProc...  
             * So we must set its height in the same way as the Button 
             * with an image or bitmap.
             */
             
            if ( (butPtr->image != None) || (butPtr->bitmap != None)) {
                int border;
                butPtr->inset = 0;
                if ( butPtr->borderWidth <= 2 ) {
                    border = 6;
                }  else {
                    border = 2 * butPtr->borderWidth + 2;
                }               
                width += border;
                height += border;
            } else {
                butPtr->inset = butPtr->borderWidth;
            }        
        }        
    } else {
        butPtr->inset = butPtr->borderWidth;
    }

    if (TkMacOSXComputeDrawParams(butPtr,&drawParams)) {
        xInset = butPtr->indicatorSpace + DEF_INSET_LEFT + DEF_INSET_RIGHT;
        yInset = DEF_INSET_TOP + DEF_INSET_BOTTOM;
    } else {
        xInset = butPtr->indicatorSpace+butPtr->inset*2;
        yInset = butPtr->inset*2;
    }
    Tk_GeometryRequest(butPtr->tkwin, width + xInset, height + yInset);
    Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDestroyButton --
 *
 *        Free data structures associated with the button control.
 *
 * Results:
 *        None.
 *
 * Side effects:
 *        Restores the default control state.
 *
 *----------------------------------------------------------------------
 */

void
TkpDestroyButton(
    TkButton *butPtr)
{
    MacButton *mbPtr = ( MacButton *) butPtr; /* Mac button. */
    if (mbPtr->userPane) {
        DisposeControl(mbPtr->userPane);
        mbPtr->userPane = NULL;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXInitControl --
 *
 *        This procedure initialises a Carbon control
 *
 * Results:
 *        0 on success, 1 on failure.
 *
 * Side effects:
 *        A background pane control and the control itself is created
 *      The contol is embedded in the background control
 *      The background control is embedded in the root control
 *      of the containing window
 *      The creation parameters for the control are also computed
 *
 *----------------------------------------------------------------------
 */

int
TkMacOSXInitControl (
    MacButton *mbPtr,                /* Mac button. */
    GWorldPtr  destPort,
    GC         gc,
    Pixmap     pixmap,
    Rect      *paneRect,
    Rect      *cntrRect
)
{
    OSErr      status;
    TkButton * butPtr = ( TkButton * )mbPtr;
    ControlRef rootControl;
    SInt16     procID;
    Boolean    initiallyVisible;
    SInt16     initialValue;
    SInt16     minValue;
    SInt16     maxValue;
    SInt32     controlReference;

    rootControl = TkMacOSXGetRootControl(Tk_WindowId(butPtr->tkwin));
    mbPtr->windowRef
            = GetWindowFromPort(TkMacOSXGetDrawablePort(Tk_WindowId(butPtr->tkwin)));

    /* 
     * Set up the user pane
     */

    initiallyVisible=false;
    initialValue=kControlSupportsEmbedding|   
        kControlHasSpecialBackground;
    minValue=0;
    maxValue=1;
    procID=kControlUserPaneProc;
    controlReference=(SInt32)mbPtr;
    mbPtr->userPane=NewControl(mbPtr->windowRef,
        paneRect, "\p",
        initiallyVisible,
        initialValue,
        minValue,
        maxValue,
        procID,
        controlReference );
        
    if (!mbPtr->userPane) {
        fprintf(stderr,"Failed to create user pane control\n");
        return 1;
    }
    
    if ((status=EmbedControl(mbPtr->userPane,rootControl))!=noErr) {
        fprintf(stderr,"Failed to embed user pane control %d\n", status);
        return 1;
    }
    
    SetUserPaneSetUpSpecialBackgroundProc(mbPtr->userPane,
        UserPaneBackgroundProc);
    SetUserPaneDrawProc(mbPtr->userPane,UserPaneDraw);
    initiallyVisible=false;
    TkMacOSXComputeControlParams(butPtr,&mbPtr->params);
    mbPtr->control=NewControl(mbPtr->windowRef,
        cntrRect, "\p",
        initiallyVisible,
        mbPtr->params.initialValue,
        mbPtr->params.minValue,
        mbPtr->params.maxValue,
        mbPtr->params.procID,
        controlReference );
        
    if (!mbPtr->control) {
        fprintf(stderr,"failed to create control of type %d\n",procID);
        return 1;
    }
    
    if (EmbedControl(mbPtr->control,mbPtr->userPane) != noErr ) {
        fprintf(stderr,"failed to embed control of type %d\n",procID);
        return 1;
    }
    
    mbPtr->flags|=(1 + 2);
    return 0;
}

/*
 *--------------------------------------------------------------
 *
 * TkMacOSXDrawControl --
 *
 *        This function draws the tk button using Mac controls
 *        In addition, this code may apply custom colors passed 
 *        in the TkButton.
 *
 * Results:
 *        None.
 *
 * Side effects:
 *      The control is created, or reinitialised as needed
 *
 *
 *--------------------------------------------------------------
 */

static void
TkMacOSXDrawControl(
    MacButton *mbPtr,    /* Mac button. */
    GWorldPtr destPort,  /* Off screen GWorld. */
    GC gc,               /* The GC we are drawing into - needed for
                          * the bevel button */
    Pixmap pixmap)       /* The pixmap we are drawing into - needed
                          * for the bevel button */
                
{
    TkButton * butPtr = ( TkButton *)mbPtr;
    int        err;
    TkWindow * winPtr;
    Rect       paneRect;
    Rect       cntrRect;
    int        hilitePart = -1;


    winPtr=(TkWindow *)butPtr->tkwin;
   
    paneRect.left = winPtr->privatePtr->xOff;
    paneRect.top = winPtr->privatePtr->yOff;
    paneRect.right = paneRect.left + Tk_Width(butPtr->tkwin);
    paneRect.bottom = paneRect.top + Tk_Height(butPtr->tkwin);

    cntrRect=paneRect;

/*
    cntrRect.left+=butPtr->inset;
    cntrRect.top+=butPtr->inset;
    cntrRect.right-=butPtr->inset;
    cntrRect.bottom-=butPtr->inset;
*/
    cntrRect.left+=DEF_INSET_LEFT;
    cntrRect.top+=DEF_INSET_TOP;
    cntrRect.right-=DEF_INSET_RIGHT;
    cntrRect.bottom-=DEF_INSET_BOTTOM;

    /* 
     * The control has been previously initialised
     * It may need to be re-initialised 
     */
     
    if (mbPtr->flags) {
        MacControlParams params;
        TkMacOSXComputeControlParams(butPtr, &params);
        if (bcmp(&params, &mbPtr->params, sizeof(params))) {
            /* 
             * the type of control has changed
             * Clean it up and clear the flag 
             */
             
            if (mbPtr->userPane) {
                DisposeControl(mbPtr->userPane);
                mbPtr->userPane = NULL;
                mbPtr->control = NULL;
            }
            mbPtr->flags = 0;
        }
    }
    if (!(mbPtr->flags & 1)) {
        if (TkMacOSXInitControl(mbPtr, destPort, gc, 
                pixmap, &paneRect, &cntrRect) ) {
            return;
        }
    }
    SetControlBounds(mbPtr->userPane, &paneRect);
    SetControlBounds(mbPtr->control, &cntrRect);

    if (!mbPtr->useTkText) {
        Str255              controlTitle;
        ControlFontStyleRec fontStyle;
        Tk_Font    font;
        int        len;
        
        len = Tk_GetFirstTextLayout(butPtr->textLayout, 
                &font, controlTitle + 1);
        controlTitle[len + 1] = 0;
        controlTitle[0] = len;
        if (bcmp(mbPtr->controlTitle, controlTitle, len+2)) {
            SetControlTitle(mbPtr->control, controlTitle);
            bcopy(controlTitle, mbPtr->controlTitle, len+2);
        }
        if (len) {
            TkMacOSXInitControlFontStyle(font, &fontStyle);
            if (bcmp(&mbPtr->fontStyle, &fontStyle, sizeof(fontStyle)) ) {
                if (SetControlFontStyle(mbPtr->control, &fontStyle) != noErr) {
                    fprintf(stderr,"SetControlFontStyle failed\n");
                }
                bcopy(&fontStyle, &mbPtr->fontStyle, 
                        sizeof(fontStyle));
            }
        }
    }
    if (mbPtr->params.isBevel) {
        /* Initialiase the image/button parameters */
        SetupBevelButton(mbPtr, mbPtr->control, destPort, 
                      gc, pixmap);
    }

    if (butPtr->flags & SELECTED) {
     SetControlValue(mbPtr->control, 1);
    } else {
     SetControlValue(mbPtr->control, 0);
    }
    
    if (!Tk_MacOSXIsAppInFront() || butPtr->state == STATE_DISABLED) {
        HiliteControl(mbPtr->control, kControlInactivePart);
    } else if (butPtr->state == STATE_ACTIVE) {
        if (mbPtr->params.isBevel) {
           HiliteControl(mbPtr->control, kControlButtonPart);
        } else {
            switch (butPtr->type) {
                case TYPE_BUTTON:
                    HiliteControl(mbPtr->control,  kControlButtonPart);
                    break;
                case TYPE_RADIO_BUTTON:
                    HiliteControl(mbPtr->control, kControlRadioButtonPart);
                    break;
                case TYPE_CHECK_BUTTON:
                    HiliteControl(mbPtr->control, kControlCheckBoxPart);
                    break;
            }
        }
    } else {
        HiliteControl(mbPtr->control, kControlNoPart);
    }
    UpdateControlColors(mbPtr);
        
    if ((butPtr->type == TYPE_BUTTON) ) {
        Boolean isDefault;
        
        if (butPtr->defaultState == STATE_ACTIVE) {
            isDefault = true;
        } else {
            isDefault = false;
        }
        if ((err=SetControlData(mbPtr->control, kControlNoPart, 
                kControlPushButtonDefaultTag,
                sizeof(isDefault), (Ptr) &isDefault)) != noErr ) {
        }
    }

    if (mbPtr->flags&2) {
        ShowControl(mbPtr->control);
        ShowControl(mbPtr->userPane);
        mbPtr->flags ^= 2;
    } else {
        Draw1Control(mbPtr->userPane);
        SetControlVisibility(mbPtr->control, true, true);
    }
 
    if (mbPtr->params.isBevel) {
        KillPicture(mbPtr->bevelButtonContent.u.picture);
    }         
}

/*
 *--------------------------------------------------------------
 *
 * SetupBevelButton --
 *
 *        Sets up the Bevel Button with image by copying the
 *        source image onto the PicHandle for the button.
 *
 * Results:
 *        None
 *
 * Side effects:
 *        The image or bitmap for the button is copied over to a picture.
 *
 *--------------------------------------------------------------
 */
void
SetupBevelButton(
    MacButton *mbPtr,                /* Mac button. */
    ControlRef controlHandle,         /* The control to set this picture to */
    GWorldPtr destPort,                /* Off screen GWorld. */
    GC gc,                        /* The GC we are drawing into - needed for
                                 * the bevel button */
    Pixmap pixmap                /* The pixmap we are drawing into - needed
                                   for the bevel button */
    )
{
    int       err;
    TkButton *butPtr = ( TkButton *)mbPtr;
    int height, width;
    ControlButtonGraphicAlignment theAlignment;
    
    SetPort(destPort);

    if (butPtr->image != None) {
        Tk_SizeOfImage(butPtr->image, 
                &width, &height);
    } else {
        Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, 
                &width, &height);
    }
            
    if ((butPtr->width > 0) && (butPtr->width < width)) {
        width = butPtr->width;
    }
    if ((butPtr->height > 0) && (butPtr->height < height)) {
        height = butPtr->height;
    }

    mbPtr->picParams.srcRect.right = width;
    mbPtr->picParams.srcRect.bottom = height;

    /* 
     * Set the flag to circumvent clipping and bounds problems with OS 10.0.4 
     */
     
    if (!(mbPtr->bevelButtonContent.u.picture 
            = OpenCPicture(&mbPtr->picParams)) ) {
        fprintf(stderr,"OpenCPicture failed\n");
    }
    tkPictureIsOpen = 1;
    
    /*
     * TO DO - There is one case where XCopyPlane calls CopyDeepMask,
     * which does not get recorded in the picture.  So the bitmap code
     * will fail in that case.
     */
     
    if ((butPtr->selectImage != NULL) && (butPtr->flags & SELECTED)) {
        Tk_RedrawImage(butPtr->selectImage, 0, 0, width, height,
                pixmap, 0, 0);
    } else if (butPtr->image != NULL) {
        Tk_RedrawImage(butPtr->image, 0, 0, width, 
                height, pixmap, 0, 0);
    } else {                        
        XSetClipOrigin(butPtr->display, gc, 0, 0);
        XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, gc, 0, 0,
                (unsigned int) width, (unsigned int) height, 0, 0, 1);
    }
    
    ClosePicture();
    tkPictureIsOpen = 0;
    
    if ( (err=SetControlData(controlHandle, kControlButtonPart,
            kControlBevelButtonContentTag,
            sizeof(ControlButtonContentInfo),
            (char *) &mbPtr->bevelButtonContent)) != noErr ) {
        fprintf(stderr,
                "SetControlData BevelButtonContent failed, %d\n", err );
    }
            
    if (butPtr->anchor == TK_ANCHOR_N) {
        theAlignment = kControlBevelButtonAlignTop;
    } else if (butPtr->anchor == TK_ANCHOR_NE) { 
        theAlignment = kControlBevelButtonAlignTopRight;
    } else if (butPtr->anchor == TK_ANCHOR_E) { 
        theAlignment = kControlBevelButtonAlignRight;
    } else if (butPtr->anchor == TK_ANCHOR_SE) {
        theAlignment = kControlBevelButtonAlignBottomRight;
    } else if (butPtr->anchor == TK_ANCHOR_S) {
        theAlignment = kControlBevelButtonAlignBottom;
    } else if (butPtr->anchor == TK_ANCHOR_SW) {
        theAlignment = kControlBevelButtonAlignBottomLeft;
    } else if (butPtr->anchor == TK_ANCHOR_W) {
        theAlignment = kControlBevelButtonAlignLeft;
    } else if (butPtr->anchor == TK_ANCHOR_NW) {
        theAlignment = kControlBevelButtonAlignTopLeft;
    } else if (butPtr->anchor == TK_ANCHOR_CENTER) {
        theAlignment = kControlBevelButtonAlignCenter;
    }

    if ((err=SetControlData(controlHandle, kControlButtonPart,
            kControlBevelButtonGraphicAlignTag,
            sizeof(ControlButtonGraphicAlignment),
            (char *) &theAlignment)) != noErr ) {
        fprintf(stderr,
                "SetControlData BevelButtonGraphicAlign failed, %d\n", err );
    }

}

/*
 *--------------------------------------------------------------
 *
 * SetUserPaneDrawProc --
 *
 *        Utility function to add a UserPaneDrawProc
 *        to a userPane control.        From MoreControls code
 *        from Apple DTS.
 *
 * Results:
 *        MacOS system error.
 *
 * Side effects:
 *        The user pane gets a new UserPaneDrawProc.
 *
 *--------------------------------------------------------------
 */
OSErr SetUserPaneDrawProc (
    ControlRef control,
    ControlUserPaneDrawProcPtr upp)
{
    ControlUserPaneDrawUPP myControlUserPaneDrawUPP;
    myControlUserPaneDrawUPP = NewControlUserPaneDrawUPP(upp);        
    return SetControlData (control, 
            kControlNoPart, kControlUserPaneDrawProcTag, 
            sizeof(myControlUserPaneDrawUPP), 
            (Ptr) &myControlUserPaneDrawUPP);
}

/*
 *--------------------------------------------------------------
 *
 * SetUserPaneSetUpSpecialBackgroundProc --
 *
 *        Utility function to add a UserPaneBackgroundProc
 *        to a userPane control
 *
 * Results:
 *        MacOS system error.
 *
 * Side effects:
 *        The user pane gets a new UserPaneBackgroundProc.
 *
 *--------------------------------------------------------------
 */
OSErr
SetUserPaneSetUpSpecialBackgroundProc(
    ControlRef control, 
    ControlUserPaneBackgroundProcPtr upp)
{
    ControlUserPaneBackgroundUPP myControlUserPaneBackgroundUPP;
    myControlUserPaneBackgroundUPP = NewControlUserPaneBackgroundUPP(upp);
    return SetControlData (control, kControlNoPart, 
            kControlUserPaneBackgroundProcTag, 
            sizeof(myControlUserPaneBackgroundUPP), 
            (Ptr) &myControlUserPaneBackgroundUPP);
}

/*
 *--------------------------------------------------------------
 *
 * UserPaneDraw --
 *
 *        This function draws the background of the user pane that will 
 *        lie under checkboxes and radiobuttons.
 *
 * Results:
 *        None.
 *
 * Side effects:
 *        The user pane gets updated to the current color.
 *
 *--------------------------------------------------------------
 */
void
UserPaneDraw(
    ControlRef control,
    ControlPartCode cpc)
{
    Rect contrlRect;
    MacButton * mbPtr;
    mbPtr = ( MacButton *)GetControlReference(control);
    GetControlBounds(control,&contrlRect);
    RGBBackColor (&mbPtr->userPaneBackground);
    EraseRect (&contrlRect);
}

/*
 *--------------------------------------------------------------
 *
 * UserPaneBackgroundProc --
 *
 *        This function sets up the background of the user pane that will 
 *        lie under checkboxes and radiobuttons.
 *
 * Results:
 *        None.
 *
 * Side effects:
 *        The user pane background gets set to the current color.
 *
 *--------------------------------------------------------------
 */

void
UserPaneBackgroundProc(
    ControlHandle control,
    ControlBackgroundPtr info)
{
    MacButton * mbPtr;
    mbPtr = ( MacButton *)GetControlReference(control);
    if (info->colorDevice) {
        RGBBackColor (&mbPtr->userPaneBackground);
    }
}

/*
 *--------------------------------------------------------------
 *
 * UpdateControlColors --
 *
 *        This function will review the colors used to display
 *        a Macintosh button.  If any non-standard colors are
 *        used we create a custom palette for the button, populate
 *        with the colors for the button and install the palette.
 *
 *        Under Appearance, we just set the pointer that will be
 *        used by the UserPaneDrawProc.
 *
 * Results:
 *        None.
 *
 * Side effects:
 *        The Macintosh control may get a custom palette installed.
 *
 *--------------------------------------------------------------
 */

static int
UpdateControlColors(MacButton * mbPtr)
{
    XColor *xcolor;
    TkButton * butPtr = ( TkButton * )mbPtr;
    
    /*
     * Under Appearance we cannot change the background of the
     * button itself.  However, the color we are setting is the color
     * of the containing userPane.  This will be the color that peeks 
     * around the rounded corners of the button.  
     * We make this the highlightbackground rather than the background,
     * because if you color the background of a frame containing a
     * button, you usually also color the highlightbackground as well,
     * or you will get a thin grey ring around the button.
     */
      
    if (butPtr->type == TYPE_BUTTON) {
        xcolor = Tk_3DBorderColor(butPtr->highlightBorder);
    } else {
        xcolor = Tk_3DBorderColor(butPtr->normalBorder);
    }
    TkSetMacColor(xcolor->pixel, &mbPtr->userPaneBackground);
    
    return false;
}
/*
 *--------------------------------------------------------------
 *
 * ButtonEventProc --
 *
 *        This procedure is invoked by the Tk dispatcher for various
 *        events on buttons.
 *
 * Results:
 *        None.
 *
 * Side effects:
 *      When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
ButtonEventProc(
    ClientData clientData,        /* Information about window. */
    XEvent *eventPtr)                /* Information about event. */
{
    TkButton *buttonPtr = (TkButton *) clientData;
    if (eventPtr->type == ActivateNotify
            || eventPtr->type == DeactivateNotify) {
        if ((buttonPtr->tkwin == NULL) 
                || (!Tk_IsMapped(buttonPtr->tkwin))) {
            return;
        }
        if ((buttonPtr->flags & REDRAW_PENDING) == 0) {
            Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) buttonPtr);
            buttonPtr->flags |= REDRAW_PENDING;
        }
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXComputeControlParams --
 *
 *        This procedure computes the various parameters used
 *        when creating a Carbon control (NewControl)
 *      These are determined by the various tk button parameters
 *
 * Results:
 *        None.
 *
 * Side effects:
 *        Sets the control initialisation parameters
 *
 *----------------------------------------------------------------------
 */

static void
TkMacOSXComputeControlParams(TkButton * butPtr, MacControlParams * paramsPtr )
{
    paramsPtr->isBevel = 0;
    
    /* 
     * Determine ProcID based on button type and dimensions 
     */
     
    switch (butPtr->type) {
        case TYPE_BUTTON:
            if ((butPtr->image == None) && (butPtr->bitmap == None)) {
                paramsPtr->initialValue = 1;
                paramsPtr->minValue = 0;
                paramsPtr->maxValue = 1;
                paramsPtr->procID = kControlPushButtonProc;
            } else {
                paramsPtr->initialValue = 0;
                paramsPtr->minValue = kControlBehaviorOffsetContents
                    | kControlContentPictHandle;
                paramsPtr->maxValue = 1;
                if (butPtr->borderWidth <= 2) {
                    paramsPtr->procID = kControlBevelButtonSmallBevelProc;
                } else if (butPtr->borderWidth == 3) {
                    paramsPtr->procID = kControlBevelButtonNormalBevelProc;
                } else {
                    paramsPtr->procID = kControlBevelButtonLargeBevelProc;
                }
                paramsPtr->isBevel = 1;                
            }
            break;
        case TYPE_RADIO_BUTTON:
            if (((butPtr->image == None) && (butPtr->bitmap == None))
                || (butPtr->indicatorOn)) {
                paramsPtr->initialValue = 1;
                paramsPtr->minValue = 0;
                paramsPtr->maxValue = 1;
                paramsPtr->procID = kControlRadioButtonProc;
            } else {
                paramsPtr->initialValue = 0;
                paramsPtr->minValue = kControlBehaviorOffsetContents|
                    kControlBehaviorSticky|
                    kControlContentPictHandle;
                paramsPtr->maxValue = 1;
                if (butPtr->borderWidth <= 2) {
                    paramsPtr->procID = kControlBevelButtonSmallBevelProc;
                } else if (butPtr->borderWidth == 3) {
                    paramsPtr->procID = kControlBevelButtonNormalBevelProc;
                } else {
                    paramsPtr->procID = kControlBevelButtonLargeBevelProc;
                }
                paramsPtr->isBevel = 1;                
            }
            break;
        case TYPE_CHECK_BUTTON:
            if (((butPtr->image == None) 
                    && (butPtr->bitmap == None))
                    || (butPtr->indicatorOn)) {
                paramsPtr->initialValue = 1;
                paramsPtr->minValue = 0;
                paramsPtr->maxValue = 1;
                paramsPtr->procID = kControlCheckBoxProc;
            } else {
                paramsPtr->initialValue = 0;
                paramsPtr->minValue = kControlBehaviorOffsetContents
                    | kControlBehaviorSticky
                    | kControlContentPictHandle;
                paramsPtr->maxValue = 1;
                if (butPtr->borderWidth <= 2) {
                    paramsPtr->procID = kControlBevelButtonSmallBevelProc;
                } else if (butPtr->borderWidth == 3) {
                    paramsPtr->procID = kControlBevelButtonNormalBevelProc;
                } else {
                    paramsPtr->procID = kControlBevelButtonLargeBevelProc;
                }
                paramsPtr->isBevel = 1;                
            }   
            break;
    }
}
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXComputeDrawParams --
 *
 *        This procedure computes the various parameters used
 *        when drawing a button
 *      These are determined by the various tk button parameters
 *
 * Results:
 *        1 if control will be used, 0 otherwise.
 *
 * Side effects:
 *        Sets the button draw parameters
 *
 *----------------------------------------------------------------------
 */

static int
TkMacOSXComputeDrawParams(TkButton * butPtr, DrawParams * dpPtr)
{
    dpPtr->hasImageOrBitmap = ((butPtr->image != NULL) 
            || (butPtr->bitmap != None));
    dpPtr->offset = (butPtr->type == TYPE_BUTTON) 
            && dpPtr->hasImageOrBitmap;
    dpPtr->border = butPtr->normalBorder;
    if ((butPtr->state == STATE_DISABLED) 
            && (butPtr->disabledFg != NULL)) {
        dpPtr->gc = butPtr->disabledGC;
    } else if ((butPtr->type == TYPE_BUTTON)
            && (butPtr->state == STATE_ACTIVE)) {
        dpPtr->gc = butPtr->activeTextGC;
        dpPtr->border = butPtr->activeBorder;
    } else {
        dpPtr->gc = butPtr->normalTextGC;
    }

    if ((butPtr->flags & SELECTED) 
            && (butPtr->state != STATE_ACTIVE)
            && (butPtr->selectBorder != NULL) 
            && !butPtr->indicatorOn) {
       dpPtr->border = butPtr->selectBorder;
    }
    
    /*
     * Override the relief specified for the button if this is a
     * checkbutton or radiobutton and there's no indicator.
     * However, don't do this in the presence of Appearance, since
     * then the bevel button will take care of the relief.
     */

    dpPtr->relief = butPtr->relief;

    if ((butPtr->type >= TYPE_CHECK_BUTTON) && !butPtr->indicatorOn) {
        if (!dpPtr->hasImageOrBitmap) {
            dpPtr->relief = (butPtr->flags & SELECTED) ? TK_RELIEF_SUNKEN
                : TK_RELIEF_RAISED;
        }
    }

    /*
     * Determine the draw type
     */
    if (butPtr->type == TYPE_LABEL) {
        dpPtr->drawType = DRAW_LABEL;
    } else if (butPtr->type == TYPE_BUTTON) {
        if (!dpPtr->hasImageOrBitmap) {
            dpPtr->drawType = DRAW_CONTROL;
        } else if (butPtr->image != None) {
            dpPtr->drawType = DRAW_BEVEL;
        } else {
            /*
             * TO DO - The current way the we draw bitmaps (XCopyPlane)
             * uses CopyDeepMask in this one case.  The Picture recording 
             * does not record this call, and so we can't use the
             * Appearance bevel button here.  The only case that would
             * exercise this is if you use a bitmap, with
             * -data & -mask specified.         We should probably draw the 
             * appearance button and overprint the image in this case.
             * This just punts and draws the old-style, ugly, button.
             */
             
            if (dpPtr->gc->clip_mask == 0) {
                dpPtr->drawType = DRAW_BEVEL;
            } else {
                TkpClipMask *clipPtr = (TkpClipMask*) dpPtr->gc->clip_mask;
                if ((clipPtr->type == TKP_CLIP_PIXMAP) &&
                        (clipPtr->value.pixmap != butPtr->bitmap)) {
                    dpPtr->drawType = DRAW_CUSTOM;
                } else {
                    dpPtr->drawType = DRAW_BEVEL;
                }
            }
        }
    } else {
        if (butPtr->indicatorOn) {
            dpPtr->drawType = DRAW_CONTROL;
        } else if (dpPtr->hasImageOrBitmap) {
            if (dpPtr->gc->clip_mask == 0) {
                dpPtr->drawType = DRAW_BEVEL;
            } else {
                TkpClipMask *clipPtr = (TkpClipMask*) dpPtr->gc->clip_mask;
                if ((clipPtr->type == TKP_CLIP_PIXMAP) &&
                        (clipPtr->value.pixmap != butPtr->bitmap)) {
                    dpPtr->drawType = DRAW_CUSTOM;
                } else {
                    dpPtr->drawType = DRAW_BEVEL;
                }
            }
        } else {
            dpPtr->drawType = DRAW_CUSTOM;
        }
    }

    if ((dpPtr->drawType == DRAW_CONTROL) || (dpPtr->drawType == DRAW_BEVEL)) {
        return 1;
    } else {
        return 0;
    }
}
@


1.1.2.2
log
@button and menubutton encodings
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.1.2.1 2001/10/15 09:22:00 wolfsuit Exp $
d956 6
a961 11
                &font, controlTitle);
        controlTitle[len] = 0;
        if (bcmp(mbPtr->controlTitle, controlTitle, len+1)) {
            CFStringRef cf;    	    
            cf = CFStringCreateWithCString(NULL,
                  controlTitle, kCFStringEncodingMacRoman);
            if (cf != NULL) {
            SetControlTitleWithCFString(mbPtr->control, cf);
            CFRelease(cf);
            }
            bcopy(controlTitle, mbPtr->controlTitle, len+1);
@


1.1.2.3
log
@encoding issues, proxy icons
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkMacOSXButton.c,v 1.1.2.2 2002/07/16 14:32:57 vincentdarley Exp $
d961 1
a961 1
                  controlTitle, kCFStringEncodingUTF8);
@


1.1.2.4
log
@whitespace & other cleanup
wish startup code cleanup induced by new support in tcl for standard MacOSX tcl package locations
renamed Tk_GetFirstTextLayout to private TkFontGetFirstTextLayout
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id$
d111 2
a113 2
extern int TkFontGetFirstTextLayout(Tk_TextLayout layout, Tk_Font * font, char * dst); 
extern void TkMacOSXInitControlFontStyle(Tk_Font tkfont,ControlFontStylePtr fsPtr);
d955 1
a955 1
        len = TkFontGetFirstTextLayout(butPtr->textLayout, 
@


1.1.2.5
log
@various project cleanups & enhancements
added macosx/Makefile to facilitate building from cli
added [tk windowingsystem] and removed $::tcl_plaform(windowingsystem)
changed all runtime library references to the above
removed duplicate entries in tk.decls & tkInt.decls
CONSTification and other small changes in macosx/ to remove compiler warnings
@
text
@d514 1
a514 1
    int width, height, avgWidth, haveImage = 0, haveText = 0;
@


