summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvincentdarley <vincentdarley>2003-07-18 11:04:58 (GMT)
committervincentdarley <vincentdarley>2003-07-18 11:04:58 (GMT)
commited5580c0df82dff12f9679b64ba4bf1424adfd0f (patch)
treea7f72cab9fe59571cc55d0f567aab23a8ad11a66
parent2a536d15c96c18d94c90cfb3eb881e912a960964 (diff)
downloadtk-ed5580c0df82dff12f9679b64ba4bf1424adfd0f.zip
tk-ed5580c0df82dff12f9679b64ba4bf1424adfd0f.tar.gz
tk-ed5580c0df82dff12f9679b64ba4bf1424adfd0f.tar.bz2
MacOSX fixes
-rw-r--r--ChangeLog13
-rw-r--r--generic/tkWindow.c4
-rw-r--r--macosx/tkMacOSXDialog.c394
-rw-r--r--macosx/tkMacOSXMenu.c9
-rw-r--r--macosx/tkMacOSXMouseEvent.c16
5 files changed, 429 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 02d9114..eafc1b4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2003-07-18 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tkWindow.c:
+ * macosx/tkMacOSXDialog.c: added native tk_messageBox command,
+ (Tk_MessageBoxObjCmd) for MacOS X platform.
+
+ * macosx/tkMacOSXMenu.c: corrected encoding conversion for
+ torn-off menu entries (but many other display problems still
+ exist with these)
+
+ * macosx/tkMacOSXMouseEvent.c: improved handling of events in the
+ presence of grabs, particularly activation events.
+
2003-07-18 Donal K. Fellows <fellowsd@cs.man.ac.uk>
* tests/panedwindow.test (panedwindow-30.2):
diff --git a/generic/tkWindow.c b/generic/tkWindow.c
index e374c2f..db0c69a 100644
--- a/generic/tkWindow.c
+++ b/generic/tkWindow.c
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkWindow.c,v 1.58 2003/07/16 22:54:08 hobbs Exp $
+ * RCS: @(#) $Id: tkWindow.c,v 1.59 2003/07/18 11:04:58 vincentdarley Exp $
*/
#include "tkPort.h"
@@ -142,7 +142,7 @@ static TkCmd commands[] = {
{"tk_getOpenFile", NULL, Tk_GetOpenFileObjCmd, 0, 1},
{"tk_getSaveFile", NULL, Tk_GetSaveFileObjCmd, 0, 1},
#endif
-#ifdef __WIN32__
+#ifdef defined(__WIN32__) || defined(MAC_OSX_TK)
{"tk_messageBox", NULL, Tk_MessageBoxObjCmd, 0, 1},
#endif
{"update", NULL, Tk_UpdateObjCmd, 1, 1},
diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c
index 8da90f6..e38cabd 100644
--- a/macosx/tkMacOSXDialog.c
+++ b/macosx/tkMacOSXDialog.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkMacOSXDialog.c,v 1.4 2003/02/25 16:09:23 das Exp $
+ * RCS: @(#) $Id: tkMacOSXDialog.c,v 1.5 2003/07/18 11:04:59 vincentdarley Exp $
*/
#include <Carbon/Carbon.h>
@@ -58,6 +58,18 @@ typedef struct _OpenFileData {
} OpenFileData;
+/*
+ * The following structure is used in the tk_messageBox
+ * implementation.
+ */
+typedef struct {
+ WindowRef windowRef;
+ int buttonIndex;
+} CallbackUserData;
+
+
+static OSStatus AlertHandler _ANSI_ARGS_(( EventHandlerCallRef callRef,
+ EventRef eventRef, void *userData ));
static Boolean MatchOneType _ANSI_ARGS_((StringPtr fileNamePtr, OSType fileType,
OpenFileData *myofdPtr, FileFilter *filterPtr));
static pascal Boolean OpenFileFilterProc(AEDesc* theItem, void* info,
@@ -1226,3 +1238,383 @@ TkAboutDlg()
return;
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_MessageBoxObjCmd --
+ *
+ * Implements the tk_messageBox in native Mac OS X style.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * none
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tk_MessageBoxObjCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
+{
+ Tk_Window tkwin = (Tk_Window) clientData;
+ AlertStdCFStringAlertParamRec paramCFStringRec;
+ AlertType alertType;
+ DialogRef dialogRef;
+ CFStringRef messageTextCF = NULL;
+ CFStringRef finemessageTextCF = NULL;
+ OSErr osError;
+ SInt16 itemHit;
+ Boolean haveDefaultOption = false;
+ Boolean haveParentOption = false;
+ char *str;
+ int index;
+ int defaultButtonIndex;
+ int defaultNativeButtonIndex; /* 1, 2, 3: right to left. */
+ int typeIndex;
+ int i;
+ int indexDefaultOption;
+ int result = TCL_OK;
+
+ static CONST char *movableAlertStrings[] = {
+ "-default", /* "-finemessage", */ "-icon",
+ "-message", "-parent",
+ "-title", "-type",
+ (char *)NULL
+ };
+ static CONST char *movableTypeStrings[] = {
+ "abortretryignore", "ok",
+ "okcancel", "retrycancel",
+ "yesno", "yesnocancel",
+ (char *)NULL
+ };
+ static CONST char *movableButtonStrings[] = {
+ "abort", "retry", "ignore",
+ "ok", "cancel", "yes", "no",
+ (char *)NULL
+ };
+ static CONST char *movableIconStrings[] = {
+ "error", "info", "question", "warning",
+ (char *)NULL
+ };
+ enum movableAlertOptions {
+ ALERT_DEFAULT, /* ALERT_FINEMESSAGE, */ ALERT_ICON,
+ ALERT_MESSAGE, ALERT_PARENT,
+ ALERT_TITLE, ALERT_TYPE
+ };
+ enum movableTypeOptions {
+ TYPE_ABORTRETRYIGNORE, TYPE_OK,
+ TYPE_OKCANCEL, TYPE_RETRYCANCEL,
+ TYPE_YESNO, TYPE_YESNOCANCEL
+ };
+ enum movableButtonOptions {
+ TEXT_ABORT, TEXT_RETRY, TEXT_IGNORE,
+ TEXT_OK, TEXT_CANCEL, TEXT_YES, TEXT_NO
+ };
+ enum movableIconOptions {
+ ICON_ERROR, ICON_INFO, ICON_QUESTION, ICON_WARNING
+ };
+
+ /*
+ * Need to map from 'movableButtonStrings' and its corresponding integer index,
+ * to the native button index, which is 1, 2, 3, from right to left.
+ * This is necessary to do for each separate '-type' of button sets.
+ */
+
+ short buttonIndexAndTypeToNativeButtonIndex[][7] = {
+ /* abort retry ignore ok cancel yes no */
+ {1, 2, 3, 0, 0, 0, 0}, /* abortretryignore */
+ {0, 0, 0, 1, 0, 0, 0}, /* ok */
+ {0, 0, 0, 1, 2, 0, 0}, /* okcancel */
+ {0, 1, 0, 0, 2, 0, 0}, /* retrycancel */
+ {0, 0, 0, 0, 0, 1, 2}, /* yesno */
+ {0, 0, 0, 0, 3, 1, 2}, /* yesnocancel */
+ };
+
+ /*
+ * Need also the inverse mapping, from native button (1, 2, 3) to the
+ * descriptive button text string index.
+ */
+
+ short nativeButtonIndexAndTypeToButtonIndex[][4] = {
+ {-1, 0, 1, 2}, /* abortretryignore */
+ {-1, 3, 0, 0}, /* ok */
+ {-1, 3, 4, 0}, /* okcancel */
+ {-1, 1, 4, 0}, /* retrycancel */
+ {-1, 5, 6, 0}, /* yesno */
+ {-1, 5, 6, 4}, /* yesnocancel */
+ };
+
+ alertType = kAlertPlainAlert;
+ typeIndex = TYPE_OK;
+
+ GetStandardAlertDefaultParams( &paramCFStringRec, kStdCFStringAlertVersionOne );
+ paramCFStringRec.movable = true;
+ paramCFStringRec.helpButton = false;
+ paramCFStringRec.defaultButton = kAlertStdAlertOKButton;
+
+ for (i = 1; i < objc; i += 2) {
+ int iconIndex;
+ char *string;
+
+ if (Tcl_GetIndexFromObj( interp, objv[i], movableAlertStrings, "option",
+ TCL_EXACT, &index ) != TCL_OK) {
+ result = TCL_ERROR;
+ goto end;
+ }
+ if (i + 1 == objc) {
+ string = Tcl_GetStringFromObj( objv[i], NULL );
+ Tcl_AppendResult(interp, "value for \"", string, "\" missing",
+ (char *) NULL);
+ result = TCL_ERROR;
+ goto end;
+ }
+
+ switch (index) {
+
+ case ALERT_DEFAULT:
+
+ /*
+ * Need to postpone processing of this option until we are
+ * sure to know the '-type' as well.
+ */
+
+ haveDefaultOption = true;
+ indexDefaultOption = i;
+ break;
+
+/* case ALERT_FINEMESSAGE:
+ str = Tcl_GetStringFromObj( objv[i + 1], NULL );
+ finemessageTextCF = CFStringCreateWithCString( NULL, str, kCFStringEncodingUTF8 );
+ break;
+*/
+ case ALERT_ICON:
+ /* not sure about UTF translation here... */
+ if (Tcl_GetIndexFromObj( interp, objv[i + 1], movableIconStrings,
+ "value", TCL_EXACT, &iconIndex ) != TCL_OK) {
+ result = TCL_ERROR;
+ goto end;
+ }
+ switch (iconIndex) {
+ case ICON_ERROR:
+ alertType = kAlertStopAlert;
+ break;
+ case ICON_INFO:
+ alertType = kAlertNoteAlert;
+ break;
+ case ICON_QUESTION:
+ alertType = kAlertCautionAlert;
+ break;
+ case ICON_WARNING:
+ alertType = kAlertCautionAlert;
+ break;
+ }
+ break;
+
+ case ALERT_MESSAGE:
+ str = Tcl_GetStringFromObj( objv[i + 1], NULL );
+ messageTextCF = CFStringCreateWithCString( NULL, str, kCFStringEncodingUTF8 );
+ break;
+
+ case ALERT_PARENT:
+ str = Tcl_GetStringFromObj( objv[i + 1], NULL );
+ tkwin = Tk_NameToWindow( interp, str, tkwin );
+ if (tkwin == NULL) {
+ result = TCL_ERROR;
+ goto end;
+ }
+ haveParentOption= true;
+ break;
+
+ case ALERT_TITLE:
+ break;
+
+ case ALERT_TYPE:
+ /* not sure about UTF translation here... */
+ if (Tcl_GetIndexFromObj( interp, objv[i + 1], movableTypeStrings,
+ "value", TCL_EXACT, &typeIndex ) != TCL_OK) {
+ result = TCL_ERROR;
+ goto end;
+ }
+ switch (typeIndex) {
+ case TYPE_ABORTRETRYIGNORE:
+ paramCFStringRec.defaultText = CFSTR("Abort");
+ paramCFStringRec.cancelText = CFSTR("Retry");
+ paramCFStringRec.otherText = CFSTR("Ignore");
+ break;
+ case TYPE_OK:
+ paramCFStringRec.defaultText = CFSTR("OK");
+ break;
+ case TYPE_OKCANCEL:
+ paramCFStringRec.defaultText = CFSTR("OK");
+ paramCFStringRec.cancelText = CFSTR("Cancel");
+ break;
+ case TYPE_RETRYCANCEL:
+ paramCFStringRec.defaultText = CFSTR("Retry");
+ paramCFStringRec.cancelText = CFSTR("Cancel");
+ break;
+ case TYPE_YESNO:
+ paramCFStringRec.defaultText = CFSTR("Yes");
+ paramCFStringRec.cancelText = CFSTR("No");
+ break;
+ case TYPE_YESNOCANCEL:
+ paramCFStringRec.defaultText = CFSTR("Yes");
+ paramCFStringRec.cancelText = CFSTR("No");
+ paramCFStringRec.otherText = CFSTR("Cancel");
+ break;
+ }
+ break;
+ }
+ }
+
+ if (haveDefaultOption) {
+
+ /*
+ * Any '-default' option needs to know the '-type' option, which is why
+ * we do this here.
+ */
+
+ str = Tcl_GetStringFromObj( objv[indexDefaultOption + 1], NULL );
+ if (Tcl_GetIndexFromObj( interp, objv[indexDefaultOption + 1],
+ movableButtonStrings, "value", TCL_EXACT,
+ &defaultButtonIndex ) != TCL_OK) {
+ result = TCL_ERROR;
+ goto end;
+ }
+
+ /* Need to map from "ok" etc. to 1, 2, 3, right to left. */
+
+ defaultNativeButtonIndex =
+ buttonIndexAndTypeToNativeButtonIndex[typeIndex][defaultButtonIndex];
+ if (defaultNativeButtonIndex == 0) {
+ Tcl_SetObjResult( interp,
+ Tcl_NewStringObj( "Illegel default option", -1 ));
+ result = TCL_ERROR;
+ goto end;
+ }
+ paramCFStringRec.defaultButton = defaultNativeButtonIndex;
+ }
+ SetThemeCursor( kThemeArrowCursor );
+
+ if (haveParentOption) {
+ TkWindow *winPtr;
+ MacDrawable *macWin;
+ WindowRef windowRef;
+ EventTargetRef notifyTarget;
+ EventHandlerUPP handler;
+ CallbackUserData data;
+ const EventTypeSpec kEvents[] = {
+ {kEventClassCommand, kEventProcessCommand}
+ };
+
+ winPtr = (TkWindow *) tkwin;
+
+ /*
+ * Create the underlying Mac window for this Tk window.
+ */
+
+ macWin = (MacDrawable *) winPtr->window;
+ windowRef = GetWindowFromPort( TkMacOSXGetDrawablePort((Drawable) macWin) );
+ notifyTarget = GetWindowEventTarget( windowRef );
+ osError = CreateStandardSheet( alertType, messageTextCF,
+ finemessageTextCF, &paramCFStringRec,
+ notifyTarget, &dialogRef );
+ if(osError != noErr) {
+ result = TCL_ERROR;
+ goto end;
+ }
+ data.windowRef = windowRef;
+ data.buttonIndex = 1;
+ handler = NewEventHandlerUPP( AlertHandler );
+ InstallEventHandler( notifyTarget, handler, GetEventTypeCount(kEvents), &kEvents, &data, NULL );
+ osError = ShowSheetWindow( GetDialogWindow(dialogRef), windowRef );
+ if(osError != noErr) {
+ result = TCL_ERROR;
+ goto end;
+ }
+ osError = RunAppModalLoopForWindow( windowRef );
+
+ itemHit = data.buttonIndex;
+ DisposeEventHandlerUPP( handler );
+ } else {
+ osError = CreateStandardAlert( alertType, messageTextCF,
+ finemessageTextCF, &paramCFStringRec, &dialogRef );
+ if(osError != noErr) {
+ result = TCL_ERROR;
+ goto end;
+ }
+ osError = RunStandardAlert( dialogRef, NULL, &itemHit );
+ }
+ if(osError == noErr) {
+ int ind;
+
+ /*
+ * Map 'itemHit' (1, 2, 3) to descriptive text string.
+ */
+
+ ind = nativeButtonIndexAndTypeToButtonIndex[typeIndex][itemHit];
+ Tcl_SetObjResult( interp,
+ Tcl_NewStringObj( movableButtonStrings[ind], -1 ));
+ } else {
+ result = TCL_ERROR;
+ }
+
+ end:
+ if (finemessageTextCF != NULL) {
+ CFRelease( finemessageTextCF );
+ }
+ if (messageTextCF != NULL) {
+ CFRelease( messageTextCF );
+ }
+ return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AlertHandler --
+ *
+ * Carbon event handler for the Standard Sheet dialog.
+ *
+ * Results:
+ * OSStatus if event handled or not.
+ *
+ * Side effects:
+ * May set userData.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static OSStatus
+AlertHandler( EventHandlerCallRef callRef, EventRef eventRef, void *userData )
+{
+ OSStatus result = eventNotHandledErr;
+ HICommand cmd;
+ CallbackUserData *dataPtr = (CallbackUserData *) userData;
+
+ GetEventParameter( eventRef, kEventParamDirectObject, typeHICommand,
+ NULL, sizeof(cmd), NULL, &cmd );
+ switch (cmd.commandID) {
+ case kHICommandOK:
+ dataPtr->buttonIndex = 1;
+ result = noErr;
+ break;
+ case kHICommandCancel:
+ dataPtr->buttonIndex = 2;
+ result = noErr;
+ break;
+ case kHICommandOther:
+ dataPtr->buttonIndex = 3;
+ result = noErr;
+ break;
+ }
+ if (result == noErr) {
+ result = QuitAppModalLoopForWindow( dataPtr->windowRef );
+ }
+ return result;
+}
diff --git a/macosx/tkMacOSXMenu.c b/macosx/tkMacOSXMenu.c
index bfaff7e..a69e871 100644
--- a/macosx/tkMacOSXMenu.c
+++ b/macosx/tkMacOSXMenu.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkMacOSXMenu.c,v 1.8 2003/03/12 05:56:21 wolfsuit Exp $
+ * RCS: @(#) $Id: tkMacOSXMenu.c,v 1.9 2003/07/18 11:04:59 vincentdarley Exp $
*/
#include "tkMacOSXInt.h"
#include "tkMenuButton.h"
@@ -3427,6 +3427,8 @@ DrawMenuEntryLabel(
GDHandle saveDevice;
GWorldPtr destPort;
#ifdef USE_ATSU
+ int xLocation;
+ int yLocation;
int runLengths;
CFStringRef stringRef;
ATSUTextLayout textLayout;
@@ -3472,7 +3474,8 @@ DrawMenuEntryLabel(
#ifdef USE_ATSU
runLengths = 1;
length = Tcl_DStringLength(&itemTextDString);
- stringRef = CFStringCreateWithCString(NULL, Tcl_DStringValue(&itemTextDString), GetApplicationTextEncoding());
+ stringRef = CFStringCreateWithCString(NULL, Tcl_DStringValue(&itemTextDString),
+ kCFStringEncodingUTF8);
if (!stringRef) {
fprintf(stderr,"CFStringCreateWithCString failed\n");
}
@@ -3494,7 +3497,7 @@ DrawMenuEntryLabel(
TkMacOSXSetUpGraphicsPort(gc, destPort);
MoveTo((short) leftEdge, (short) baseline);
- Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&itemTextDString),
+ Tcl_UtfToExternalDString(TkMacOSXCarbonEncoding, Tcl_DStringValue(&itemTextDString),
Tcl_DStringLength(&itemTextDString), &convertedTextDString);
#ifdef USE_ATSU
xLocation = leftEdge<<16;
diff --git a/macosx/tkMacOSXMouseEvent.c b/macosx/tkMacOSXMouseEvent.c
index 2516ef8..6a18426 100644
--- a/macosx/tkMacOSXMouseEvent.c
+++ b/macosx/tkMacOSXMouseEvent.c
@@ -271,11 +271,25 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr)
if (!(TkpIsWindowFloating(medPtr->whichWin))
&& (medPtr->whichWin != medPtr->activeNonFloating)) {
Tk_Window grabWin = TkMacOSXGetCapture();
+ if ((grabWin == NULL)) {
+ int grabState = TkGrabState((TkWindow*)tkwin);
+ if (grabState != TK_GRAB_NONE && grabState != TK_GRAB_IN_TREE) {
+ /* Now we want to set the focus to the local grabWin */
+ TkMacOSXSetEatButtonUp(true);
+ grabWin = (Tk_Window) (((TkWindow*)tkwin)->dispPtr->grabWinPtr);
+ BringWindowForward(GetWindowFromPort(TkMacOSXGetDrawablePort(((TkWindow*)grabWin)->window)));
+ statusPtr->stopProcessing = 1;
+ return false;
+ }
+ }
if ((grabWin != NULL) && (grabWin != tkwin)) {
TkWindow * tkw, * grb;
tkw = (TkWindow *)tkwin;
grb = (TkWindow *)grabWin;
- SysBeep(1);
+ /* Now we want to set the focus to the global grabWin */
+ TkMacOSXSetEatButtonUp(true);
+ BringWindowForward(GetWindowFromPort(TkMacOSXGetDrawablePort(((TkWindow*)grabWin)->window)));
+ statusPtr->stopProcessing = 1;
return false;
}