-- cgit v0.12 From 73ff727f2c72d26737eed09892846d5f4ff2f7b2 Mon Sep 17 00:00:00 2001 From: simonbachmann Date: Mon, 17 Apr 2017 09:51:02 +0000 Subject: Proposed fix for 22ace0d494 (documentation only) --- doc/FindPhoto.3 | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/doc/FindPhoto.3 b/doc/FindPhoto.3 index e4d83f0..3f6b919 100644 --- a/doc/FindPhoto.3 +++ b/doc/FindPhoto.3 @@ -130,14 +130,23 @@ The \fIpixelPtr\fR field points to the first pixel, that is, the top-left pixel in the block. The \fIwidth\fR and \fIheight\fR fields specify the dimensions of the block of pixels. The \fIpixelSize\fR field specifies the address -difference between two horizontally adjacent pixels. Often it is 3 -or 4, but it can have any value. The \fIpitch\fR field specifies the +difference between two horizontally adjacent pixels. It should be 4 for +RGB and 2 for grayscale image data. Other values are possible, if the +offsets in the \fIoffset\fR array are adjusted accordingly (e.g. for +red, green and blue data stored in different planes). Using such a +layout is strongly discouraged, though. Due to a bug, it might not work +correctly if an alpha channel is provided. (see the \fBBUGS\fR section +below). The \fIpitch\fR field specifies the address difference between two vertically adjacent pixels. The \fIoffset\fR array contains the offsets from the address of a pixel to the addresses of the bytes containing the red, green, blue and alpha -(transparency) components. These are normally 0, 1, 2 and 3, but can -have other values, e.g., for images that are stored as separate red, -green and blue planes. +(transparency) components. If the offsets for red, green and blue are +equal, the image is interpreted as grayscale. If they differ, RGB data +is assumed. Normally the offsets will be 0, 1, 2, 3 for RGB data +and 0, 0, 0, 1 for grayscale. It is possible to provide image data +without an alpha channel by setting the offset for alpha to a negative +value and adjusting the \fIpixelSize\fR field accordingly. This use is +discouraged, though (see the \fBBUGS\fR section below). .PP The \fIcompRule\fR parameter to \fBTk_PhotoPutBlock\fR specifies a compositing rule that says what to do with transparent pixels. The @@ -248,6 +257,24 @@ memory was available for an image, Tk would panic. This behaviour is still supported if you compile your extension with the additional flag -DUSE_PANIC_ON_PHOTO_ALLOC_FAILURE. Code linked using Stubs against older versions of Tk will continue to work. +.SH BUGS +The \fBTk_PhotoImageBlock\fR structure used to provide image data to +\fBTk_PhotoPutBlock\fR promises great flexibility in the layout of the +data (e.g. separate planes for the red, green, blue and alpha +channels). Unfortunately, the implementation fails to hold this +promise. The problem is that the \fIpixelSize\fR field is +(incorrectly) used to determine wehter the image has an alpha channel. +Currently, if the offset for the alpha channel is greater or equal than +\fIpixelSize\fR, \fBtk_PhotoPutblock\fR assumes no alpha data is +present and makes the image fully opaque. This means that for layouts +where the channels are separate (or any other exotic layout where +\fIpixelSize\fR has to be smaller than the alpha offset), the alpha +channel will not be read correctly. In order to be on the safe side +if this issue will be corrected in a future release, it is strongly +recommended you always provide alpha data - even if the image has no +transparency - and only use the "standard" layout with a +\fIpixelSize\fR of 2 for grayscale and 4 for RGB data with +\fIoffset\fRs of 0, 0, 0, 1 or 0, 1, 2, 3 respectively. .SH CREDITS .PP The code for the photo image type was developed by Paul Mackerras, -- cgit v0.12 From 63b6554668963fa5a4b94cd64931e556ad154fcb Mon Sep 17 00:00:00 2001 From: Kevin Walzer Date: Thu, 20 Apr 2017 01:47:21 +0000 Subject: 1. Fix for segfault with latest version of Xcode on macOS 10.12; thanks to Bill Joye for patch. 2. Improvements to HITheme scroller on macOS: smoother scrolling, and scrollbar now correctly highlights when being pressed and during enter/leave events. Thanks to Tortsen Reincke for bug report (061bf93176a5684a4a855f8177b290c59dd39bf2). --- macosx/tkMacOSXScrlbr.c | 81 ++++++++++++++++++++++++++++++------------------- macosx/tkMacOSXWm.c | 5 ++- macosx/tkMacOSXWm.h | 4 +-- 3 files changed, 55 insertions(+), 35 deletions(-) diff --git a/macosx/tkMacOSXScrlbr.c b/macosx/tkMacOSXScrlbr.c index 91cf112..6253fff 100644 --- a/macosx/tkMacOSXScrlbr.c +++ b/macosx/tkMacOSXScrlbr.c @@ -19,6 +19,13 @@ #define MIN_SCROLLBAR_VALUE 0 +/* + * Minimum slider length, in pixels (designed to make sure that the slider is + * always easy to grab with the mouse). + */ + +#define MIN_SLIDER_LENGTH 5 + /*Borrowed from ttkMacOSXTheme.c to provide appropriate scaling of scrollbar values.*/ #ifdef __LP64__ #define RangeToFactor(maximum) (((double) (INT_MAX >> 1)) / (maximum)) @@ -60,16 +67,14 @@ typedef struct ScrollbarMetrics { } ScrollbarMetrics; static ScrollbarMetrics metrics[2] = { - {15, 54, 26, 14, 14, NSRegularControlSize}, /* kThemeScrollBarMedium */ - {11, 40, 20, 10, 10, NSSmallControlSize}, /* kThemeScrollBarSmall */ + {15, 54, 26, 14, 14, kControlSizeNormal}, /* kThemeScrollBarMedium */ + {11, 40, 20, 10, 10, kControlSizeSmall}, /* kThemeScrollBarSmall */ }; - HIThemeTrackDrawInfo info = { .version = 0, .min = 0.0, .max = 100.0, .attributes = kThemeTrackShowThumb, - .kind = kThemeScrollBarMedium, }; @@ -107,7 +112,7 @@ TkpCreateScrollbar( scrollPtr->troughGC = None; scrollPtr->copyGC = None; - Tk_CreateEventHandler(tkwin,ExposureMask|StructureNotifyMask|FocusChangeMask|ButtonPressMask|VisibilityChangeMask, ScrollbarEventProc, scrollPtr); + Tk_CreateEventHandler(tkwin,ExposureMask|StructureNotifyMask|FocusChangeMask|ButtonPressMask|ButtonReleaseMask|EnterWindowMask|LeaveWindowMask|VisibilityChangeMask, ScrollbarEventProc, scrollPtr); return (TkScrollbar *) scrollPtr; } @@ -212,7 +217,8 @@ TkpDisplayScrollbar( *---------------------------------------------------------------------- */ -extern void + + extern void TkpComputeScrollbarGeometry( register TkScrollbar *scrollPtr) /* Scrollbar whose geometry may have @@ -259,14 +265,12 @@ TkpComputeScrollbarGeometry( if (scrollPtr->sliderLast > fieldLength) { scrollPtr->sliderLast = fieldLength; } - if (!(MOUNTAIN_LION_STYLE)) { - scrollPtr->sliderFirst += scrollPtr->inset + - metrics[variant].topArrowHeight; - scrollPtr->sliderLast += scrollPtr->inset + - metrics[variant].bottomArrowHeight; - } - /* - * Register the desired geometry for the window (leave enough space + + scrollPtr->sliderFirst += scrollPtr->arrowLength + scrollPtr->inset; + scrollPtr->sliderLast += scrollPtr->arrowLength + scrollPtr->inset; + + + /* Register the desired geometry for the window (leave enough space * for the two arrows plus a minimum-size slider, plus border around * the whole window, if any). Then arrange for the window to be * redisplayed. @@ -281,6 +285,9 @@ TkpComputeScrollbarGeometry( } + + + /* *---------------------------------------------------------------------- * @@ -376,21 +383,22 @@ TkpScrollbarPosition( register const int arrowSize = scrollPtr->arrowLength + inset; if (scrollPtr->vertical) { - length = Tk_Height(scrollPtr->tkwin); - fieldlength = length - 2 * arrowSize; - width = Tk_Width(scrollPtr->tkwin); + length = Tk_Height(scrollPtr->tkwin); + fieldlength = length - 2 * arrowSize; + width = Tk_Width(scrollPtr->tkwin); } else { - tmp = x; - x = y; - y = tmp; - length = Tk_Width(scrollPtr->tkwin); - fieldlength = length - 2 * arrowSize; - width = Tk_Height(scrollPtr->tkwin); + tmp = x; + x = y; + y = tmp; + length = Tk_Width(scrollPtr->tkwin); + fieldlength = length - 2 * arrowSize; + width = Tk_Height(scrollPtr->tkwin); } + fieldlength = fieldlength < 0 ? 0 : fieldlength; if (x=width-inset || y=length-inset) { - return OUTSIDE; + return OUTSIDE; } /* @@ -399,18 +407,19 @@ TkpScrollbarPosition( */ if (y < scrollPtr->sliderFirst) { - return TOP_GAP; + return TOP_GAP; } if (y < scrollPtr->sliderLast) { - return SLIDER; + return SLIDER; } if (y < fieldlength){ - return BOTTOM_GAP; + return BOTTOM_GAP; } if (y < fieldlength + arrowSize) { - return TOP_ARROW; + return TOP_ARROW; } return BOTTOM_ARROW; + } /* @@ -458,7 +467,7 @@ UpdateControlValues( width = contrlRect.size.width; height = contrlRect.size.height; - variant = contrlRect.size.width < metrics[0].width ? 1 : 0; + variant = contrlRect.size.width < metrics[0].width ? 1 : 0; /* * Ensure we set scrollbar control bounds only once all size adjustments @@ -514,8 +523,8 @@ UpdateControlValues( * * ScrollbarPress -- * - * This procedure is invoked in response to events. - * Enters a modal loop to handle scrollbar interactions. + * This procedure is invoked in response to , , + * , and events. Scrollbar appearance is modified. * *-------------------------------------------------------------- */ @@ -526,6 +535,13 @@ ScrollbarPress(TkScrollbar *scrollPtr, XEvent *eventPtr) if (eventPtr->type == ButtonPress) { UpdateControlValues(scrollPtr); + info.trackInfo.scrollbar.pressState = 1; + } + if (eventPtr->type == EnterNotify) { + info.trackInfo.scrollbar.pressState = 1; + } + if (eventPtr->type == ButtonRelease || eventPtr->type == LeaveNotify) { + info.trackInfo.scrollbar.pressState = 0; } return TCL_OK; } @@ -566,6 +582,9 @@ ScrollbarEventProc( TkScrollbarEventuallyRedraw(scrollPtr); break; case ButtonPress: + case ButtonRelease: + case EnterNotify: + case LeaveNotify: ScrollbarPress(clientData, eventPtr); break; default: diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c index 39990e6..75473bf 100644 --- a/macosx/tkMacOSXWm.c +++ b/macosx/tkMacOSXWm.c @@ -2893,17 +2893,20 @@ WmProtocolCmd( } else { prevPtr->nextPtr = protPtr->nextPtr; } + if (protPtr->command) + ckfree(protPtr->command); Tcl_EventuallyFree(protPtr, TCL_DYNAMIC); break; } } cmd = Tcl_GetStringFromObj(objv[4], &cmdLength); if (cmdLength > 0) { - protPtr = ckalloc(HANDLER_SIZE(cmdLength)); + protPtr = ckalloc(sizeof(ProtocolHandler)); protPtr->protocol = protocol; protPtr->nextPtr = wmPtr->protPtr; wmPtr->protPtr = protPtr; protPtr->interp = interp; + protPtr->command = ckalloc(cmdLength+1); strcpy(protPtr->command, cmd); } return TCL_OK; diff --git a/macosx/tkMacOSXWm.h b/macosx/tkMacOSXWm.h index 0a128ef..e904f50 100644 --- a/macosx/tkMacOSXWm.h +++ b/macosx/tkMacOSXWm.h @@ -29,15 +29,13 @@ typedef struct ProtocolHandler { * same top-level window, or NULL for end of * list. */ Tcl_Interp *interp; /* Interpreter in which to invoke command. */ - char command[]; /* Tcl command to invoke when a client message + char* command; /* Tcl command to invoke when a client message * for this protocol arrives. The actual size * of the structure varies to accommodate the * needs of the actual command. THIS MUST BE * THE LAST FIELD OF THE STRUCTURE. */ } ProtocolHandler; -#define HANDLER_SIZE(cmdLength) \ -((unsigned) (sizeof(ProtocolHandler) + cmdLength + 1)) /* * A data structure of the following type holds window-manager-related -- cgit v0.12 From 77e0c5e9fb76f2aa4dd4f3d9545f3bf22b77cdc4 Mon Sep 17 00:00:00 2001 From: Kevin Walzer Date: Thu, 20 Apr 2017 01:53:22 +0000 Subject: 1. Fix for segfault with latest version of Xcode on macOS 10.12; thanks to Bill Joye for patch. 2. Improvements to HITheme scroller on macOS: smoother scrolling, and scrollbar now correctly highlights when being pressed and during enter/leave events. Thanks to Tortsen Reincke for bug report (061bf93176a5684a4a855f8177b290c59dd39bf2). --- macosx/tkMacOSXScrlbr.c | 83 ++++++++++++++++++++++++++++++------------------- macosx/tkMacOSXWm.c | 7 +++-- macosx/tkMacOSXWm.h | 6 ++-- 3 files changed, 58 insertions(+), 38 deletions(-) diff --git a/macosx/tkMacOSXScrlbr.c b/macosx/tkMacOSXScrlbr.c index 91cf112..1f5470c 100644 --- a/macosx/tkMacOSXScrlbr.c +++ b/macosx/tkMacOSXScrlbr.c @@ -19,6 +19,13 @@ #define MIN_SCROLLBAR_VALUE 0 +/* + * Minimum slider length, in pixels (designed to make sure that the slider is + * always easy to grab with the mouse). + */ + +#define MIN_SLIDER_LENGTH 5 + /*Borrowed from ttkMacOSXTheme.c to provide appropriate scaling of scrollbar values.*/ #ifdef __LP64__ #define RangeToFactor(maximum) (((double) (INT_MAX >> 1)) / (maximum)) @@ -60,16 +67,14 @@ typedef struct ScrollbarMetrics { } ScrollbarMetrics; static ScrollbarMetrics metrics[2] = { - {15, 54, 26, 14, 14, NSRegularControlSize}, /* kThemeScrollBarMedium */ - {11, 40, 20, 10, 10, NSSmallControlSize}, /* kThemeScrollBarSmall */ + {15, 54, 26, 14, 14, kControlSizeNormal}, /* kThemeScrollBarMedium */ + {11, 40, 20, 10, 10, kControlSizeSmall}, /* kThemeScrollBarSmall */ }; - HIThemeTrackDrawInfo info = { .version = 0, .min = 0.0, .max = 100.0, .attributes = kThemeTrackShowThumb, - .kind = kThemeScrollBarMedium, }; @@ -107,7 +112,7 @@ TkpCreateScrollbar( scrollPtr->troughGC = None; scrollPtr->copyGC = None; - Tk_CreateEventHandler(tkwin,ExposureMask|StructureNotifyMask|FocusChangeMask|ButtonPressMask|VisibilityChangeMask, ScrollbarEventProc, scrollPtr); + Tk_CreateEventHandler(tkwin,ExposureMask|StructureNotifyMask|FocusChangeMask|ButtonPressMask|ButtonReleaseMask|EnterWindowMask|LeaveWindowMask|VisibilityChangeMask, ScrollbarEventProc, scrollPtr); return (TkScrollbar *) scrollPtr; } @@ -212,7 +217,8 @@ TkpDisplayScrollbar( *---------------------------------------------------------------------- */ -extern void + + extern void TkpComputeScrollbarGeometry( register TkScrollbar *scrollPtr) /* Scrollbar whose geometry may have @@ -259,14 +265,12 @@ TkpComputeScrollbarGeometry( if (scrollPtr->sliderLast > fieldLength) { scrollPtr->sliderLast = fieldLength; } - if (!(MOUNTAIN_LION_STYLE)) { - scrollPtr->sliderFirst += scrollPtr->inset + - metrics[variant].topArrowHeight; - scrollPtr->sliderLast += scrollPtr->inset + - metrics[variant].bottomArrowHeight; - } - /* - * Register the desired geometry for the window (leave enough space + + scrollPtr->sliderFirst += scrollPtr->arrowLength + scrollPtr->inset; + scrollPtr->sliderLast += scrollPtr->arrowLength + scrollPtr->inset; + + + /* Register the desired geometry for the window (leave enough space * for the two arrows plus a minimum-size slider, plus border around * the whole window, if any). Then arrange for the window to be * redisplayed. @@ -281,6 +285,9 @@ TkpComputeScrollbarGeometry( } + + + /* *---------------------------------------------------------------------- * @@ -376,21 +383,22 @@ TkpScrollbarPosition( register const int arrowSize = scrollPtr->arrowLength + inset; if (scrollPtr->vertical) { - length = Tk_Height(scrollPtr->tkwin); - fieldlength = length - 2 * arrowSize; - width = Tk_Width(scrollPtr->tkwin); + length = Tk_Height(scrollPtr->tkwin); + fieldlength = length - 2 * arrowSize; + width = Tk_Width(scrollPtr->tkwin); } else { - tmp = x; - x = y; - y = tmp; - length = Tk_Width(scrollPtr->tkwin); - fieldlength = length - 2 * arrowSize; - width = Tk_Height(scrollPtr->tkwin); + tmp = x; + x = y; + y = tmp; + length = Tk_Width(scrollPtr->tkwin); + fieldlength = length - 2 * arrowSize; + width = Tk_Height(scrollPtr->tkwin); } + fieldlength = fieldlength < 0 ? 0 : fieldlength; if (x=width-inset || y=length-inset) { - return OUTSIDE; + return OUTSIDE; } /* @@ -399,18 +407,19 @@ TkpScrollbarPosition( */ if (y < scrollPtr->sliderFirst) { - return TOP_GAP; + return TOP_GAP; } if (y < scrollPtr->sliderLast) { - return SLIDER; + return SLIDER; } if (y < fieldlength){ - return BOTTOM_GAP; + return BOTTOM_GAP; } if (y < fieldlength + arrowSize) { - return TOP_ARROW; + return TOP_ARROW; } return BOTTOM_ARROW; + } /* @@ -458,7 +467,7 @@ UpdateControlValues( width = contrlRect.size.width; height = contrlRect.size.height; - variant = contrlRect.size.width < metrics[0].width ? 1 : 0; + variant = contrlRect.size.width < metrics[0].width ? 1 : 0; /* * Ensure we set scrollbar control bounds only once all size adjustments @@ -514,11 +523,11 @@ UpdateControlValues( * * ScrollbarPress -- * - * This procedure is invoked in response to events. - * Enters a modal loop to handle scrollbar interactions. + * This procedure is invoked in response to , , + * , and events. Scrollbar appearance is modified. * *-------------------------------------------------------------- - */ + */ static int ScrollbarPress(TkScrollbar *scrollPtr, XEvent *eventPtr) @@ -526,6 +535,13 @@ ScrollbarPress(TkScrollbar *scrollPtr, XEvent *eventPtr) if (eventPtr->type == ButtonPress) { UpdateControlValues(scrollPtr); + info.trackInfo.scrollbar.pressState = 1; + } + if (eventPtr->type == EnterNotify) { + info.trackInfo.scrollbar.pressState = 1; + } + if (eventPtr->type == ButtonRelease || eventPtr->type == LeaveNotify) { + info.trackInfo.scrollbar.pressState = 0; } return TCL_OK; } @@ -566,6 +582,9 @@ ScrollbarEventProc( TkScrollbarEventuallyRedraw(scrollPtr); break; case ButtonPress: + case ButtonRelease: + case EnterNotify: + case LeaveNotify: ScrollbarPress(clientData, eventPtr); break; default: diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c index 39990e6..dfb7912 100644 --- a/macosx/tkMacOSXWm.c +++ b/macosx/tkMacOSXWm.c @@ -1,5 +1,5 @@ /* - * tkMacOSXWm.c -- + * tkMacOSXWm.c -- * * This module takes care of the interactions between a Tk-based * application and the window manager. Among other things, it implements @@ -2893,17 +2893,20 @@ WmProtocolCmd( } else { prevPtr->nextPtr = protPtr->nextPtr; } + if (protPtr->command) + ckfree(protPtr->command); Tcl_EventuallyFree(protPtr, TCL_DYNAMIC); break; } } cmd = Tcl_GetStringFromObj(objv[4], &cmdLength); if (cmdLength > 0) { - protPtr = ckalloc(HANDLER_SIZE(cmdLength)); + protPtr = ckalloc(sizeof(ProtocolHandler)); protPtr->protocol = protocol; protPtr->nextPtr = wmPtr->protPtr; wmPtr->protPtr = protPtr; protPtr->interp = interp; + protPtr->command = ckalloc(cmdLength+1); strcpy(protPtr->command, cmd); } return TCL_OK; diff --git a/macosx/tkMacOSXWm.h b/macosx/tkMacOSXWm.h index 0a128ef..8256b54 100644 --- a/macosx/tkMacOSXWm.h +++ b/macosx/tkMacOSXWm.h @@ -11,7 +11,7 @@ */ #ifndef _TKMACWM -#define _TKMACWM +#define _TKMACWM #include "tkMacOSXInt.h" #include "tkMenu.h" @@ -29,15 +29,13 @@ typedef struct ProtocolHandler { * same top-level window, or NULL for end of * list. */ Tcl_Interp *interp; /* Interpreter in which to invoke command. */ - char command[]; /* Tcl command to invoke when a client message + char* command; /* Tcl command to invoke when a client message * for this protocol arrives. The actual size * of the structure varies to accommodate the * needs of the actual command. THIS MUST BE * THE LAST FIELD OF THE STRUCTURE. */ } ProtocolHandler; -#define HANDLER_SIZE(cmdLength) \ -((unsigned) (sizeof(ProtocolHandler) + cmdLength + 1)) /* * A data structure of the following type holds window-manager-related -- cgit v0.12 From 677efb49e66dded5f3db56da9137d51531e1f1a2 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 25 Apr 2017 10:42:10 +0000 Subject: Let the unimplemented function XDrawSegments() return BadDrawable in stead of Success: It's only in the stub table since [a0883a07026127ef], before that the function was only internal and returned void. --- xlib/xgc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xlib/xgc.c b/xlib/xgc.c index 78c7501..984c949 100644 --- a/xlib/xgc.c +++ b/xlib/xgc.c @@ -560,7 +560,7 @@ XDrawSegments( XSegment *segments, int nsegments) { - return Success; + return BadDrawable; } #endif -- cgit v0.12 -- cgit v0.12 From 3fa7a16d212c7d1b6252294cadf3e5d35e47ec69 Mon Sep 17 00:00:00 2001 From: simonbachmann Date: Sun, 30 Apr 2017 09:04:00 +0000 Subject: Fix [e4336bef5d] (Unexpected result when copying a photo image to itself): if source and destination image are the same, make a local copy of image data before the actual copy/zoom/subsample. --- generic/tkImgPhoto.c | 166 +++++++++++++++++++++++++++++++++++++-------------- tests/imgBmap.test | 3 +- tests/imgPhoto.test | 73 ++++++++++++++++++++++ 3 files changed, 195 insertions(+), 47 deletions(-) diff --git a/generic/tkImgPhoto.c b/generic/tkImgPhoto.c index 1bd0142..8b7350d 100644 --- a/generic/tkImgPhoto.c +++ b/generic/tkImgPhoto.c @@ -2698,7 +2698,7 @@ Tk_PhotoPutBlock( * messages, or NULL. */ Tk_PhotoHandle handle, /* Opaque handle for the photo image to be * updated. */ - register Tk_PhotoImageBlock *blockPtr, + Tk_PhotoImageBlock *blockPtr, /* Pointer to a structure describing the pixel * data to be copied into the image. */ int x, int y, /* Coordinates of the top-left pixel to be @@ -2709,6 +2709,8 @@ Tk_PhotoPutBlock( * transparent pixels. */ { register PhotoMaster *masterPtr = (PhotoMaster *) handle; + Tk_PhotoImageBlock sourceBlock; + unsigned char *memToFree; int xEnd, yEnd, greenOffset, blueOffset, alphaOffset; int wLeft, hLeft, wCopy, hCopy, pitch; unsigned char *srcPtr, *srcLinePtr, *destPtr, *destLinePtr; @@ -2736,11 +2738,43 @@ Tk_PhotoPutBlock( return TCL_OK; } + /* + * Fix for bug e4336bef5d: + * + * Make a local copy of *blockPtr, as we might have to change some + * of its fields and don't want to interfere with the caller's data. + * + * If source and destination are the same image, create a copy of the + * source data in our local sourceBlock. + * + * To find out, just comparing the pointers is not enough - they might have + * different values and still point to the same block of memory. (e.g. + * if the -from option was passed to [imageName copy]) + */ + sourceBlock = *blockPtr; + memToFree = NULL; + if (sourceBlock.pixelPtr >= masterPtr->pix32 + && sourceBlock.pixelPtr <= masterPtr->pix32 + masterPtr->width + * masterPtr->height * 4) { + sourceBlock.pixelPtr = attemptckalloc(sourceBlock.height + * sourceBlock.pitch); + if (sourceBlock.pixelPtr == NULL) { + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1)); + Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); + } + return TCL_ERROR; + } + memToFree = sourceBlock.pixelPtr; + memcpy(sourceBlock.pixelPtr, blockPtr->pixelPtr, sourceBlock.height + * sourceBlock.pitch); + } + + xEnd = x + width; yEnd = y + height; if ((xEnd > masterPtr->width) || (yEnd > masterPtr->height)) { - int sameSrc = (blockPtr->pixelPtr == masterPtr->pix32); - if (ImgPhotoSetSize(masterPtr, MAX(xEnd, masterPtr->width), MAX(yEnd, masterPtr->height)) == TCL_ERROR) { if (interp != NULL) { @@ -2748,11 +2782,7 @@ Tk_PhotoPutBlock( TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1)); Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); } - return TCL_ERROR; - } - if (sameSrc) { - blockPtr->pixelPtr = masterPtr->pix32; - blockPtr->pitch = masterPtr->width * 4; + goto errorExit; } } @@ -2771,14 +2801,14 @@ Tk_PhotoPutBlock( * components, mark it as a color image. */ - greenOffset = blockPtr->offset[1] - blockPtr->offset[0]; - blueOffset = blockPtr->offset[2] - blockPtr->offset[0]; - alphaOffset = blockPtr->offset[3]; - if ((alphaOffset >= blockPtr->pixelSize) || (alphaOffset < 0)) { + greenOffset = sourceBlock.offset[1] - sourceBlock.offset[0]; + blueOffset = sourceBlock.offset[2] - sourceBlock.offset[0]; + alphaOffset = sourceBlock.offset[3]; + if ((alphaOffset >= sourceBlock.pixelSize) || (alphaOffset < 0)) { alphaOffset = 0; sourceIsSimplePhoto = 1; } else { - alphaOffset -= blockPtr->offset[0]; + alphaOffset -= sourceBlock.offset[0]; } if ((greenOffset != 0) || (blueOffset != 0)) { masterPtr->flags |= COLOR_IMAGE; @@ -2798,13 +2828,13 @@ Tk_PhotoPutBlock( * pixelSize == 3 and alphaOffset == 0. Maybe other cases too. */ - if ((blockPtr->pixelSize == 4) + if ((sourceBlock.pixelSize == 4) && (greenOffset == 1) && (blueOffset == 2) && (alphaOffset == 3) - && (width <= blockPtr->width) && (height <= blockPtr->height) + && (width <= sourceBlock.width) && (height <= sourceBlock.height) && ((height == 1) || ((x == 0) && (width == masterPtr->width) - && (blockPtr->pitch == pitch))) + && (sourceBlock.pitch == pitch))) && (compRule == TK_PHOTO_COMPOSITE_SET)) { - memmove(destLinePtr, blockPtr->pixelPtr + blockPtr->offset[0], + memmove(destLinePtr, sourceBlock.pixelPtr + sourceBlock.offset[0], ((size_t)height * width * 4)); /* @@ -2820,11 +2850,11 @@ Tk_PhotoPutBlock( */ for (hLeft = height; hLeft > 0;) { - int pixelSize = blockPtr->pixelSize; + int pixelSize = sourceBlock.pixelSize; int compRuleSet = (compRule == TK_PHOTO_COMPOSITE_SET); - srcLinePtr = blockPtr->pixelPtr + blockPtr->offset[0]; - hCopy = MIN(hLeft, blockPtr->height); + srcLinePtr = sourceBlock.pixelPtr + sourceBlock.offset[0]; + hCopy = MIN(hLeft, sourceBlock.height); hLeft -= hCopy; for (; hCopy > 0; --hCopy) { /* @@ -2835,10 +2865,10 @@ Tk_PhotoPutBlock( if ((pixelSize == 4) && (greenOffset == 1) && (blueOffset == 2) && (alphaOffset == 3) - && (width <= blockPtr->width) + && (width <= sourceBlock.width) && compRuleSet) { memcpy(destLinePtr, srcLinePtr, ((size_t)width * 4)); - srcLinePtr += blockPtr->pitch; + srcLinePtr += sourceBlock.pitch; destLinePtr += pitch; continue; } @@ -2849,7 +2879,7 @@ Tk_PhotoPutBlock( destPtr = destLinePtr; for (wLeft = width; wLeft > 0;) { - wCopy = MIN(wLeft, blockPtr->width); + wCopy = MIN(wLeft, sourceBlock.width); wLeft -= wCopy; srcPtr = srcLinePtr; @@ -2939,7 +2969,7 @@ Tk_PhotoPutBlock( destPtr += 4; } } - srcLinePtr += blockPtr->pitch; + srcLinePtr += sourceBlock.pitch; destLinePtr += pitch; } } @@ -3055,7 +3085,15 @@ Tk_PhotoPutBlock( Tk_ImageChanged(masterPtr->tkMaster, x, y, width, height, masterPtr->width, masterPtr->height); + + ckfree(memToFree); + return TCL_OK; + + errorExit: + ckfree(memToFree); + + return TCL_ERROR; } /* @@ -3082,7 +3120,7 @@ Tk_PhotoPutZoomedBlock( * messages, or NULL. */ Tk_PhotoHandle handle, /* Opaque handle for the photo image to be * updated. */ - register Tk_PhotoImageBlock *blockPtr, + Tk_PhotoImageBlock *blockPtr, /* Pointer to a structure describing the pixel * data to be copied into the image. */ int x, int y, /* Coordinates of the top-left pixel to be @@ -3097,6 +3135,8 @@ Tk_PhotoPutZoomedBlock( * transparent pixels. */ { register PhotoMaster *masterPtr = (PhotoMaster *) handle; + register Tk_PhotoImageBlock sourceBlock; + unsigned char *memToFree; int xEnd, yEnd, greenOffset, blueOffset, alphaOffset; int wLeft, hLeft, wCopy, hCopy, blockWid, blockHt; unsigned char *srcPtr, *srcLinePtr, *srcOrigPtr, *destPtr, *destLinePtr; @@ -3132,12 +3172,42 @@ Tk_PhotoPutZoomedBlock( if (width <= 0 || height <= 0) { return TCL_OK; } + + /* + * Fix for Bug e4336bef5d: + * Make a local copy of *blockPtr, as we might have to change some + * of its fields and don't want to interfere with the caller's data. + * + * If source and destination are the same image, create a copy of the + * source data in our local sourceBlock. + * + * To find out, just comparing the pointers is not enough - they might have + * different values and still point to the same block of memory. (e.g. + * if the -from option was passed to [imageName copy]) + */ + sourceBlock = *blockPtr; + memToFree = NULL; + if (sourceBlock.pixelPtr >= masterPtr->pix32 + && sourceBlock.pixelPtr <= masterPtr->pix32 + masterPtr->width + * masterPtr->height * 4) { + sourceBlock.pixelPtr = attemptckalloc(sourceBlock.height + * sourceBlock.pitch); + if (sourceBlock.pixelPtr == NULL) { + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1)); + Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); + } + return TCL_ERROR; + } + memToFree = sourceBlock.pixelPtr; + memcpy(sourceBlock.pixelPtr, blockPtr->pixelPtr, sourceBlock.height + * sourceBlock.pitch); + } xEnd = x + width; yEnd = y + height; if ((xEnd > masterPtr->width) || (yEnd > masterPtr->height)) { - int sameSrc = (blockPtr->pixelPtr == masterPtr->pix32); - if (ImgPhotoSetSize(masterPtr, MAX(xEnd, masterPtr->width), MAX(yEnd, masterPtr->height)) == TCL_ERROR) { if (interp != NULL) { @@ -3145,11 +3215,7 @@ Tk_PhotoPutZoomedBlock( TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1)); Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); } - return TCL_ERROR; - } - if (sameSrc) { - blockPtr->pixelPtr = masterPtr->pix32; - blockPtr->pitch = masterPtr->width * 4; + goto errorExit; } } @@ -3168,14 +3234,14 @@ Tk_PhotoPutZoomedBlock( * components, mark it as a color image. */ - greenOffset = blockPtr->offset[1] - blockPtr->offset[0]; - blueOffset = blockPtr->offset[2] - blockPtr->offset[0]; - alphaOffset = blockPtr->offset[3]; - if ((alphaOffset >= blockPtr->pixelSize) || (alphaOffset < 0)) { + greenOffset = sourceBlock.offset[1] - sourceBlock.offset[0]; + blueOffset = sourceBlock.offset[2] - sourceBlock.offset[0]; + alphaOffset = sourceBlock.offset[3]; + if ((alphaOffset >= sourceBlock.pixelSize) || (alphaOffset < 0)) { alphaOffset = 0; sourceIsSimplePhoto = 1; } else { - alphaOffset -= blockPtr->offset[0]; + alphaOffset -= sourceBlock.offset[0]; } if ((greenOffset != 0) || (blueOffset != 0)) { masterPtr->flags |= COLOR_IMAGE; @@ -3186,21 +3252,21 @@ Tk_PhotoPutZoomedBlock( * subsampling and zooming. */ - blockXSkip = subsampleX * blockPtr->pixelSize; - blockYSkip = subsampleY * blockPtr->pitch; + blockXSkip = subsampleX * sourceBlock.pixelSize; + blockYSkip = subsampleY * sourceBlock.pitch; if (subsampleX > 0) { - blockWid = ((blockPtr->width + subsampleX - 1) / subsampleX) * zoomX; + blockWid = ((sourceBlock.width + subsampleX - 1) / subsampleX) * zoomX; } else if (subsampleX == 0) { blockWid = width; } else { - blockWid = ((blockPtr->width - subsampleX - 1) / -subsampleX) * zoomX; + blockWid = ((sourceBlock.width - subsampleX - 1) / -subsampleX) * zoomX; } if (subsampleY > 0) { - blockHt = ((blockPtr->height + subsampleY - 1) / subsampleY) * zoomY; + blockHt = ((sourceBlock.height + subsampleY - 1) / subsampleY) * zoomY; } else if (subsampleY == 0) { blockHt = height; } else { - blockHt = ((blockPtr->height - subsampleY - 1) / -subsampleY) * zoomY; + blockHt = ((sourceBlock.height - subsampleY - 1) / -subsampleY) * zoomY; } /* @@ -3208,12 +3274,12 @@ Tk_PhotoPutZoomedBlock( */ destLinePtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4; - srcOrigPtr = blockPtr->pixelPtr + blockPtr->offset[0]; + srcOrigPtr = sourceBlock.pixelPtr + sourceBlock.offset[0]; if (subsampleX < 0) { - srcOrigPtr += (blockPtr->width - 1) * blockPtr->pixelSize; + srcOrigPtr += (sourceBlock.width - 1) * sourceBlock.pixelSize; } if (subsampleY < 0) { - srcOrigPtr += (blockPtr->height - 1) * blockPtr->pitch; + srcOrigPtr += (sourceBlock.height - 1) * sourceBlock.pitch; } pitch = masterPtr->width * 4; @@ -3363,7 +3429,15 @@ Tk_PhotoPutZoomedBlock( Tk_ImageChanged(masterPtr->tkMaster, x, y, width, height, masterPtr->width, masterPtr->height); + + ckfree(memToFree); + return TCL_OK; + + errorExit: + ckfree(memToFree); + + return TCL_ERROR; } /* diff --git a/tests/imgBmap.test b/tests/imgBmap.test index 5ffd7c4..e7f2c7e 100644 --- a/tests/imgBmap.test +++ b/tests/imgBmap.test @@ -380,7 +380,8 @@ test imageBmap-7.9 {ImgBmapCmd procedure} -body { test imageBmap-7.10 {ImgBmapCmd procedure} -body { i1 gorp } -returnCodes error -result {bad option "gorp": must be cget or configure} - +# Clean it up after use!! +imageCleanup test imageBmap-8.1 {ImgBmapGet/Free procedures, shared instances} -setup { destroy .c diff --git a/tests/imgPhoto.test b/tests/imgPhoto.test index e93dab4..ff53576 100644 --- a/tests/imgPhoto.test +++ b/tests/imgPhoto.test @@ -953,6 +953,44 @@ test imgPhoto-10.1 {Tk_ImgPhotoPutBlock procedure} -setup { photo1 put "{#00ff00 #00ff00}" -to 2 0 list [photo1 get 2 0] [photo1 get 3 0] [photo1 get 4 0] } -result {{0 255 0} {0 255 0} {255 0 0}} +test imgPhoto-10.2 {Tk_ImgPhotoPutBlock, same source and dest img} -constraints { + hasTeapotPhoto +} -setup { + imageCleanup +} -body { + # Test for bug e4336bef5d + image create photo photo1 -file $teapotPhotoFile + image create photo photo2 -file $teapotPhotoFile + photo2 copy photo1 -to 1 2 + photo1 copy photo1 -to 1 2 + string equal [photo1 data] [photo2 data] +} -cleanup { + imageCleanup +} -result {1} +test imgPhoto-10.3 {Tk_ImgPhotoPutBlock, same source and dest img} -constraints { + hasTeapotPhoto +} -setup { + imageCleanup +} -body { + # Test for bug e4336bef5d + image create photo photo1 -file $teapotPhotoFile + image create photo photo2 -file $teapotPhotoFile + photo2 copy photo1 -from 2 1 -to 4 5 300 300 + photo1 copy photo1 -from 2 1 -to 4 5 300 300 + string equal [photo1 data] [photo2 data] +} -cleanup { + imageCleanup +} -result {1} +test imgPhoto-10.4 {Tk_ImgPhotoPutBlock, empty image} -setup { + imageCleanup +} -body { + image create photo photo1 + photo1 copy photo1 -to 0 5 10 20 + list [image width photo1] [image height photo1] +} -cleanup { + imageCleanup +} -result {0 0} + test imgPhoto-11.1 {Tk_FindPhoto} -setup { imageCleanup @@ -972,6 +1010,41 @@ test imgPhoto-12.1 {Tk_PhotoPutZoomedBlock} -constraints hasTeapotPhoto -body { } -cleanup { image delete p3 } -result {{19 92 192} {169 117 90} 512 512 {19 92 192}} +test imgPhoto-12.2 {Tk_ImgPhotoPutZoomedBlock, same source and dest img} -constraints { + hasTeapotPhoto +} -setup { + imageCleanup +} -body { + # Test for bug e4336bef5d + image create photo photo1 -file $teapotPhotoFile + image create photo photo2 -file $teapotPhotoFile + photo2 copy photo1 -to 0 1 200 200 -zoom 2 3 + photo1 copy photo1 -to 0 1 200 200 -zoom 2 3 + string equal [photo1 data] [photo2 data] +} -cleanup { + imageCleanup +} -result {1} +test imgPhoto-12.3 {Tk_ImgPhotoPutZoomedBlock, same source and dest img} -setup { + imageCleanup +} -body { + # Test for bug e4336bef5d + image create photo photo1 -file $teapotPhotoFile + image create photo photo2 -file $teapotPhotoFile + photo2 copy photo1 -from 1 0 -to 4 5 300 300 -zoom 1 2 + photo1 copy photo1 -from 1 0 -to 4 5 300 300 -zoom 1 2 + string equal [photo1 data] [photo2 data] +} -cleanup { + imageCleanup +} -result {1} +test imgPhoto-12.4 {Tk_ImgPhotoPutZoomedBlock, empty image} -setup { + imageCleanup +} -body { + image create photo photo1 + photo1 copy photo1 -to 0 5 10 20 + list [image width photo1] [image height photo1] +} -cleanup { + imageCleanup +} -result {0 0} test imgPhoto-13.1 {check separation of images in different interpreters} -setup { imageCleanup -- cgit v0.12 From cba0849390d99fbc8c07d7df1d35abb4dfca9c43 Mon Sep 17 00:00:00 2001 From: Kevin Walzer Date: Mon, 1 May 2017 01:53:42 +0000 Subject: tk_getSaveFile now correctly displays file name on macOS when -initialfile flag used; this functionality broke after Tk 8.6.5. The filetypes filter also now works correctly in tk_getOpenFile on macOS; this functionality was mostly broken after the transition to Cocoa. Thanks to Torsten Reincke and Christian Gollwitzer for the bug reports on c.l.t. --- macosx/tkMacOSXDialog.c | 80 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 22 deletions(-) diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index 80a7a11..990cfb1 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.c @@ -24,6 +24,9 @@ #define modalOther -1 #define modalError -2 +/*Vars for filtering in "open file" dialog.*/ +NSMutableArray *openFileTypes; +NSOpenPanel *openpanel; static const char *const colorOptionStrings[] = { "-initialcolor", "-parent", "-title", NULL @@ -212,6 +215,7 @@ static NSURL *getFileURL(NSString *directory, NSString *filename) { } } + - (void) tkAlertDidEnd: (NSAlert *) alert returnCode: (NSInteger) returnCode contextInfo: (void *) contextInfo { @@ -247,6 +251,17 @@ static NSURL *getFileURL(NSString *directory, NSString *filename) { ckfree(callbackInfo); } } + +- (void)selectFormat:(id)sender { + NSPopUpButton *button = (NSPopUpButton *)sender; + NSInteger selectedItemIndex = [button indexOfSelectedItem]; + openFileTypes = nil; + openFileTypes = [NSMutableArray array]; + [openFileTypes addObject:[button titleOfSelectedItem]]; + [openpanel setAllowedFileTypes:openFileTypes]; + +} + @end #pragma mark - @@ -395,8 +410,8 @@ Tk_GetOpenFileObjCmd( NSString *directory = nil, *filename = nil; NSString *message, *title, *type; NSWindow *parent; - NSMutableArray *fileTypes = nil; - NSOpenPanel *panel = [NSOpenPanel openPanel]; + // NSOpenPanel *panel = [NSOpenPanel openPanel]; + openpanel = [NSOpenPanel openPanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; @@ -432,12 +447,13 @@ Tk_GetOpenFileObjCmd( if (len) { filename = [[[NSString alloc] initWithUTF8String:str] autorelease]; + [openpanel setNameFieldStringValue:filename]; } break; case OPEN_MESSAGE: message = [[NSString alloc] initWithUTF8String: Tcl_GetString(objv[i + 1])]; - [panel setMessage:message]; + [openpanel setMessage:message]; [message release]; break; case OPEN_MULTIPLE: @@ -457,7 +473,7 @@ Tk_GetOpenFileObjCmd( case OPEN_TITLE: title = [[NSString alloc] initWithUTF8String: Tcl_GetString(objv[i + 1])]; - [panel setTitle:title]; + [openpanel setTitle:title]; [title release]; break; case OPEN_TYPEVARIABLE: @@ -468,9 +484,9 @@ Tk_GetOpenFileObjCmd( break; } } - [panel setAllowsMultipleSelection:multiple]; + [openpanel setAllowsMultipleSelection:multiple]; if (fl.filters) { - fileTypes = [NSMutableArray array]; + openFileTypes = [NSMutableArray array]; for (FileFilter *filterPtr = fl.filters; filterPtr; filterPtr = filterPtr->next) { for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr; @@ -483,8 +499,8 @@ Tk_GetOpenFileObjCmd( } if (*str) { type = [[NSString alloc] initWithUTF8String:str]; - if (![fileTypes containsObject:type]) { - [fileTypes addObject:type]; + if (![openFileTypes containsObject:type]) { + [openFileTypes addObject:type]; } [type release]; } @@ -493,15 +509,33 @@ Tk_GetOpenFileObjCmd( mfPtr = mfPtr->next) { if (mfPtr->type) { type = NSFileTypeForHFSTypeCode(mfPtr->type); - if (![fileTypes containsObject:type]) { - [fileTypes addObject:type]; + if (![openFileTypes containsObject:type]) { + /*Do nothing here, type and creator codes now ignored on macOS.*/ } } } } } } - [panel setAllowedFileTypes:fileTypes]; + + /*Accessory view for file filtering. Adapted from http://codefromabove.com/2015/01/nssavepanel-adding-an-accessory-view/ */ + NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)]; + NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)]; + [label setEditable:NO]; + [label setStringValue:@"Enable:"]; + [label setBordered:NO]; + [label setBezeled:NO]; + [label setDrawsBackground:NO]; + + NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) pullsDown:NO]; + [popupButton addItemsWithTitles:openFileTypes]; + [popupButton setAction:@selector(selectFormat:)]; + + [accessoryView addSubview:label]; + [accessoryView addSubview:popupButton]; + [openpanel setAllowedFileTypes:openFileTypes]; + + [openpanel setAccessoryView:accessoryView]; if (cmdObj) { callbackInfo = ckalloc(sizeof(FilePanelCallbackInfo)); if (Tcl_IsShared(cmdObj)) { @@ -516,33 +550,33 @@ Tk_GetOpenFileObjCmd( if (haveParentOption && parent && ![parent attachedSheet]) { parentIsKey = [parent isKeyWindow]; #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - [panel beginSheetForDirectory:directory + [openpanel beginSheetForDirectory:directory file:filename - types:fileTypes + types:openFileTypes modalForWindow:parent modalDelegate:NSApp didEndSelector: @selector(tkFilePanelDidEnd:returnCode:contextInfo:) contextInfo:callbackInfo]; #else - [panel setAllowedFileTypes:fileTypes]; - [panel setDirectoryURL:getFileURL(directory, filename)]; - [panel beginSheetModalForWindow:parent + [openpanel setAllowedFileTypes:openFileTypes]; + [openpanel setDirectoryURL:getFileURL(directory, filename)]; + [openpanel beginSheetModalForWindow:parent completionHandler:^(NSInteger returnCode) - { [NSApp tkFilePanelDidEnd:panel + { [NSApp tkFilePanelDidEnd:openpanel returnCode:returnCode contextInfo:callbackInfo ]; } ]; #endif - modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:panel]; + modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:openpanel]; } else { #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - modalReturnCode = [panel runModalForDirectory:directory + modalReturnCode = [openpanel runModalForDirectory:directory file:filename]; #else - [panel setDirectoryURL:getFileURL(directory, filename)]; - modalReturnCode = [panel runModal]; + [openpanel setDirectoryURL:getFileURL(directory, filename)]; + modalReturnCode = [openpanel runModal]; #endif - [NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode + [NSApp tkFilePanelDidEnd:openpanel returnCode:modalReturnCode contextInfo:callbackInfo]; } result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR; @@ -562,6 +596,7 @@ Tk_GetOpenFileObjCmd( TkFreeFileFilters(&fl); return result; } + /* *---------------------------------------------------------------------- @@ -643,6 +678,7 @@ Tk_GetSaveFileObjCmd( if (len) { filename = [[[NSString alloc] initWithUTF8String:str] autorelease]; + [panel setNameFieldStringValue:filename]; } break; case SAVE_MESSAGE: -- cgit v0.12 From 4d9d4cbb74c5e7fc099fcb08706909d8fc04027b Mon Sep 17 00:00:00 2001 From: Kevin Walzer Date: Mon, 1 May 2017 01:55:55 +0000 Subject: tk_getSaveFile now correctly displays file name on macOS when -initialfile flag used; this functionality broke after Tk 8.6.5. The filetypes filter also now works correctly in tk_getOpenFile on macOS; this functionality was mostly broken after the transition to Cocoa. Thanks to Torsten Reincke and Christian Gollwitzer for the bug reports on c.l.t. --- macosx/tkMacOSXDialog.c | 80 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 22 deletions(-) diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index 80a7a11..990cfb1 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.c @@ -24,6 +24,9 @@ #define modalOther -1 #define modalError -2 +/*Vars for filtering in "open file" dialog.*/ +NSMutableArray *openFileTypes; +NSOpenPanel *openpanel; static const char *const colorOptionStrings[] = { "-initialcolor", "-parent", "-title", NULL @@ -212,6 +215,7 @@ static NSURL *getFileURL(NSString *directory, NSString *filename) { } } + - (void) tkAlertDidEnd: (NSAlert *) alert returnCode: (NSInteger) returnCode contextInfo: (void *) contextInfo { @@ -247,6 +251,17 @@ static NSURL *getFileURL(NSString *directory, NSString *filename) { ckfree(callbackInfo); } } + +- (void)selectFormat:(id)sender { + NSPopUpButton *button = (NSPopUpButton *)sender; + NSInteger selectedItemIndex = [button indexOfSelectedItem]; + openFileTypes = nil; + openFileTypes = [NSMutableArray array]; + [openFileTypes addObject:[button titleOfSelectedItem]]; + [openpanel setAllowedFileTypes:openFileTypes]; + +} + @end #pragma mark - @@ -395,8 +410,8 @@ Tk_GetOpenFileObjCmd( NSString *directory = nil, *filename = nil; NSString *message, *title, *type; NSWindow *parent; - NSMutableArray *fileTypes = nil; - NSOpenPanel *panel = [NSOpenPanel openPanel]; + // NSOpenPanel *panel = [NSOpenPanel openPanel]; + openpanel = [NSOpenPanel openPanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; @@ -432,12 +447,13 @@ Tk_GetOpenFileObjCmd( if (len) { filename = [[[NSString alloc] initWithUTF8String:str] autorelease]; + [openpanel setNameFieldStringValue:filename]; } break; case OPEN_MESSAGE: message = [[NSString alloc] initWithUTF8String: Tcl_GetString(objv[i + 1])]; - [panel setMessage:message]; + [openpanel setMessage:message]; [message release]; break; case OPEN_MULTIPLE: @@ -457,7 +473,7 @@ Tk_GetOpenFileObjCmd( case OPEN_TITLE: title = [[NSString alloc] initWithUTF8String: Tcl_GetString(objv[i + 1])]; - [panel setTitle:title]; + [openpanel setTitle:title]; [title release]; break; case OPEN_TYPEVARIABLE: @@ -468,9 +484,9 @@ Tk_GetOpenFileObjCmd( break; } } - [panel setAllowsMultipleSelection:multiple]; + [openpanel setAllowsMultipleSelection:multiple]; if (fl.filters) { - fileTypes = [NSMutableArray array]; + openFileTypes = [NSMutableArray array]; for (FileFilter *filterPtr = fl.filters; filterPtr; filterPtr = filterPtr->next) { for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr; @@ -483,8 +499,8 @@ Tk_GetOpenFileObjCmd( } if (*str) { type = [[NSString alloc] initWithUTF8String:str]; - if (![fileTypes containsObject:type]) { - [fileTypes addObject:type]; + if (![openFileTypes containsObject:type]) { + [openFileTypes addObject:type]; } [type release]; } @@ -493,15 +509,33 @@ Tk_GetOpenFileObjCmd( mfPtr = mfPtr->next) { if (mfPtr->type) { type = NSFileTypeForHFSTypeCode(mfPtr->type); - if (![fileTypes containsObject:type]) { - [fileTypes addObject:type]; + if (![openFileTypes containsObject:type]) { + /*Do nothing here, type and creator codes now ignored on macOS.*/ } } } } } } - [panel setAllowedFileTypes:fileTypes]; + + /*Accessory view for file filtering. Adapted from http://codefromabove.com/2015/01/nssavepanel-adding-an-accessory-view/ */ + NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)]; + NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)]; + [label setEditable:NO]; + [label setStringValue:@"Enable:"]; + [label setBordered:NO]; + [label setBezeled:NO]; + [label setDrawsBackground:NO]; + + NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) pullsDown:NO]; + [popupButton addItemsWithTitles:openFileTypes]; + [popupButton setAction:@selector(selectFormat:)]; + + [accessoryView addSubview:label]; + [accessoryView addSubview:popupButton]; + [openpanel setAllowedFileTypes:openFileTypes]; + + [openpanel setAccessoryView:accessoryView]; if (cmdObj) { callbackInfo = ckalloc(sizeof(FilePanelCallbackInfo)); if (Tcl_IsShared(cmdObj)) { @@ -516,33 +550,33 @@ Tk_GetOpenFileObjCmd( if (haveParentOption && parent && ![parent attachedSheet]) { parentIsKey = [parent isKeyWindow]; #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - [panel beginSheetForDirectory:directory + [openpanel beginSheetForDirectory:directory file:filename - types:fileTypes + types:openFileTypes modalForWindow:parent modalDelegate:NSApp didEndSelector: @selector(tkFilePanelDidEnd:returnCode:contextInfo:) contextInfo:callbackInfo]; #else - [panel setAllowedFileTypes:fileTypes]; - [panel setDirectoryURL:getFileURL(directory, filename)]; - [panel beginSheetModalForWindow:parent + [openpanel setAllowedFileTypes:openFileTypes]; + [openpanel setDirectoryURL:getFileURL(directory, filename)]; + [openpanel beginSheetModalForWindow:parent completionHandler:^(NSInteger returnCode) - { [NSApp tkFilePanelDidEnd:panel + { [NSApp tkFilePanelDidEnd:openpanel returnCode:returnCode contextInfo:callbackInfo ]; } ]; #endif - modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:panel]; + modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:openpanel]; } else { #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - modalReturnCode = [panel runModalForDirectory:directory + modalReturnCode = [openpanel runModalForDirectory:directory file:filename]; #else - [panel setDirectoryURL:getFileURL(directory, filename)]; - modalReturnCode = [panel runModal]; + [openpanel setDirectoryURL:getFileURL(directory, filename)]; + modalReturnCode = [openpanel runModal]; #endif - [NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode + [NSApp tkFilePanelDidEnd:openpanel returnCode:modalReturnCode contextInfo:callbackInfo]; } result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR; @@ -562,6 +596,7 @@ Tk_GetOpenFileObjCmd( TkFreeFileFilters(&fl); return result; } + /* *---------------------------------------------------------------------- @@ -643,6 +678,7 @@ Tk_GetSaveFileObjCmd( if (len) { filename = [[[NSString alloc] initWithUTF8String:str] autorelease]; + [panel setNameFieldStringValue:filename]; } break; case SAVE_MESSAGE: -- cgit v0.12 -- cgit v0.12 From 491465f7f1042b9a347f579cc49f5ba49e9377dc Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 1 May 2017 10:07:45 +0000 Subject: various end-of-line spaces --- macosx/tkMacOSXDialog.c | 8 ++++---- macosx/tkMacOSXScrlbr.c | 4 ++-- tests/imgPhoto.test | 44 ++++++++++++++++++++++---------------------- xlib/xcolors.c | 4 ++-- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index 990cfb1..cd289d2 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.c @@ -517,7 +517,7 @@ Tk_GetOpenFileObjCmd( } } } - + /*Accessory view for file filtering. Adapted from http://codefromabove.com/2015/01/nssavepanel-adding-an-accessory-view/ */ NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)]; NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)]; @@ -526,15 +526,15 @@ Tk_GetOpenFileObjCmd( [label setBordered:NO]; [label setBezeled:NO]; [label setDrawsBackground:NO]; - + NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) pullsDown:NO]; [popupButton addItemsWithTitles:openFileTypes]; [popupButton setAction:@selector(selectFormat:)]; - + [accessoryView addSubview:label]; [accessoryView addSubview:popupButton]; [openpanel setAllowedFileTypes:openFileTypes]; - + [openpanel setAccessoryView:accessoryView]; if (cmdObj) { callbackInfo = ckalloc(sizeof(FilePanelCallbackInfo)); diff --git a/macosx/tkMacOSXScrlbr.c b/macosx/tkMacOSXScrlbr.c index 6253fff..49ba999 100644 --- a/macosx/tkMacOSXScrlbr.c +++ b/macosx/tkMacOSXScrlbr.c @@ -285,8 +285,8 @@ TkpComputeScrollbarGeometry( } - - + + /* *---------------------------------------------------------------------- diff --git a/tests/imgPhoto.test b/tests/imgPhoto.test index e93dab4..f9ffa94 100644 --- a/tests/imgPhoto.test +++ b/tests/imgPhoto.test @@ -134,7 +134,7 @@ test imgPhoto-2.2 {ImgPhotoCreate procedure} -setup { # } {couldn't open "bogus.img": no such file or directory} test imgPhoto-3.1 {ImgPhotoConfigureMaster procedure} -constraints { - hasTeapotPhoto + hasTeapotPhoto } -body { image create photo photo1 -file $teapotPhotoFile photo1 configure -file $teapotPhotoFile @@ -142,7 +142,7 @@ test imgPhoto-3.1 {ImgPhotoConfigureMaster procedure} -constraints { image delete photo1 } -result {} test imgPhoto-3.2 {ImgPhotoConfigureMaster procedure} -constraints { - hasTeapotPhoto + hasTeapotPhoto } -body { image create photo photo1 -file $teapotPhotoFile list [catch {photo1 configure -file bogus} err] [string tolower $err] \ @@ -151,7 +151,7 @@ test imgPhoto-3.2 {ImgPhotoConfigureMaster procedure} -constraints { image delete photo1 } -result {1 {couldn't open "bogus": no such file or directory} 256 256} test imgPhoto-3.3 {ImgPhotoConfigureMaster procedure} -constraints { - hasTeapotPhoto + hasTeapotPhoto } -setup { destroy .c pack [canvas .c] @@ -235,7 +235,7 @@ test imgPhoto-4.9 {ImgPhotoCmd procedure: configure option} -setup { image delete photo1 } -returnCodes error -result {value for "-gamma" missing} test imgPhoto-4.10 {ImgPhotoCmd procedure: copy option} -constraints { - hasTeapotPhoto + hasTeapotPhoto } -setup { image create photo photo1 image create photo photo2 -width 25 -height 30 @@ -278,7 +278,7 @@ test imgPhoto-4.14 {ImgPhotoCmd procedure: copy option} -setup { image delete photo1 photo2 } -result {the "-from" option requires one to four integer values} test imgPhoto-4.15 {ImgPhotoCmd procedure: copy option} -constraints { - hasTeapotPhoto + hasTeapotPhoto } -setup { image create photo photo1 image create photo photo2 -file $teapotPhotoFile @@ -290,7 +290,7 @@ test imgPhoto-4.15 {ImgPhotoCmd procedure: copy option} -constraints { image delete photo1 photo2 } -result {60 50 {215 154 120}} test imgPhoto-4.16 {ImgPhotoCmd procedure: copy option} -constraints { - hasTeapotPhoto + hasTeapotPhoto } -setup { image create photo photo1 image create photo photo2 -file $teapotPhotoFile @@ -301,7 +301,7 @@ test imgPhoto-4.16 {ImgPhotoCmd procedure: copy option} -constraints { image delete photo1 photo2 } -result {80 100 {19 92 192}} test imgPhoto-4.17 {ImgPhotoCmd procedure: copy option} -constraints { - hasTeapotPhoto + hasTeapotPhoto } -setup { image create photo photo1 image create photo photo2 -file $teapotPhotoFile @@ -312,7 +312,7 @@ test imgPhoto-4.17 {ImgPhotoCmd procedure: copy option} -constraints { image delete photo1 photo2 } -result {100 100 {215 154 120}} test imgPhoto-4.18 {ImgPhotoCmd procedure: copy option} -constraints { - hasTeapotPhoto + hasTeapotPhoto } -setup { image create photo photo1 image create photo photo2 -file $teapotPhotoFile @@ -334,7 +334,7 @@ test imgPhoto-4.19 {ImgPhotoCmd procedure: copy option} -constraints { image delete photo1 photo2 } -result {120 100 {169 99 47}} test imgPhoto-4.20 {ImgPhotoCmd procedure: copy option} -constraints { - hasTeapotPhoto + hasTeapotPhoto } -setup { image create photo photo1 image create photo photo2 -file $teapotPhotoFile @@ -345,7 +345,7 @@ test imgPhoto-4.20 {ImgPhotoCmd procedure: copy option} -constraints { image delete photo1 photo2 } -result {90 80 {207 146 112}} test imgPhoto-4.21 {ImgPhotoCmd procedure: copy option} -constraints { - hasTeapotPhoto + hasTeapotPhoto } -setup { image create photo photo1 image create photo photo2 -file $teapotPhotoFile @@ -368,7 +368,7 @@ test imgPhoto-4.21 {ImgPhotoCmd procedure: copy option} -constraints { image delete photo1 photo2 } -result {256 256 49 51 49 51 49 51 10 51 10 10} test imgPhoto-4.22 {ImgPhotoCmd procedure: get option} -constraints { - hasTeapotPhoto + hasTeapotPhoto } -setup { image create photo photo1 } -body { @@ -435,7 +435,7 @@ test imgPhoto-4.30 {ImgPhotoCmd procedure: read option} -setup { image delete photo1 } -result {wrong # args: should be "photo1 read fileName ?-option value ...?"} test imgPhoto-4.31 {ImgPhotoCmd procedure: read option} -constraints { - hasTeapotPhoto + hasTeapotPhoto } -setup { image create photo photo1 } -body { @@ -451,7 +451,7 @@ test imgPhoto-4.32 {ImgPhotoCmd procedure: read option} -setup { image delete photo1 } -result {1 {couldn't open "bogus": no such file or directory}} test imgPhoto-4.33 {ImgPhotoCmd procedure: read option} -constraints { - hasTeapotPhoto + hasTeapotPhoto } -setup { image create photo photo1 } -body { @@ -467,7 +467,7 @@ test imgPhoto-4.34 {ImgPhotoCmd procedure: read option} -setup { image delete photo1 } -result [subst {couldn't recognize data in image file "$README"}] test imgPhoto-4.35 {ImgPhotoCmd procedure: read option} -constraints { - hasTeapotPhoto + hasTeapotPhoto } -setup { image create photo photo1 } -body { @@ -477,7 +477,7 @@ test imgPhoto-4.35 {ImgPhotoCmd procedure: read option} -constraints { image delete photo1 } -result {256 256 {161 109 82}} test imgPhoto-4.36 {ImgPhotoCmd procedure: read option} -constraints { - hasTeapotPhoto + hasTeapotPhoto } -setup { image create photo photo1 } -body { @@ -805,7 +805,7 @@ test imgPhoto-4.74 {ImgPhotoCmd procedure: put option error handling} -setup { image delete photo1 } -returnCodes 1 -result {wrong # args: should be "photo1 put data ?-option value ...?"} test imgPhoto-4.75 { read command: filename starting with '-'} -constraints { - hasTeapotPhoto + hasTeapotPhoto } -body { file copy -force $teapotPhotoFile -teapotPhotoFile image create photo photo1 @@ -816,7 +816,7 @@ test imgPhoto-4.75 { read command: filename starting with '-'} -constrain } -result {} test imgPhoto-5.1 {ImgPhotoGet/Free procedures, shared instances} -constraints { - hasTeapotPhoto + hasTeapotPhoto } -setup { destroy .c pack [canvas .c] @@ -853,7 +853,7 @@ test imgPhoto-6.1 {ImgPhotoDisplay procedure, blank display} -setup { } -result {} test imgPhoto-7.1 {ImgPhotoFree procedure, resource freeing} -constraints { - hasTeapotPhoto + hasTeapotPhoto } -setup { destroy .c pack [canvas .c] @@ -868,7 +868,7 @@ test imgPhoto-7.1 {ImgPhotoFree procedure, resource freeing} -constraints { destroy .c } -result {} test imgPhoto-7.2 {ImgPhotoFree procedures, unlinking} -constraints { - hasTeapotPhoto + hasTeapotPhoto } -setup { deleteWindows imageCleanup @@ -893,7 +893,7 @@ test imgPhoto-7.2 {ImgPhotoFree procedures, unlinking} -constraints { image delete photo1 } -result {} test imgPhoto-7.3 {ImgPhotoFree procedures, multiple visuals} -constraints { - hasTeapotPhoto + hasTeapotPhoto } -setup { deleteWindows imageCleanup @@ -918,7 +918,7 @@ test imgPhoto-8.1 {ImgPhotoDelete procedure} -constraints hasTeapotPhoto -body { image delete photo2 } -result {} test imgPhoto-8.2 {ImgPhotoDelete procedure} -constraints { - hasTeapotPhoto + hasTeapotPhoto } -setup { set x {} } -body { @@ -938,7 +938,7 @@ test imgPhoto-8.3 {ImgPhotoDelete procedure, name cleanup} -body { } -result {image "photo2" doesn't exist or is not a photo image} test imgPhoto-9.1 {ImgPhotoCmdDeletedProc procedure} -constraints { - hasTeapotPhoto + hasTeapotPhoto } -body { image create photo photo2 -file $teapotPhotoFile rename photo2 {} diff --git a/xlib/xcolors.c b/xlib/xcolors.c index 36dc67c..78fd44b 100644 --- a/xlib/xcolors.c +++ b/xlib/xcolors.c @@ -350,11 +350,11 @@ XParseColor( * digits in the spec. Ergo, it is not a vailid color string. * (Bug f0188aca9e) */ - + if (*p != '\0') { return 0; } - + switch ((int)(p-spec)) { case 3: colorPtr->red = US(((value >> 8) & 0xf) * 0x1111); -- cgit v0.12 From ddf5e6ae8f6240fdbee22b4db0c3a5a8575bd7f1 Mon Sep 17 00:00:00 2001 From: gcramer Date: Mon, 1 May 2017 13:27:42 +0000 Subject: Fix [2433781fff]: Under X11 image/text now will be centered correctly, the old algorithm has an obvious offset bug, it did not take into account the case if the padding is even. --- unix/tkUnixButton.c | 81 +++++++++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 37 deletions(-) diff --git a/unix/tkUnixButton.c b/unix/tkUnixButton.c index 1aeefac..6a99124 100644 --- a/unix/tkUnixButton.c +++ b/unix/tkUnixButton.c @@ -351,6 +351,47 @@ TkpCreateButton( *---------------------------------------------------------------------- */ +static void +ShiftByOffset( + TkButton *butPtr, + int relief, + int *x, /* shift this x coordinate */ + int *y, /* shift this y coordinate */ + int width, /* width of image/text */ + int height) /* height of image/text */ +{ + if (relief != TK_RELIEF_RAISED + && butPtr->type == TYPE_BUTTON + && !Tk_StrictMotif(butPtr->tkwin)) { + int shiftX; + int shiftY; + + /* + * This is an (unraised) button widget, so we offset the text to make + * the button appear to move up and down as the relief changes. + */ + + shiftX = shiftY = (relief == TK_RELIEF_SUNKEN) ? 2 : 1; + + if (relief != TK_RELIEF_RIDGE) { + /* + * Take back one pixel if the padding is even, otherwise the + * content will be displayed too far right/down. + */ + + if ((Tk_Width(butPtr->tkwin) - width) % 2 == 0) { + shiftX -= 1; + } + if ((Tk_Height(butPtr->tkwin) - height) % 2 == 0) { + shiftY -= 1; + } + } + + *x += shiftX; + *y += shiftY; + } +} + void TkpDisplayButton( ClientData clientData) /* Information about widget. */ @@ -366,10 +407,6 @@ TkpDisplayButton( int width = 0, height = 0, fullWidth, fullHeight; int textXOffset, textYOffset; int haveImage = 0, haveText = 0; - int offset; /* 1 means this is a button widget, so we - * offset the text to make the button appear - * to move up and down as the relief - * changes. */ int imageWidth, imageHeight; int imageXOffset = 0, imageYOffset = 0; /* image information that will be used to @@ -432,8 +469,6 @@ TkpDisplayButton( } } - offset = (butPtr->type == TYPE_BUTTON) && !Tk_StrictMotif(butPtr->tkwin); - /* * In order to avoid screen flashes, this function redraws the button in a * pixmap, then copies the pixmap to the screen in a single operation. @@ -525,17 +560,7 @@ TkpDisplayButton( butPtr->indicatorSpace + fullWidth, fullHeight, &x, &y); x += butPtr->indicatorSpace; - - x += offset; - y += offset; - if (relief == TK_RELIEF_RAISED) { - x -= offset; - y -= offset; - } else if (relief == TK_RELIEF_SUNKEN) { - x += offset; - y += offset; - } - + ShiftByOffset(butPtr, relief, &x, &y, width, height); imageXOffset += x; imageYOffset += y; @@ -593,16 +618,7 @@ TkpDisplayButton( TkComputeAnchor(butPtr->anchor, tkwin, 0, 0, butPtr->indicatorSpace + width, height, &x, &y); x += butPtr->indicatorSpace; - - x += offset; - y += offset; - if (relief == TK_RELIEF_RAISED) { - x -= offset; - y -= offset; - } else if (relief == TK_RELIEF_SUNKEN) { - x += offset; - y += offset; - } + ShiftByOffset(butPtr, relief, &x, &y, width, height); imageXOffset += x; imageYOffset += y; if (butPtr->image != NULL) { @@ -655,16 +671,7 @@ TkpDisplayButton( butPtr->textHeight, &x, &y); x += butPtr->indicatorSpace; - - x += offset; - y += offset; - if (relief == TK_RELIEF_RAISED) { - x -= offset; - y -= offset; - } else if (relief == TK_RELIEF_SUNKEN) { - x += offset; - y += offset; - } + ShiftByOffset(butPtr, relief, &x, &y, width, height); Tk_DrawTextLayout(butPtr->display, pixmap, gc, butPtr->textLayout, x, y, 0, -1); Tk_UnderlineTextLayout(butPtr->display, pixmap, gc, -- cgit v0.12 From fa9b215690838b15cde6db8cf2be1545c20f6032 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 2 May 2017 08:41:01 +0000 Subject: Typo (wehter -> whether) and minor consistancy in code comment (grey -> gray) --- doc/FindPhoto.3 | 22 +++++++++++----------- generic/tkImgPhInstance.c | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/doc/FindPhoto.3 b/doc/FindPhoto.3 index 3f6b919..dc218bf 100644 --- a/doc/FindPhoto.3 +++ b/doc/FindPhoto.3 @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" '\" Author: Paul Mackerras (paulus@cs.anu.edu.au), '\" Department of Computer Science, '\" Australian National University. @@ -99,8 +99,8 @@ being written to the photo image. particular photo image to the other procedures. The parameter is the name of the image, that is, the name specified to the \fBimage create photo\fR command, or assigned by that command if no name was specified. -If \fIimageName\fR does not exist or is not a photo image, -\fBTk_FindPhoto\fR returns NULL. +If \fIimageName\fR does not exist or is not a photo image, +\fBTk_FindPhoto\fR returns NULL. .PP \fBTk_PhotoPutBlock\fR is used to supply blocks of image data to be displayed. The call affects an area of the image of size @@ -193,16 +193,16 @@ that describe the address and layout of the image data that the photo image has stored internally. The values are valid until the image is destroyed or its size is changed. .PP -It is possible to modify an image by writing directly to the data +It is possible to modify an image by writing directly to the data the \fIpixelPtr\fR field points to. The size of the image cannot be changed this way, though. -Also, changes made by writing directly to \fIpixelPtr\fR will not be -immediately visible, but only after a call to -\fBTk_ImageChanged\fR or after an event that causes the interested +Also, changes made by writing directly to \fIpixelPtr\fR will not be +immediately visible, but only after a call to +\fBTk_ImageChanged\fR or after an event that causes the interested widgets to redraw themselves. -For these reasons usually it is preferable to make changes to -a copy of the image data and write it back with -\fBTk_PhotoPutBlock\fR or \fBTk_PhotoPutZoomedBlock\fR. +For these reasons usually it is preferable to make changes to +a copy of the image data and write it back with +\fBTk_PhotoPutBlock\fR or \fBTk_PhotoPutZoomedBlock\fR. .PP \fBTk_PhotoGetImage\fR returns 1 for compatibility with the corresponding procedure in the old photo widget. @@ -263,7 +263,7 @@ The \fBTk_PhotoImageBlock\fR structure used to provide image data to data (e.g. separate planes for the red, green, blue and alpha channels). Unfortunately, the implementation fails to hold this promise. The problem is that the \fIpixelSize\fR field is -(incorrectly) used to determine wehter the image has an alpha channel. +(incorrectly) used to determine whether the image has an alpha channel. Currently, if the offset for the alpha channel is greater or equal than \fIpixelSize\fR, \fBtk_PhotoPutblock\fR assumes no alpha data is present and makes the image fully opaque. This means that for layouts diff --git a/generic/tkImgPhInstance.c b/generic/tkImgPhInstance.c index 98aaeab..fd98c6e 100644 --- a/generic/tkImgPhInstance.c +++ b/generic/tkImgPhInstance.c @@ -1261,7 +1261,7 @@ AllocateColors( } } else { /* - * Monochrome display - allocate the shades of grey we want. + * Monochrome display - allocate the shades of gray we want. */ for (i = 0; i < numColors; ++i) { -- cgit v0.12 From 2f6129689e39c5411a3826293de8f81d5a8ed614 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 2 May 2017 12:32:59 +0000 Subject: If compiled with -DTK_NO_DEPRECATED, remove the functions Tk_PhotoPutBlock_NoComposite/Tk_PhotoPutZoomedBlock_NoComposite/Tk_PhotoExpand_Panic/Tk_PhotoPutBlock_Panic/Tk_PhotoPutZoomedBlock_Panic/Tk_PhotoSetSize_Panic, which only exist to make stub-enabled extensions work which used those old functions. Otherwise, mark those functions as deprecated, causing a compiler warning if the compiler supports this. --- generic/tk.decls | 14 ++++++------- generic/tkDecls.h | 57 +++++++++++++++++++++++++++++++++++----------------- generic/tkImgPhoto.c | 3 ++- generic/tkStubInit.c | 6 ++++++ 4 files changed, 54 insertions(+), 26 deletions(-) diff --git a/generic/tk.decls b/generic/tk.decls index eaaa063..a8d0c58 100644 --- a/generic/tk.decls +++ b/generic/tk.decls @@ -326,7 +326,7 @@ declare 75 { declare 76 { void Tk_FreeTextLayout(Tk_TextLayout textLayout) } -declare 77 deprecated { +declare 77 {deprecated {function does nothing, call can be removed}} { void Tk_FreeXId(Display *display, XID xid) } declare 78 { @@ -564,12 +564,12 @@ declare 143 { Tk_Window tkwin, int *argcPtr, CONST84 char **argv, const Tk_ArgvInfo *argTable, int flags) } -declare 144 { +declare 144 {deprecated {function signature changed}} { void Tk_PhotoPutBlock_NoComposite(Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height) } -declare 145 { +declare 145 {deprecated {function signature changed}} { void Tk_PhotoPutZoomedBlock_NoComposite(Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, @@ -581,13 +581,13 @@ declare 146 { declare 147 { void Tk_PhotoBlank(Tk_PhotoHandle handle) } -declare 148 { +declare 148 {deprecated {function signature changed}} { void Tk_PhotoExpand_Panic(Tk_PhotoHandle handle, int width, int height ) } declare 149 { void Tk_PhotoGetSize(Tk_PhotoHandle handle, int *widthPtr, int *heightPtr) } -declare 150 { +declare 150 {deprecated {function signature changed}} { void Tk_PhotoSetSize_Panic(Tk_PhotoHandle handle, int width, int height) } declare 151 { @@ -943,12 +943,12 @@ declare 244 { declare 245 { void Tk_SetCaretPos(Tk_Window tkwin, int x, int y, int height) } -declare 246 { +declare 246 {deprecated {function signature changed}} { void Tk_PhotoPutBlock_Panic(Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule) } -declare 247 { +declare 247 {deprecated {function signature changed}} { void Tk_PhotoPutZoomedBlock_Panic(Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, diff --git a/generic/tkDecls.h b/generic/tkDecls.h index 3b72706..1aa087f 100644 --- a/generic/tkDecls.h +++ b/generic/tkDecls.h @@ -18,9 +18,9 @@ #endif #if defined(TK_NO_DEPRECATED) && defined(BUILD_tk) -# define TK_DEPRECATED MODULE_SCOPE +# define TK_DEPRECATED(msg) MODULE_SCOPE #else -# define TK_DEPRECATED EXTERN +# define TK_DEPRECATED(msg) EXTERN TCL_DEPRECATED_API(msg) #endif /* @@ -287,7 +287,9 @@ EXTERN void Tk_FreePixmap(Display *display, Pixmap pixmap); /* 76 */ EXTERN void Tk_FreeTextLayout(Tk_TextLayout textLayout); /* 77 */ -TK_DEPRECATED void Tk_FreeXId(Display *display, XID xid); +TK_DEPRECATED("function does nothing, call can be removed") +void Tk_FreeXId( + Display *display, XID xid); /* 78 */ EXTERN GC Tk_GCForColor(XColor *colorPtr, Drawable drawable); /* 79 */ @@ -477,11 +479,14 @@ EXTERN int Tk_ParseArgv(Tcl_Interp *interp, Tk_Window tkwin, int *argcPtr, CONST84 char **argv, const Tk_ArgvInfo *argTable, int flags); /* 144 */ -EXTERN void Tk_PhotoPutBlock_NoComposite(Tk_PhotoHandle handle, +TK_DEPRECATED("function signature changed") +void Tk_PhotoPutBlock_NoComposite( + Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height); /* 145 */ -EXTERN void Tk_PhotoPutZoomedBlock_NoComposite( +TK_DEPRECATED("function signature changed") +void Tk_PhotoPutZoomedBlock_NoComposite( Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, @@ -492,14 +497,16 @@ EXTERN int Tk_PhotoGetImage(Tk_PhotoHandle handle, /* 147 */ EXTERN void Tk_PhotoBlank(Tk_PhotoHandle handle); /* 148 */ -EXTERN void Tk_PhotoExpand_Panic(Tk_PhotoHandle handle, - int width, int height); +TK_DEPRECATED("function signature changed") +void Tk_PhotoExpand_Panic( + Tk_PhotoHandle handle, int width, int height); /* 149 */ EXTERN void Tk_PhotoGetSize(Tk_PhotoHandle handle, int *widthPtr, int *heightPtr); /* 150 */ -EXTERN void Tk_PhotoSetSize_Panic(Tk_PhotoHandle handle, - int width, int height); +TK_DEPRECATED("function signature changed") +void Tk_PhotoSetSize_Panic( + Tk_PhotoHandle handle, int width, int height); /* 151 */ EXTERN int Tk_PointToChar(Tk_TextLayout layout, int x, int y); /* 152 */ @@ -782,11 +789,15 @@ EXTERN void Tk_SetMinimumRequestSize(Tk_Window tkwin, EXTERN void Tk_SetCaretPos(Tk_Window tkwin, int x, int y, int height); /* 246 */ -EXTERN void Tk_PhotoPutBlock_Panic(Tk_PhotoHandle handle, +TK_DEPRECATED("function signature changed") +void Tk_PhotoPutBlock_Panic( + Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule); /* 247 */ -EXTERN void Tk_PhotoPutZoomedBlock_Panic(Tk_PhotoHandle handle, +TK_DEPRECATED("function signature changed") +void Tk_PhotoPutZoomedBlock_Panic( + Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY, int compRule); @@ -959,7 +970,7 @@ typedef struct TkStubs { void (*tk_FreeOptions) (const Tk_ConfigSpec *specs, char *widgRec, Display *display, int needFlags); /* 74 */ void (*tk_FreePixmap) (Display *display, Pixmap pixmap); /* 75 */ void (*tk_FreeTextLayout) (Tk_TextLayout textLayout); /* 76 */ - void (*tk_FreeXId) (Display *display, XID xid); /* 77 */ + TCL_DEPRECATED_API("function does nothing, call can be removed") void (*tk_FreeXId) (Display *display, XID xid); /* 77 */ GC (*tk_GCForColor) (XColor *colorPtr, Drawable drawable); /* 78 */ void (*tk_GeometryRequest) (Tk_Window tkwin, int reqWidth, int reqHeight); /* 79 */ Tk_3DBorder (*tk_Get3DBorder) (Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid colorName); /* 80 */ @@ -1026,13 +1037,13 @@ typedef struct TkStubs { Tk_Window (*tk_NameToWindow) (Tcl_Interp *interp, const char *pathName, Tk_Window tkwin); /* 141 */ void (*tk_OwnSelection) (Tk_Window tkwin, Atom selection, Tk_LostSelProc *proc, ClientData clientData); /* 142 */ int (*tk_ParseArgv) (Tcl_Interp *interp, Tk_Window tkwin, int *argcPtr, CONST84 char **argv, const Tk_ArgvInfo *argTable, int flags); /* 143 */ - void (*tk_PhotoPutBlock_NoComposite) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height); /* 144 */ - void (*tk_PhotoPutZoomedBlock_NoComposite) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY); /* 145 */ + TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoPutBlock_NoComposite) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height); /* 144 */ + TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoPutZoomedBlock_NoComposite) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY); /* 145 */ int (*tk_PhotoGetImage) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr); /* 146 */ void (*tk_PhotoBlank) (Tk_PhotoHandle handle); /* 147 */ - void (*tk_PhotoExpand_Panic) (Tk_PhotoHandle handle, int width, int height); /* 148 */ + TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoExpand_Panic) (Tk_PhotoHandle handle, int width, int height); /* 148 */ void (*tk_PhotoGetSize) (Tk_PhotoHandle handle, int *widthPtr, int *heightPtr); /* 149 */ - void (*tk_PhotoSetSize_Panic) (Tk_PhotoHandle handle, int width, int height); /* 150 */ + TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoSetSize_Panic) (Tk_PhotoHandle handle, int width, int height); /* 150 */ int (*tk_PointToChar) (Tk_TextLayout layout, int x, int y); /* 151 */ int (*tk_PostscriptFontName) (Tk_Font tkfont, Tcl_DString *dsPtr); /* 152 */ void (*tk_PreserveColormap) (Display *display, Colormap colormap); /* 153 */ @@ -1128,8 +1139,8 @@ typedef struct TkStubs { void (*tk_SetInternalBorderEx) (Tk_Window tkwin, int left, int right, int top, int bottom); /* 243 */ void (*tk_SetMinimumRequestSize) (Tk_Window tkwin, int minWidth, int minHeight); /* 244 */ void (*tk_SetCaretPos) (Tk_Window tkwin, int x, int y, int height); /* 245 */ - void (*tk_PhotoPutBlock_Panic) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule); /* 246 */ - void (*tk_PhotoPutZoomedBlock_Panic) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY, int compRule); /* 247 */ + TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoPutBlock_Panic) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule); /* 246 */ + TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoPutZoomedBlock_Panic) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY, int compRule); /* 247 */ int (*tk_CollapseMotionEvents) (Display *display, int collapse); /* 248 */ Tk_StyleEngine (*tk_RegisterStyleEngine) (const char *name, Tk_StyleEngine parent); /* 249 */ Tk_StyleEngine (*tk_GetStyleEngine) (const char *name); /* 250 */ @@ -1736,6 +1747,16 @@ extern const TkStubs *tkStubsPtr; Tcl_AppInitProc *appInitProc, Tcl_Interp *interp); #endif + +#ifdef TK_NO_DEPRECATED +#undef Tk_PhotoPutBlock_NoComposite +#undef Tk_PhotoPutZoomedBlock_NoComposite +#undef Tk_PhotoExpand_Panic +#undef Tk_PhotoPutBlock_Panic +#undef Tk_PhotoPutZoomedBlock_Panic +#undef Tk_PhotoSetSize_Panic +#endif /* TK_NO_DEPRECATED */ + #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT diff --git a/generic/tkImgPhoto.c b/generic/tkImgPhoto.c index 1fec208..fa35553 100644 --- a/generic/tkImgPhoto.c +++ b/generic/tkImgPhoto.c @@ -4063,7 +4063,7 @@ ImgPhotoPostscript( * *---------------------------------------------------------------------- */ - +#ifndef TK_NO_DEPRECATED void Tk_PhotoPutBlock_NoComposite( Tk_PhotoHandle handle, @@ -4149,6 +4149,7 @@ Tk_PhotoSetSize_Panic( Tcl_Panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE); } } +#endif /* TK_NO_DEPRECATED */ /* * Local Variables: diff --git a/generic/tkStubInit.c b/generic/tkStubInit.c index 7f5b3be..bf55adf 100644 --- a/generic/tkStubInit.c +++ b/generic/tkStubInit.c @@ -43,6 +43,12 @@ MODULE_SCOPE const TkStubs tkStubs; #ifdef TK_NO_DEPRECATED #define Tk_FreeXId 0 +#define Tk_PhotoPutBlock_NoComposite 0 +#define Tk_PhotoPutZoomedBlock_NoComposite 0 +#define Tk_PhotoExpand_Panic 0 +#define Tk_PhotoPutBlock_Panic 0 +#define Tk_PhotoPutZoomedBlock_Panic 0 +#define Tk_PhotoSetSize_Panic 0 #else static void doNothing(void) -- cgit v0.12 From 17dc3ad82adb8c68cc4548ce8af220784340df96 Mon Sep 17 00:00:00 2001 From: fvogel Date: Tue, 2 May 2017 18:22:32 +0000 Subject: Revert the previous commit since it has drawbacks (see [6020ee2d03]). --- generic/ttk/ttkNotebook.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/generic/ttk/ttkNotebook.c b/generic/ttk/ttkNotebook.c index b649e4b..389d520 100644 --- a/generic/ttk/ttkNotebook.c +++ b/generic/ttk/ttkNotebook.c @@ -4,7 +4,6 @@ #include #include -#include #include #include @@ -455,17 +454,15 @@ static void SqueezeTabs( if (nTabs > 0) { int difference = available - needed; - double fraction = (double)difference / needed; + double delta = (double)difference / needed; double slack = 0; - double ad; int i; for (i = 0; i < nTabs; ++i) { Tab *tab = Ttk_SlaveData(nb->notebook.mgr,i); - - ad = slack + tab->width * fraction; + double ad = slack + tab->width * delta; tab->width += (int)ad; - slack = ad - floor(ad); + slack = ad - (int)ad; } } } -- cgit v0.12 From defed109c22cf0e3570fcc2686645ccef8228dfc Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 5 May 2017 13:55:47 +0000 Subject: On Windows, use Tcl_WinTCharToUtf() in stead of Tcl_NewUnicodeObj(), since Tcl_WinTCharToUtf() works correctly when TCL_UTF_MAX==6 while Tcl_NewUnicodeObj() doesn't. All changes taken over from androwish. Thanks to Christian Werner! And ... on the go ... fixed a few memory leaks correctly detected by Christian. --- win/tkWinClipboard.c | 2 +- win/tkWinDialog.c | 52 ++++++++++++++++++++++++++++++++++++++++++++-------- win/tkWinInit.c | 7 ++++++- win/tkWinSend.c | 42 ++++++++++++++++++++++++++++++++++-------- win/tkWinSendCom.c | 25 ++++++++++++++++++++----- win/tkWinTest.c | 5 ++++- 6 files changed, 109 insertions(+), 24 deletions(-) diff --git a/win/tkWinClipboard.c b/win/tkWinClipboard.c index 929070b..03c0cde 100644 --- a/win/tkWinClipboard.c +++ b/win/tkWinClipboard.c @@ -331,7 +331,7 @@ TkWinClipboardRender( #ifdef UNICODE Tcl_DStringInit(&ds); - Tcl_UtfToUniCharDString(rawText, -1, &ds); + Tcl_WinUtfToTChar(rawText, -1, &ds); ckfree(rawText); handle = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, (unsigned) Tcl_DStringLength(&ds) + 2); diff --git a/win/tkWinDialog.c b/win/tkWinDialog.c index a7d8c7d..635b9a3 100644 --- a/win/tkWinDialog.c +++ b/win/tkWinDialog.c @@ -1379,17 +1379,27 @@ static int GetFileNameVista(Tcl_Interp *interp, OFNOpts *optsPtr, goto vamoose; if (optsPtr->extObj != NULL) { - wstr = Tcl_GetUnicode(optsPtr->extObj); + Tcl_DString ds; + const char *src; + + src = Tcl_GetString(optsPtr->extObj); + wstr = (LPWSTR) Tcl_WinUtfToTChar(src, optsPtr->extObj->length, &ds); if (wstr[0] == L'.') ++wstr; hr = fdlgIf->lpVtbl->SetDefaultExtension(fdlgIf, wstr); + Tcl_DStringFree(&ds); if (FAILED(hr)) goto vamoose; } if (optsPtr->titleObj != NULL) { - hr = fdlgIf->lpVtbl->SetTitle(fdlgIf, - Tcl_GetUnicode(optsPtr->titleObj)); + Tcl_DString ds; + const char *src; + + src = Tcl_GetString(optsPtr->titleObj); + wstr = (LPWSTR) Tcl_WinUtfToTChar(src, optsPtr->titleObj->length, &ds); + hr = fdlgIf->lpVtbl->SetTitle(fdlgIf, wstr); + Tcl_DStringFree(&ds); if (FAILED(hr)) goto vamoose; } @@ -1464,12 +1474,14 @@ static int GetFileNameVista(Tcl_Interp *interp, OFNOpts *optsPtr, SIGDN_FILESYSPATH, &wstr); if (SUCCEEDED(hr)) { Tcl_DString fnds; + ConvertExternalFilename(wstr, &fnds); CoTaskMemFree(wstr); Tcl_ListObjAppendElement( interp, multiObj, Tcl_NewStringObj(Tcl_DStringValue(&fnds), Tcl_DStringLength(&fnds))); + Tcl_DStringFree(&fnds); } itemIf->lpVtbl->Release(itemIf); if (FAILED(hr)) @@ -1490,10 +1502,12 @@ static int GetFileNameVista(Tcl_Interp *interp, OFNOpts *optsPtr, &wstr); if (SUCCEEDED(hr)) { Tcl_DString fnds; + ConvertExternalFilename(wstr, &fnds); resultObj = Tcl_NewStringObj(Tcl_DStringValue(&fnds), Tcl_DStringLength(&fnds)); CoTaskMemFree(wstr); + Tcl_DStringFree(&fnds); } resultIf->lpVtbl->Release(resultIf); } @@ -1501,13 +1515,20 @@ static int GetFileNameVista(Tcl_Interp *interp, OFNOpts *optsPtr, if (SUCCEEDED(hr)) { if (filterPtr && optsPtr->typeVariableObj) { UINT ftix; + hr = fdlgIf->lpVtbl->GetFileTypeIndex(fdlgIf, &ftix); if (SUCCEEDED(hr)) { /* Note ftix is a 1-based index */ if (ftix > 0 && ftix <= nfilters) { + Tcl_DString ftds; + Tcl_Obj *ftobj; + + Tcl_WinTCharToUtf(filterPtr[ftix-1].pszName, -1, &ftds); + ftobj = Tcl_NewStringObj(Tcl_DStringValue(&ftds), + Tcl_DStringLength(&ftds)); Tcl_ObjSetVar2(interp, optsPtr->typeVariableObj, NULL, - Tcl_NewUnicodeObj(filterPtr[ftix-1].pszName, -1), - TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG); + ftobj, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG); + Tcl_DStringFree(&ftds); } } } @@ -2786,6 +2807,9 @@ Tk_MessageBoxObjCmd( }; ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + Tcl_DString titleBuf, tmpBuf; + WCHAR *titlePtr, *tmpPtr; + const char *src; defaultBtn = -1; detailObj = NULL; @@ -2896,7 +2920,9 @@ Tk_MessageBoxObjCmd( : Tcl_NewUnicodeObj(NULL, 0); Tcl_IncrRefCount(tmpObj); if (detailObj) { - Tcl_AppendUnicodeToObj(tmpObj, L"\n\n", 2); + const Tcl_UniChar twoNL[] = { '\n', '\n' }; + + Tcl_AppendUnicodeToObj(tmpObj, twoNL, 2); Tcl_AppendObjToObj(tmpObj, detailObj); } @@ -2915,8 +2941,18 @@ Tk_MessageBoxObjCmd( tsdPtr->hBigIcon = TkWinGetIcon(parent, ICON_BIG); tsdPtr->hMsgBoxHook = SetWindowsHookEx(WH_CBT, MsgBoxCBTProc, NULL, GetCurrentThreadId()); - winCode = MessageBox(hWnd, Tcl_GetUnicode(tmpObj), - titleObj ? Tcl_GetUnicode(titleObj) : L"", flags); + src = Tcl_GetString(tmpObj); + tmpPtr = Tcl_WinUtfToTChar(src, tmpObj->length, &tmpBuf); + if (titleObj != NULL) { + src = Tcl_GetString(titleObj); + titlePtr = Tcl_WinUtfToTChar(src, titleObj->length, &titleBuf); + } else { + titlePtr = L""; + Tcl_DStringInit(&titleBuf); + } + winCode = MessageBox(hWnd, tmpPtr, titlePtr, flags); + Tcl_DStringFree(&titleBuf); + Tcl_DStringFree(&tmpBuf); UnhookWindowsHookEx(tsdPtr->hMsgBoxHook); (void) Tcl_SetServiceMode(oldMode); diff --git a/win/tkWinInit.c b/win/tkWinInit.c index b1b2d6b..4c18399 100644 --- a/win/tkWinInit.c +++ b/win/tkWinInit.c @@ -181,6 +181,9 @@ TkWin32ErrorObj( LPTSTR lpBuffer = NULL, p = NULL; TCHAR sBuffer[30]; Tcl_Obj* errPtr = NULL; +#ifdef _UNICODE + Tcl_DString ds; +#endif FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, (DWORD)hrError, @@ -196,7 +199,9 @@ TkWin32ErrorObj( } #ifdef _UNICODE - errPtr = Tcl_NewUnicodeObj(lpBuffer, (int)wcslen(lpBuffer)); + Tcl_WinTCharToUtf(lpBuffer, (int)wcslen(lpBuffer) * sizeof (WCHAR), &ds); + errPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)); + Tcl_DStringFree(&ds); #else errPtr = Tcl_NewStringObj(lpBuffer, (int)strlen(lpBuffer)); #endif /* _UNICODE */ diff --git a/win/tkWinSend.c b/win/tkWinSend.c index 6c4731a..c999c0b 100644 --- a/win/tkWinSend.c +++ b/win/tkWinSend.c @@ -252,8 +252,14 @@ TkGetInterpNames( LPOLESTR p = olestr + wcslen(oleszStub); if (*p) { + Tcl_DString ds; + + Tcl_WinTCharToUtf(p + 1, -1, &ds); result = Tcl_ListObjAppendElement(interp, - objList, Tcl_NewUnicodeObj(p + 1, -1)); + objList, + Tcl_NewStringObj(Tcl_DStringValue(&ds), + Tcl_DStringLength(&ds))); + Tcl_DStringFree(&ds); } } @@ -614,7 +620,7 @@ BuildMoniker( Tcl_DString dString; Tcl_DStringInit(&dString); - Tcl_UtfToUniCharDString(name, -1, &dString); + Tcl_WinUtfToTChar(name, -1, &dString); hr = CreateFileMoniker((LPOLESTR)Tcl_DStringValue(&dString), &pmkItem); Tcl_DStringFree(&dString); if (SUCCEEDED(hr)) { @@ -740,6 +746,8 @@ Send( HRESULT hr = S_OK, ehr = S_OK; Tcl_Obj *cmd = NULL; DISPID dispid; + Tcl_DString ds; + const char *src; cmd = Tcl_ConcatObj(objc, objv); @@ -753,7 +761,10 @@ Send( memset(&ei, 0, sizeof(ei)); vCmd.vt = VT_BSTR; - vCmd.bstrVal = SysAllocString(Tcl_GetUnicode(cmd)); + src = Tcl_GetString(cmd); + Tcl_WinUtfToTChar(src, cmd->length, &ds); + vCmd.bstrVal = SysAllocString((WCHAR *) Tcl_DStringValue(&ds)); + Tcl_DStringFree(&ds); dp.cArgs = 1; dp.rgvarg = &vCmd; @@ -774,7 +785,9 @@ Send( ehr = VariantChangeType(&vResult, &vResult, 0, VT_BSTR); if (SUCCEEDED(ehr)) { - Tcl_SetObjResult(interp, Tcl_NewUnicodeObj(vResult.bstrVal, -1)); + Tcl_WinTCharToUtf(vResult.bstrVal, (int) SysStringLen(vResult.bstrVal) * + sizeof (WCHAR), &ds); + Tcl_DStringResult(interp, &ds); } /* @@ -785,8 +798,11 @@ Send( if (hr == DISP_E_EXCEPTION && ei.bstrSource != NULL) { Tcl_Obj *opError, *opErrorCode, *opErrorInfo; - - opError = Tcl_NewUnicodeObj(ei.bstrSource, -1); + Tcl_WinTCharToUtf(ei.bstrSource, (int) SysStringLen(ei.bstrSource) * + sizeof (WCHAR), &ds); + opError = Tcl_NewStringObj(Tcl_DStringValue(&ds), + Tcl_DStringLength(&ds)); + Tcl_DStringFree(&ds); Tcl_ListObjIndex(interp, opError, 0, &opErrorCode); Tcl_SetObjErrorCode(interp, opErrorCode); Tcl_ListObjIndex(interp, opError, 1, &opErrorInfo); @@ -833,6 +849,8 @@ TkWinSend_SetExcepInfo( ICreateErrorInfo *pCEI; IErrorInfo *pEI, **ppEI = &pEI; HRESULT hr; + Tcl_DString ds; + const char *src; if (!pExcepInfo) { return; @@ -851,8 +869,16 @@ TkWinSend_SetExcepInfo( Tcl_ListObjAppendElement(interp, opErrorCode, opErrorInfo); /* TODO: Handle failure to append */ - pExcepInfo->bstrDescription = SysAllocString(Tcl_GetUnicode(opError)); - pExcepInfo->bstrSource = SysAllocString(Tcl_GetUnicode(opErrorCode)); + src = Tcl_GetString(opError); + Tcl_WinUtfToTChar(src, opError->length, &ds); + pExcepInfo->bstrDescription = + SysAllocString((WCHAR *) Tcl_DStringValue(&ds)); + Tcl_DStringFree(&ds); + src = Tcl_GetString(opErrorCode); + Tcl_WinUtfToTChar(src, opErrorCode->length, &ds); + pExcepInfo->bstrSource = + SysAllocString((WCHAR *) Tcl_DStringValue(&ds)); + Tcl_DStringFree(&ds); Tcl_DecrRefCount(opErrorCode); pExcepInfo->scode = E_FAIL; diff --git a/win/tkWinSendCom.c b/win/tkWinSendCom.c index 83dd56b..9e5b7a0 100644 --- a/win/tkWinSendCom.c +++ b/win/tkWinSendCom.c @@ -370,6 +370,7 @@ Async( { HRESULT hr = S_OK; VARIANT vCmd; + Tcl_DString ds; VariantInit(&vCmd); @@ -382,9 +383,13 @@ Async( } if (SUCCEEDED(hr) && obj->interp) { - Tcl_Obj *scriptPtr = Tcl_NewUnicodeObj(vCmd.bstrVal, - (int) SysStringLen(vCmd.bstrVal)); + Tcl_Obj *scriptPtr; + Tcl_WinTCharToUtf(vCmd.bstrVal, (int) SysStringLen(vCmd.bstrVal) * + sizeof (WCHAR), &ds); + scriptPtr = + Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)); + Tcl_DStringFree(&ds); TkWinSend_QueueCommand(obj->interp, scriptPtr); } @@ -424,6 +429,7 @@ Send( VARIANT v; register Tcl_Interp *interp = obj->interp; Tcl_Obj *scriptPtr; + Tcl_DString ds; if (interp == NULL) { return S_OK; @@ -434,17 +440,26 @@ Send( return hr; } - scriptPtr = Tcl_NewUnicodeObj(v.bstrVal, (int) SysStringLen(v.bstrVal)); + Tcl_WinTCharToUtf(v.bstrVal, (int) SysStringLen(v.bstrVal) * + sizeof (WCHAR), &ds); + scriptPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)); + Tcl_DStringFree(&ds); Tcl_Preserve(interp); Tcl_IncrRefCount(scriptPtr); result = Tcl_EvalObjEx(interp, scriptPtr, TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL); Tcl_DecrRefCount(scriptPtr); if (pvResult != NULL) { + Tcl_Obj *obj; + const char *src; + VariantInit(pvResult); pvResult->vt = VT_BSTR; - pvResult->bstrVal = SysAllocString(Tcl_GetUnicode( - Tcl_GetObjResult(interp))); + obj = Tcl_GetObjResult(interp); + src = Tcl_GetString(obj); + Tcl_WinUtfToTChar(src, obj->length, &ds); + pvResult->bstrVal = SysAllocString((WCHAR *) Tcl_DStringValue(&ds)); + Tcl_DStringFree(&ds); } if (result == TCL_ERROR) { hr = DISP_E_EXCEPTION; diff --git a/win/tkWinTest.c b/win/tkWinTest.c index d824ee4..6e79df3 100644 --- a/win/tkWinTest.c +++ b/win/tkWinTest.c @@ -515,6 +515,7 @@ TestgetwindowinfoObjCmd( Tcl_Obj *childrenObj = NULL; TCHAR buf[512]; int cch, cchBuf = 256; + Tcl_DString ds; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "hwnd"); @@ -542,7 +543,9 @@ TestgetwindowinfoObjCmd( Tcl_NewLongObj(GetWindowLongA(INT2PTR(hwnd), GWL_ID))); cch = GetWindowText(INT2PTR(hwnd), (LPTSTR)buf, cchBuf); - textObj = Tcl_NewUnicodeObj((LPCWSTR)buf, cch); + Tcl_WinTCharToUtf(buf, cch * sizeof (WCHAR), &ds); + textObj = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)); + Tcl_DStringFree(&ds); Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("text", 4), textObj); Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("parent", 6), -- cgit v0.12 From f19be0447c6d2d01a10d3881d6f8aab3c87dad5d Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 5 May 2017 15:06:01 +0000 Subject: Constrain test that demands user interaction --- tests/menu.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/menu.test b/tests/menu.test index 05356e3..ebf3fb7 100644 --- a/tests/menu.test +++ b/tests/menu.test @@ -3879,7 +3879,7 @@ test menu-37.1 {menubar menues cannot be posted - bug 2160206} -setup { } -result {1 {a menubar menu cannot be posted}} test menu-38.1 {Can't dismiss ttk::menubutton menu until mouse has hovered over it - bug fa32290898} -setup { -} -constraints {macOrUnix} -body { +} -constraints {userInteraction} -body { toplevel .top ttk::menubutton .top.mb -text "Some menu"; menu .top.mb.m; -- cgit v0.12 From 18da6f580a2bb9daa22123c2ff6aaa6bd6609005 Mon Sep 17 00:00:00 2001 From: fvogel Date: Fri, 5 May 2017 21:25:29 +0000 Subject: Fix [a5ba1c9764]: Race condition in clipboard cleanup on Windows. Patch from Roman Donchenko (aka dpb). --- win/tkWinX.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/win/tkWinX.c b/win/tkWinX.c index 098fc6d..fca72c3 100644 --- a/win/tkWinX.c +++ b/win/tkWinX.c @@ -686,19 +686,6 @@ TkClipCleanup( TkDisplay *dispPtr) /* Display associated with clipboard. */ { if (dispPtr->clipWindow != NULL) { - /* - * Force the clipboard to be rendered if we are the clipboard owner. - */ - - HWND hwnd = Tk_GetHWND(Tk_WindowId(dispPtr->clipWindow)); - - if (GetClipboardOwner() == hwnd) { - OpenClipboard(hwnd); - EmptyClipboard(); - TkWinClipboardRender(dispPtr, CF_TEXT); - CloseClipboard(); - } - Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom, dispPtr->applicationAtom); Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom, @@ -875,6 +862,23 @@ Tk_TranslateWinEvent( return 1; } + case WM_RENDERALLFORMATS: { + TkWindow *winPtr = (TkWindow *) Tk_HWNDToWindow(hwnd); + + if (winPtr && OpenClipboard(hwnd)) { + /* + * Make sure that nobody had taken ownership of the clipboard + * before we opened it. + */ + + if (GetClipboardOwner() == hwnd) { + TkWinClipboardRender(winPtr->dispPtr, CF_TEXT); + } + CloseClipboard(); + } + return 1; + } + case WM_COMMAND: case WM_NOTIFY: case WM_VSCROLL: -- cgit v0.12 From 8a4d0d14da64361e454f103ecd196a53318f1a32 Mon Sep 17 00:00:00 2001 From: Kevin Walzer Date: Sat, 6 May 2017 02:14:16 +0000 Subject: Add support for file filters in tk_getSaveFile on macOS/Cocoa --- macosx/tkMacOSXDialog.c | 74 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index cd289d2..9970bc1 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.c @@ -24,9 +24,11 @@ #define modalOther -1 #define modalError -2 -/*Vars for filtering in "open file" dialog.*/ +/*Vars for filtering in "open file" and "save file" dialogs.*/ NSMutableArray *openFileTypes; +NSMutableArray *saveFileTypes; NSOpenPanel *openpanel; +NSSavePanel *savepanel; static const char *const colorOptionStrings[] = { "-initialcolor", "-parent", "-title", NULL @@ -262,6 +264,16 @@ static NSURL *getFileURL(NSString *directory, NSString *filename) { } +- (void)saveFormat:(id)sender { + NSPopUpButton *button = (NSPopUpButton *)sender; + NSInteger selectedItemIndex = [button indexOfSelectedItem]; + saveFileTypes = nil; + saveFileTypes = [NSMutableArray array]; + [saveFileTypes addObject:[button titleOfSelectedItem]]; + [savepanel setAllowedFileTypes:saveFileTypes]; + +} + @end #pragma mark - @@ -410,7 +422,6 @@ Tk_GetOpenFileObjCmd( NSString *directory = nil, *filename = nil; NSString *message, *title, *type; NSWindow *parent; - // NSOpenPanel *panel = [NSOpenPanel openPanel]; openpanel = [NSOpenPanel openPanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; @@ -518,7 +529,6 @@ Tk_GetOpenFileObjCmd( } } - /*Accessory view for file filtering. Adapted from http://codefromabove.com/2015/01/nssavepanel-adding-an-accessory-view/ */ NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)]; NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)]; [label setEditable:NO]; @@ -634,7 +644,7 @@ Tk_GetSaveFileObjCmd( NSString *message, *title, *type; NSWindow *parent; NSMutableArray *fileTypes = nil; - NSSavePanel *panel = [NSSavePanel savePanel]; + savepanel = [NSSavePanel savePanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; @@ -678,13 +688,13 @@ Tk_GetSaveFileObjCmd( if (len) { filename = [[[NSString alloc] initWithUTF8String:str] autorelease]; - [panel setNameFieldStringValue:filename]; + [savepanel setNameFieldStringValue:filename]; } break; case SAVE_MESSAGE: message = [[NSString alloc] initWithUTF8String: Tcl_GetString(objv[i + 1])]; - [panel setMessage:message]; + [savepanel setMessage:message]; [message release]; break; case SAVE_PARENT: @@ -698,7 +708,7 @@ Tk_GetSaveFileObjCmd( case SAVE_TITLE: title = [[NSString alloc] initWithUTF8String: Tcl_GetString(objv[i + 1])]; - [panel setTitle:title]; + [savepanel setTitle:title]; [title release]; break; case SAVE_TYPEVARIABLE: @@ -715,8 +725,6 @@ Tk_GetSaveFileObjCmd( } } if (fl.filters || defaultType) { - fileTypes = [NSMutableArray array]; - [fileTypes addObject:defaultType ? defaultType : (id)kUTTypeContent]; for (FileFilter *filterPtr = fl.filters; filterPtr; filterPtr = filterPtr->next) { for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr; @@ -729,19 +737,37 @@ Tk_GetSaveFileObjCmd( } if (*str) { type = [[NSString alloc] initWithUTF8String:str]; - if (![fileTypes containsObject:type]) { - [fileTypes addObject:type]; + if (![saveFileTypes containsObject:type]) { + [saveFileTypes addObject:type]; } [type release]; } } } } - [panel setAllowedFileTypes:fileTypes]; - [panel setAllowsOtherFileTypes:YES]; + + + NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)]; + NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)]; + [label setEditable:NO]; + [label setStringValue:@"Enable:"]; + [label setBordered:NO]; + [label setBezeled:NO]; + [label setDrawsBackground:NO]; + + NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) pullsDown:NO]; + [popupButton addItemsWithTitles:saveFileTypes]; + [popupButton setAction:@selector(saveFormat:)]; + + [accessoryView addSubview:label]; + [accessoryView addSubview:popupButton]; + [savepanel setAllowedFileTypes:saveFileTypes]; + + [savepanel setAccessoryView:accessoryView]; + [savepanel setAllowsOtherFileTypes:YES]; } - [panel setCanSelectHiddenExtension:YES]; - [panel setExtensionHidden:NO]; + [savepanel setCanSelectHiddenExtension:YES]; + [savepanel setExtensionHidden:NO]; if (cmdObj) { callbackInfo = ckalloc(sizeof(FilePanelCallbackInfo)); if (Tcl_IsShared(cmdObj)) { @@ -756,7 +782,7 @@ Tk_GetSaveFileObjCmd( if (haveParentOption && parent && ![parent attachedSheet]) { parentIsKey = [parent isKeyWindow]; #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - [panel beginSheetForDirectory:directory + [savepanel beginSheetForDirectory:directory file:filename modalForWindow:parent modalDelegate:NSApp @@ -764,22 +790,22 @@ Tk_GetSaveFileObjCmd( @selector(tkFilePanelDidEnd:returnCode:contextInfo:) contextInfo:callbackInfo]; #else - [panel setDirectoryURL:getFileURL(directory, filename)]; - [panel beginSheetModalForWindow:parent + [savepanel setDirectoryURL:getFileURL(directory, filename)]; + [savepanel beginSheetModalForWindow:parent completionHandler:^(NSInteger returnCode) - { [NSApp tkFilePanelDidEnd:panel + { [NSApp tkFilePanelDidEnd:savepanel returnCode:returnCode contextInfo:callbackInfo ]; } ]; #endif - modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:panel]; + modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:savepanel]; } else { #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - modalReturnCode = [panel runModalForDirectory:directory file:filename]; + modalReturnCode = [savepanel runModalForDirectory:directory file:filename]; #else - [panel setDirectoryURL:getFileURL(directory, filename)]; - modalReturnCode = [panel runModal]; + [savepanel setDirectoryURL:getFileURL(directory, filename)]; + modalReturnCode = [savepanel runModal]; #endif - [NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode + [NSApp tkFilePanelDidEnd:savepanel returnCode:modalReturnCode contextInfo:callbackInfo]; } result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR; -- cgit v0.12 From 7b7b2ce13d5c8f9e6dda9fb5c4b083cf09c8b15c Mon Sep 17 00:00:00 2001 From: Kevin Walzer Date: Sat, 6 May 2017 02:16:13 +0000 Subject: Add support for file filters in tk_GetSaveFile on macOS/Cocoa --- macosx/tkMacOSXDialog.c | 74 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index cd289d2..9970bc1 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.c @@ -24,9 +24,11 @@ #define modalOther -1 #define modalError -2 -/*Vars for filtering in "open file" dialog.*/ +/*Vars for filtering in "open file" and "save file" dialogs.*/ NSMutableArray *openFileTypes; +NSMutableArray *saveFileTypes; NSOpenPanel *openpanel; +NSSavePanel *savepanel; static const char *const colorOptionStrings[] = { "-initialcolor", "-parent", "-title", NULL @@ -262,6 +264,16 @@ static NSURL *getFileURL(NSString *directory, NSString *filename) { } +- (void)saveFormat:(id)sender { + NSPopUpButton *button = (NSPopUpButton *)sender; + NSInteger selectedItemIndex = [button indexOfSelectedItem]; + saveFileTypes = nil; + saveFileTypes = [NSMutableArray array]; + [saveFileTypes addObject:[button titleOfSelectedItem]]; + [savepanel setAllowedFileTypes:saveFileTypes]; + +} + @end #pragma mark - @@ -410,7 +422,6 @@ Tk_GetOpenFileObjCmd( NSString *directory = nil, *filename = nil; NSString *message, *title, *type; NSWindow *parent; - // NSOpenPanel *panel = [NSOpenPanel openPanel]; openpanel = [NSOpenPanel openPanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; @@ -518,7 +529,6 @@ Tk_GetOpenFileObjCmd( } } - /*Accessory view for file filtering. Adapted from http://codefromabove.com/2015/01/nssavepanel-adding-an-accessory-view/ */ NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)]; NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)]; [label setEditable:NO]; @@ -634,7 +644,7 @@ Tk_GetSaveFileObjCmd( NSString *message, *title, *type; NSWindow *parent; NSMutableArray *fileTypes = nil; - NSSavePanel *panel = [NSSavePanel savePanel]; + savepanel = [NSSavePanel savePanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; @@ -678,13 +688,13 @@ Tk_GetSaveFileObjCmd( if (len) { filename = [[[NSString alloc] initWithUTF8String:str] autorelease]; - [panel setNameFieldStringValue:filename]; + [savepanel setNameFieldStringValue:filename]; } break; case SAVE_MESSAGE: message = [[NSString alloc] initWithUTF8String: Tcl_GetString(objv[i + 1])]; - [panel setMessage:message]; + [savepanel setMessage:message]; [message release]; break; case SAVE_PARENT: @@ -698,7 +708,7 @@ Tk_GetSaveFileObjCmd( case SAVE_TITLE: title = [[NSString alloc] initWithUTF8String: Tcl_GetString(objv[i + 1])]; - [panel setTitle:title]; + [savepanel setTitle:title]; [title release]; break; case SAVE_TYPEVARIABLE: @@ -715,8 +725,6 @@ Tk_GetSaveFileObjCmd( } } if (fl.filters || defaultType) { - fileTypes = [NSMutableArray array]; - [fileTypes addObject:defaultType ? defaultType : (id)kUTTypeContent]; for (FileFilter *filterPtr = fl.filters; filterPtr; filterPtr = filterPtr->next) { for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr; @@ -729,19 +737,37 @@ Tk_GetSaveFileObjCmd( } if (*str) { type = [[NSString alloc] initWithUTF8String:str]; - if (![fileTypes containsObject:type]) { - [fileTypes addObject:type]; + if (![saveFileTypes containsObject:type]) { + [saveFileTypes addObject:type]; } [type release]; } } } } - [panel setAllowedFileTypes:fileTypes]; - [panel setAllowsOtherFileTypes:YES]; + + + NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)]; + NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)]; + [label setEditable:NO]; + [label setStringValue:@"Enable:"]; + [label setBordered:NO]; + [label setBezeled:NO]; + [label setDrawsBackground:NO]; + + NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) pullsDown:NO]; + [popupButton addItemsWithTitles:saveFileTypes]; + [popupButton setAction:@selector(saveFormat:)]; + + [accessoryView addSubview:label]; + [accessoryView addSubview:popupButton]; + [savepanel setAllowedFileTypes:saveFileTypes]; + + [savepanel setAccessoryView:accessoryView]; + [savepanel setAllowsOtherFileTypes:YES]; } - [panel setCanSelectHiddenExtension:YES]; - [panel setExtensionHidden:NO]; + [savepanel setCanSelectHiddenExtension:YES]; + [savepanel setExtensionHidden:NO]; if (cmdObj) { callbackInfo = ckalloc(sizeof(FilePanelCallbackInfo)); if (Tcl_IsShared(cmdObj)) { @@ -756,7 +782,7 @@ Tk_GetSaveFileObjCmd( if (haveParentOption && parent && ![parent attachedSheet]) { parentIsKey = [parent isKeyWindow]; #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - [panel beginSheetForDirectory:directory + [savepanel beginSheetForDirectory:directory file:filename modalForWindow:parent modalDelegate:NSApp @@ -764,22 +790,22 @@ Tk_GetSaveFileObjCmd( @selector(tkFilePanelDidEnd:returnCode:contextInfo:) contextInfo:callbackInfo]; #else - [panel setDirectoryURL:getFileURL(directory, filename)]; - [panel beginSheetModalForWindow:parent + [savepanel setDirectoryURL:getFileURL(directory, filename)]; + [savepanel beginSheetModalForWindow:parent completionHandler:^(NSInteger returnCode) - { [NSApp tkFilePanelDidEnd:panel + { [NSApp tkFilePanelDidEnd:savepanel returnCode:returnCode contextInfo:callbackInfo ]; } ]; #endif - modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:panel]; + modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:savepanel]; } else { #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - modalReturnCode = [panel runModalForDirectory:directory file:filename]; + modalReturnCode = [savepanel runModalForDirectory:directory file:filename]; #else - [panel setDirectoryURL:getFileURL(directory, filename)]; - modalReturnCode = [panel runModal]; + [savepanel setDirectoryURL:getFileURL(directory, filename)]; + modalReturnCode = [savepanel runModal]; #endif - [NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode + [NSApp tkFilePanelDidEnd:savepanel returnCode:modalReturnCode contextInfo:callbackInfo]; } result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR; -- cgit v0.12 From cfbabe08a1a584f554365f7387e6c7a59799e0c8 Mon Sep 17 00:00:00 2001 From: Kevin Walzer Date: Sat, 6 May 2017 15:37:27 +0000 Subject: tk_getSaveFile now correctly displays multiple file types with filtering on macOS --- macosx/tkMacOSXDialog.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index 9970bc1..ca55c60 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.c @@ -725,6 +725,7 @@ Tk_GetSaveFileObjCmd( } } if (fl.filters || defaultType) { + saveFileTypes = [NSMutableArray array]; for (FileFilter *filterPtr = fl.filters; filterPtr; filterPtr = filterPtr->next) { for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr; @@ -733,8 +734,8 @@ Tk_GetSaveFileObjCmd( globPtr = globPtr->next) { str = globPtr->pattern; while (*str && (*str == '*' || *str == '.')) { - str++; - } + str++; + } if (*str) { type = [[NSString alloc] initWithUTF8String:str]; if (![saveFileTypes containsObject:type]) { -- cgit v0.12 From 4b8bb9766c83c93000160b5aeb3723d90dd95926 Mon Sep 17 00:00:00 2001 From: Kevin Walzer Date: Sat, 6 May 2017 15:38:13 +0000 Subject: tk_getSaveFile now correctly displays multiple file types with filtering on macOS --- macosx/tkMacOSXDialog.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index 9970bc1..ca55c60 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.c @@ -725,6 +725,7 @@ Tk_GetSaveFileObjCmd( } } if (fl.filters || defaultType) { + saveFileTypes = [NSMutableArray array]; for (FileFilter *filterPtr = fl.filters; filterPtr; filterPtr = filterPtr->next) { for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr; @@ -733,8 +734,8 @@ Tk_GetSaveFileObjCmd( globPtr = globPtr->next) { str = globPtr->pattern; while (*str && (*str == '*' || *str == '.')) { - str++; - } + str++; + } if (*str) { type = [[NSString alloc] initWithUTF8String:str]; if (![saveFileTypes containsObject:type]) { -- cgit v0.12 From 83920326ba5851cad594e6a261205a202b75a338 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 8 May 2017 11:18:52 +0000 Subject: Don't use sizeof(struct) when the structure has a char array as last element: If the size of this array changes, we'll be in trouble. --- generic/tkSelect.c | 4 ++-- generic/tkTextDisp.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/generic/tkSelect.c b/generic/tkSelect.c index ab9018a..d763411 100644 --- a/generic/tkSelect.c +++ b/generic/tkSelect.c @@ -190,8 +190,8 @@ Tk_CreateSelHandler( * should make a copy for this selPtr. */ - unsigned cmdInfoLen = Tk_Offset(CommandInfo, command) + - ((CommandInfo *)clientData)->cmdLength + 1; + unsigned cmdInfoLen = Tk_Offset(CommandInfo, command) + 1 + + ((CommandInfo *)clientData)->cmdLength; selPtr->clientData = ckalloc(cmdInfoLen); memcpy(selPtr->clientData, clientData, cmdInfoLen); diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c index 371e910..03d11e1 100644 --- a/generic/tkTextDisp.c +++ b/generic/tkTextDisp.c @@ -7561,7 +7561,7 @@ TkTextCharLayoutProc( ciPtr = &bciPtr->ci; } else { bciPtr = baseCharChunkPtr->clientData; - ciPtr = ckalloc(sizeof(CharInfo)); + ciPtr = ckalloc(Tk_Offset(CharInfo, chars) + 1); baseString = &bciPtr->baseChars; } -- cgit v0.12 From 39dd1134f379cf247b40c74d68ea6bec62edb33e Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 8 May 2017 12:02:25 +0000 Subject: Remove calls to Tk_FreeXId(), since it's just a NOP. --- generic/tkGC.c | 7 ------- unix/tkUnixCursor.c | 1 - unix/tkUnixXId.c | 1 - 3 files changed, 9 deletions(-) diff --git a/generic/tkGC.c b/generic/tkGC.c index 5663ede..c424e30 100644 --- a/generic/tkGC.c +++ b/generic/tkGC.c @@ -314,7 +314,6 @@ Tk_FreeGC( gcPtr = Tcl_GetHashValue(idHashPtr); gcPtr->refCount--; if (gcPtr->refCount == 0) { - Tk_FreeXId(gcPtr->display, (XID) XGContextFromGC(gcPtr->gc)); XFreeGC(gcPtr->display, gcPtr->gc); Tcl_DeleteHashEntry(gcPtr->valueHashPtr); Tcl_DeleteHashEntry(idHashPtr); @@ -351,12 +350,6 @@ TkGCCleanup( entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { gcPtr = Tcl_GetHashValue(entryPtr); - /* - * This call is not needed, as it is only used on Unix to restore the - * Id to the stack pool, and we don't want to use them anymore. - * Tk_FreeXId(gcPtr->display, (XID) XGContextFromGC(gcPtr->gc)); - */ - XFreeGC(gcPtr->display, gcPtr->gc); Tcl_DeleteHashEntry(gcPtr->valueHashPtr); Tcl_DeleteHashEntry(entryPtr); diff --git a/unix/tkUnixCursor.c b/unix/tkUnixCursor.c index 5266bde..8afb92d 100644 --- a/unix/tkUnixCursor.c +++ b/unix/tkUnixCursor.c @@ -639,7 +639,6 @@ TkpFreeCursor( TkUnixCursor *unixCursorPtr = (TkUnixCursor *) cursorPtr; XFreeCursor(unixCursorPtr->display, (Cursor) unixCursorPtr->info.cursor); - Tk_FreeXId(unixCursorPtr->display, (XID) unixCursorPtr->info.cursor); } /* diff --git a/unix/tkUnixXId.c b/unix/tkUnixXId.c index 668f228..ec2451c 100644 --- a/unix/tkUnixXId.c +++ b/unix/tkUnixXId.c @@ -96,7 +96,6 @@ Tk_FreePixmap( Pixmap pixmap) /* Identifier for pixmap. */ { XFreePixmap(display, pixmap); - Tk_FreeXId(display, (XID) pixmap); } -- cgit v0.12 From 900ca0d4015ef35172971ffe2cbc49f8205f42e3 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 9 May 2017 13:50:24 +0000 Subject: unnecessary Tcl_DStringInit(), since Tcl_WinUtfToTChar() already does that. --- macosx/tkMacOSXDialog.c | 6 +++--- win/tkWinSend.c | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index ca55c60..42cd1e5 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.c @@ -755,15 +755,15 @@ Tk_GetSaveFileObjCmd( [label setBordered:NO]; [label setBezeled:NO]; [label setDrawsBackground:NO]; - + NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) pullsDown:NO]; [popupButton addItemsWithTitles:saveFileTypes]; [popupButton setAction:@selector(saveFormat:)]; - + [accessoryView addSubview:label]; [accessoryView addSubview:popupButton]; [savepanel setAllowedFileTypes:saveFileTypes]; - + [savepanel setAccessoryView:accessoryView]; [savepanel setAllowsOtherFileTypes:YES]; } diff --git a/win/tkWinSend.c b/win/tkWinSend.c index c999c0b..fca8561 100644 --- a/win/tkWinSend.c +++ b/win/tkWinSend.c @@ -619,7 +619,6 @@ BuildMoniker( LPMONIKER pmkItem = NULL; Tcl_DString dString; - Tcl_DStringInit(&dString); Tcl_WinUtfToTChar(name, -1, &dString); hr = CreateFileMoniker((LPOLESTR)Tcl_DStringValue(&dString), &pmkItem); Tcl_DStringFree(&dString); -- cgit v0.12 From e41b58b108a24a08463fbc083fbfae137d3a8897 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 10 May 2017 09:04:55 +0000 Subject: New internal function TkpCancelWarp(), which does a proper warp clean-up when the display is closed. Follow-up to [db8c541b6bff91848c53006b0fe352136fbd4be9|db8c541b6b]. Backported from androwish [http://www.androwish.org/index.html/info/0b3392c9134c228f|0b3392c9134c228f] (which was a little more than just a "add tk upstream changes" ...). Thanks, Christian! --- generic/tkBind.c | 38 ++++++++++++++++++++++++++++++-------- generic/tkInt.h | 1 + generic/tkWindow.c | 2 ++ 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/generic/tkBind.c b/generic/tkBind.c index 61b44df..285b3f7 100644 --- a/generic/tkBind.c +++ b/generic/tkBind.c @@ -1267,7 +1267,7 @@ Tk_BindEvent( */ if ((eventPtr->type >= TK_LASTEVENT) || !flagArray[eventPtr->type]) { - return; + return; } dispPtr = ((TkWindow *) tkwin)->dispPtr; @@ -2878,7 +2878,7 @@ GetAllVirtualEvents( * Any other fields in eventPtr which are not specified by the pattern * string or the optional arguments, are set to 0. * - * The event may be handled sychronously or asynchronously, depending on + * The event may be handled synchronously or asynchronously, depending on * the value specified by the optional "-when" option. The default * setting is synchronous. * @@ -3466,12 +3466,7 @@ HandleEventGenerate( if ((warp != 0) && Tk_IsMapped(tkwin)) { TkDisplay *dispPtr = TkGetDisplay(event.general.xmotion.display); - /* - * TODO: No protection is in place to handle dispPtr destruction - * before DoWarp is called back. - */ - - Tk_Window warpWindow = Tk_IdToWindow(dispPtr->display, +Tk_Window warpWindow = Tk_IdToWindow(dispPtr->display, event.general.xmotion.window); if (!(dispPtr->flags & TK_DISPLAY_IN_WARP)) { @@ -4321,6 +4316,33 @@ TkpGetBindingXEvent( } /* + *---------------------------------------------------------------------- + * + * TkpCancelWarp -- + * + * This function cancels an outstanding pointer warp and + * is called during tear down of the display. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +void +TkpCancelWarp( + TkDisplay *dispPtr) +{ + if (dispPtr->flags & TK_DISPLAY_IN_WARP) { + Tcl_CancelIdleCall(DoWarp, dispPtr); + dispPtr->flags &= ~TK_DISPLAY_IN_WARP; + } +} + +/* * Local Variables: * mode: c * c-basic-offset: 4 diff --git a/generic/tkInt.h b/generic/tkInt.h index f00d833..a28cae4 100644 --- a/generic/tkInt.h +++ b/generic/tkInt.h @@ -1223,6 +1223,7 @@ MODULE_SCOPE int TkInitTkCmd(Tcl_Interp *interp, MODULE_SCOPE int TkInitFontchooser(Tcl_Interp *interp, ClientData clientData); MODULE_SCOPE void TkpWarpPointer(TkDisplay *dispPtr); +MODULE_SCOPE void TkpCancelWarp(TkDisplay *dispPtr); MODULE_SCOPE int TkListCreateFrame(ClientData clientData, Tcl_Interp *interp, Tcl_Obj *listObj, int toplevel, Tcl_Obj *nameObj); diff --git a/generic/tkWindow.c b/generic/tkWindow.c index 690a841..2848ff5 100644 --- a/generic/tkWindow.c +++ b/generic/tkWindow.c @@ -239,6 +239,8 @@ TkCloseDisplay( { TkClipCleanup(dispPtr); + TkpCancelWarp(dispPtr); + if (dispPtr->name != NULL) { ckfree(dispPtr->name); } -- cgit v0.12 From 0feebd2bb96d0045ad6b67352539c022d2f148da Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 12 May 2017 08:57:19 +0000 Subject: Revert [f38091d0]: If TK_LAYOUT_WITH_BASE_CHUNKS is set (MacOSX), this change leads to crash, struct CharInfo is defined differently depending on TK_LAYOUT_WITH_BASE_CHUNKS (however strange that is ...) --- generic/tkTextDisp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c index 03d11e1..371e910 100644 --- a/generic/tkTextDisp.c +++ b/generic/tkTextDisp.c @@ -7561,7 +7561,7 @@ TkTextCharLayoutProc( ciPtr = &bciPtr->ci; } else { bciPtr = baseCharChunkPtr->clientData; - ciPtr = ckalloc(Tk_Offset(CharInfo, chars) + 1); + ciPtr = ckalloc(sizeof(CharInfo)); baseString = &bciPtr->baseChars; } -- cgit v0.12 From c257b74035bb102d5860b77c9484c8e7e5ee833c Mon Sep 17 00:00:00 2001 From: Kevin Walzer Date: Sat, 13 May 2017 16:34:32 +0000 Subject: Major reworking of tkMacOSXDialog.c to support -typevariable, improve file filtering, fix for 3588462; thanks to Christian Gollwitzer for patch --- macosx/tkMacOSXDialog.c | 490 ++++++++++++++++++++++++++++++------------------ 1 file changed, 310 insertions(+), 180 deletions(-) diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index 42cd1e5..2670b32 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.c @@ -6,6 +6,7 @@ * Copyright (c) 1996-1997 Sun Microsystems, Inc. * Copyright 2001-2009, Apple Inc. * Copyright (c) 2006-2009 Daniel A. Steffen + * Copyright (c) 2017 Christian Gollwitzer. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. @@ -25,8 +26,19 @@ #define modalError -2 /*Vars for filtering in "open file" and "save file" dialogs.*/ -NSMutableArray *openFileTypes; -NSMutableArray *saveFileTypes; +typedef struct { + bool doFileTypes; // show the accessory view which displays the filter menu + bool preselectFilter; // a filter was selected by the typevariable + bool userHasSelectedFilter; // The user has changed the filter in the accessory view + NSMutableArray *fileTypeNames; // array of names, e.g. "Text document" + NSMutableArray *fileTypeExtensions; // array of allowed extensions per name, e.g. "txt", "doc" + NSMutableArray *fileTypeLabels; // displayed string, e.g. "Text document (.txt, .doc)" + NSMutableArray *allAllowedExtensions; // set of all allowed extensions + NSInteger fileTypeIndex; // index of currently selected filter +} filepanelFilterInfo; + +filepanelFilterInfo filterInfo; + NSOpenPanel *openpanel; NSSavePanel *savepanel; @@ -256,22 +268,18 @@ static NSURL *getFileURL(NSString *directory, NSString *filename) { - (void)selectFormat:(id)sender { NSPopUpButton *button = (NSPopUpButton *)sender; - NSInteger selectedItemIndex = [button indexOfSelectedItem]; - openFileTypes = nil; - openFileTypes = [NSMutableArray array]; - [openFileTypes addObject:[button titleOfSelectedItem]]; - [openpanel setAllowedFileTypes:openFileTypes]; + filterInfo.fileTypeIndex = [button indexOfSelectedItem]; + NSMutableArray *allowedtypes = filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex]; + [openpanel setAllowedFileTypes:allowedtypes]; + filterInfo.userHasSelectedFilter = true; } - (void)saveFormat:(id)sender { NSPopUpButton *button = (NSPopUpButton *)sender; - NSInteger selectedItemIndex = [button indexOfSelectedItem]; - saveFileTypes = nil; - saveFileTypes = [NSMutableArray array]; - [saveFileTypes addObject:[button titleOfSelectedItem]]; - [savepanel setAllowedFileTypes:saveFileTypes]; - + filterInfo.fileTypeIndex = [button indexOfSelectedItem]; + NSMutableArray *allowedtypes = filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex]; + [savepanel setAllowedFileTypes:allowedtypes]; } @end @@ -387,6 +395,98 @@ Tk_ChooseColorObjCmd( end: return result; } + +/* dissect the -filetype nested lists and store the information + * in the filterInfo structure */ +int parseFileFilters(Tcl_Interp *interp, Tcl_Obj *fileTypesPtr, Tcl_Obj *typeVariablePtr) { + + if (!fileTypesPtr) { + filterInfo.doFileTypes = false; + return TCL_OK; + } + + FileFilterList fl; + TkInitFileFilters(&fl); + if (TkGetFileFilters(interp, &fl, fileTypesPtr, 0) != TCL_OK) { + TkFreeFileFilters(&fl); + return TCL_ERROR; + } + + filterInfo.doFileTypes = (fl.filters != NULL); + + filterInfo.fileTypeIndex = 0; + filterInfo.fileTypeExtensions = [NSMutableArray array]; + filterInfo.fileTypeNames = [NSMutableArray array]; + filterInfo.fileTypeLabels = [NSMutableArray array]; + filterInfo.allAllowedExtensions = [NSMutableArray array]; + + if (filterInfo.doFileTypes) { + for (FileFilter *filterPtr = fl.filters; filterPtr; + filterPtr = filterPtr->next) { + NSString * name = [[NSString alloc] initWithUTF8String: filterPtr -> name]; + [filterInfo.fileTypeNames addObject:name]; + [name release]; + NSMutableArray * clauseextensions = [NSMutableArray array]; + NSMutableArray * displayextensions = [NSMutableArray array]; + + for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr; + clausePtr = clausePtr->next) { + for (GlobPattern *globPtr = clausePtr->patterns; globPtr; + globPtr = globPtr->next) { + const char *str = globPtr->pattern; + while (*str && (*str == '*' || *str == '.')) { + str++; + } + if (*str) { + NSString *extension = [[NSString alloc] initWithUTF8String:str]; + if (![filterInfo.allAllowedExtensions containsObject:extension]) { + [filterInfo.allAllowedExtensions addObject:extension]; + } + + [clauseextensions addObject:extension]; + [displayextensions addObject:[@"." stringByAppendingString:extension]]; + + [extension release]; + } + } + } + [filterInfo.fileTypeExtensions addObject:clauseextensions]; + + NSMutableString * label = [[NSMutableString alloc] initWithString:name]; + [label appendString:@" ("]; + [label appendString:[displayextensions componentsJoinedByString:@", "]]; + [label appendString:@")"]; + [filterInfo.fileTypeLabels addObject:label]; + [label release]; + + } + + /* Check if the typevariable exists and matches one of the names */ + filterInfo.preselectFilter = false; + filterInfo.userHasSelectedFilter = false; + if (typeVariablePtr) { + /* extract the variable content as a NSString */ + Tcl_Obj *selectedFileTypeObj = Tcl_ObjGetVar2(interp, typeVariablePtr, NULL, TCL_GLOBAL_ONLY); + + /* check that the typevariable exists */ + if (selectedFileTypeObj != NULL) { + const char *selectedFileType = Tcl_GetString(selectedFileTypeObj); + NSString *selectedFileTypeStr = [[NSString alloc] initWithUTF8String:selectedFileType]; + NSUInteger index = [filterInfo.fileTypeNames indexOfObject:selectedFileTypeStr]; + + if (index != NSNotFound) { + filterInfo.fileTypeIndex = index; + filterInfo.preselectFilter = true; + } + } + } + + } + + TkFreeFileFilters(&fl); + return TCL_OK; +} + /* *---------------------------------------------------------------------- @@ -415,18 +515,16 @@ Tk_GetOpenFileObjCmd( char *str; int i, result = TCL_ERROR, haveParentOption = 0; int index, len, multiple = 0; - FileFilterList fl; - Tcl_Obj *cmdObj = NULL, *typeVariablePtr = NULL; + Tcl_Obj *cmdObj = NULL, *typeVariablePtr = NULL, *fileTypesPtr = NULL; FilePanelCallbackInfo callbackInfoStruct; FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct; NSString *directory = nil, *filename = nil; - NSString *message, *title, *type; + NSString *message = nil, *title = nil; NSWindow *parent; openpanel = [NSOpenPanel openPanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; - TkInitFileFilters(&fl); for (i = 1; i < objc; i += 2) { if (Tcl_GetIndexFromObjStruct(interp, objv[i], openOptionStrings, sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { @@ -442,9 +540,7 @@ Tk_GetOpenFileObjCmd( case OPEN_DEFAULT: break; case OPEN_FILETYPES: - if (TkGetFileFilters(interp, &fl, objv[i + 1], 0) != TCL_OK) { - goto end; - } + fileTypesPtr = objv[i + 1]; break; case OPEN_INITDIR: str = Tcl_GetStringFromObj(objv[i + 1], &len); @@ -464,8 +560,6 @@ Tk_GetOpenFileObjCmd( case OPEN_MESSAGE: message = [[NSString alloc] initWithUTF8String: Tcl_GetString(objv[i + 1])]; - [openpanel setMessage:message]; - [message release]; break; case OPEN_MULTIPLE: if (Tcl_GetBooleanFromObj(interp, objv[i + 1], @@ -484,8 +578,6 @@ Tk_GetOpenFileObjCmd( case OPEN_TITLE: title = [[NSString alloc] initWithUTF8String: Tcl_GetString(objv[i + 1])]; - [openpanel setTitle:title]; - [title release]; break; case OPEN_TYPEVARIABLE: typeVariablePtr = objv[i + 1]; @@ -495,57 +587,70 @@ Tk_GetOpenFileObjCmd( break; } } - [openpanel setAllowsMultipleSelection:multiple]; - if (fl.filters) { - openFileTypes = [NSMutableArray array]; - for (FileFilter *filterPtr = fl.filters; filterPtr; - filterPtr = filterPtr->next) { - for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr; - clausePtr = clausePtr->next) { - for (GlobPattern *globPtr = clausePtr->patterns; globPtr; - globPtr = globPtr->next) { - str = globPtr->pattern; - while (*str && (*str == '*' || *str == '.')) { - str++; - } - if (*str) { - type = [[NSString alloc] initWithUTF8String:str]; - if (![openFileTypes containsObject:type]) { - [openFileTypes addObject:type]; - } - [type release]; - } - } - for (MacFileType *mfPtr = clausePtr->macTypes; mfPtr; - mfPtr = mfPtr->next) { - if (mfPtr->type) { - type = NSFileTypeForHFSTypeCode(mfPtr->type); - if (![openFileTypes containsObject:type]) { - /*Do nothing here, type and creator codes now ignored on macOS.*/ - } - } - } - } + + /* From OSX 10.11, the title string is silently ignored. + * Prepend the title to the message + * NOTE should be conditional on OSX version, but + * -mmacosx-version-min does not revert this behaviour*/ + if (title) { + [openpanel setTitle:title]; + if (message) { + NSString *fullmessage = [[NSString alloc] initWithFormat:@"%@\n%@",title,message]; + [message release]; + [title release]; + message = fullmessage; + } else { + message = title; } } - NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)]; - NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)]; - [label setEditable:NO]; - [label setStringValue:@"Enable:"]; - [label setBordered:NO]; - [label setBezeled:NO]; - [label setDrawsBackground:NO]; + if (message) { + [openpanel setMessage:message]; + [message release]; + } - NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) pullsDown:NO]; - [popupButton addItemsWithTitles:openFileTypes]; - [popupButton setAction:@selector(selectFormat:)]; + [openpanel setAllowsMultipleSelection:multiple]; + + if (parseFileFilters(interp, fileTypesPtr, typeVariablePtr) != TCL_OK) { + goto end; + } - [accessoryView addSubview:label]; - [accessoryView addSubview:popupButton]; - [openpanel setAllowedFileTypes:openFileTypes]; + if (filterInfo.doFileTypes) { + NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)]; + NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)]; + [label setEditable:NO]; + [label setStringValue:@"Enable:"]; + [label setBordered:NO]; + [label setBezeled:NO]; + [label setDrawsBackground:NO]; + + NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) pullsDown:NO]; + [popupButton addItemsWithTitles:filterInfo.fileTypeLabels]; + [popupButton setAction:@selector(selectFormat:)]; + + [accessoryView addSubview:label]; + [accessoryView addSubview:popupButton]; + + if (filterInfo.preselectFilter) { + /* A specific filter was selected from the typevariable. Select it and + * open the accessory view */ + [popupButton selectItemAtIndex:filterInfo.fileTypeIndex]; + /* on OSX > 10.11, the optons are not visible by default. Ergo allow all file types + [openpanel setAllowedFileTypes:filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex]]; + */ + [openpanel setAllowedFileTypes:filterInfo.allAllowedExtensions]; + } else { + [openpanel setAllowedFileTypes:filterInfo.allAllowedExtensions]; + } + + [openpanel setAllowsOtherFileTypes:NO]; + + [openpanel setAccessoryView:accessoryView]; + } else { + /* No filters are given. Allow picking all files */ + [openpanel setAllowsOtherFileTypes:YES]; + } - [openpanel setAccessoryView:accessoryView]; if (cmdObj) { callbackInfo = ckalloc(sizeof(FilePanelCallbackInfo)); if (Tcl_IsShared(cmdObj)) { @@ -553,6 +658,7 @@ Tk_GetOpenFileObjCmd( } Tcl_IncrRefCount(cmdObj); } + callbackInfo->cmdObj = cmdObj; callbackInfo->interp = interp; callbackInfo->multiple = multiple; @@ -569,7 +675,6 @@ Tk_GetOpenFileObjCmd( @selector(tkFilePanelDidEnd:returnCode:contextInfo:) contextInfo:callbackInfo]; #else - [openpanel setAllowedFileTypes:openFileTypes]; [openpanel setDirectoryURL:getFileURL(directory, filename)]; [openpanel beginSheetModalForWindow:parent completionHandler:^(NSInteger returnCode) @@ -593,17 +698,22 @@ Tk_GetOpenFileObjCmd( if (parentIsKey) { [parent makeKeyWindow]; } - if (typeVariablePtr && result == TCL_OK) { + + if ((typeVariablePtr && (modalReturnCode == NSOKButton)) && + filterInfo.doFileTypes && filterInfo.userHasSelectedFilter) { /* - * The -typevariable option is not really supported. + * The -typevariable must be set to the selected file type, if the dialog was not cancelled */ - - Tcl_SetVar2(interp, Tcl_GetString(typeVariablePtr), NULL, - "", TCL_GLOBAL_ONLY); + #if 0 + NSLog(@"result: %i modal: %li", result, (long)modalReturnCode); + #endif + NSString * selectedFilter = filterInfo.fileTypeNames[filterInfo.fileTypeIndex]; + Tcl_ObjSetVar2(interp, typeVariablePtr, NULL, + Tcl_NewStringObj([selectedFilter UTF8String], -1), TCL_GLOBAL_ONLY); } + end: - TkFreeFileFilters(&fl); return result; } @@ -636,19 +746,16 @@ Tk_GetSaveFileObjCmd( int i, result = TCL_ERROR, haveParentOption = 0; int confirmOverwrite = 1; int index, len; - FileFilterList fl; - Tcl_Obj *cmdObj = NULL; + Tcl_Obj *cmdObj = NULL, *typeVariablePtr = NULL, *fileTypesPtr = NULL; FilePanelCallbackInfo callbackInfoStruct; FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct; NSString *directory = nil, *filename = nil, *defaultType = nil; - NSString *message, *title, *type; + NSString *message = nil, *title = nil; NSWindow *parent; - NSMutableArray *fileTypes = nil; savepanel = [NSSavePanel savePanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; - TkInitFileFilters(&fl); for (i = 1; i < objc; i += 2) { if (Tcl_GetIndexFromObjStruct(interp, objv[i], saveOptionStrings, sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { @@ -661,114 +768,120 @@ Tk_GetSaveFileObjCmd( goto end; } switch (index) { - case SAVE_DEFAULT: - str = Tcl_GetStringFromObj(objv[i + 1], &len); - while (*str && (*str == '*' || *str == '.')) { - str++; - } - if (*str) { - defaultType = [[[NSString alloc] initWithUTF8String:str] - autorelease]; - } - break; - case SAVE_FILETYPES: - if (TkGetFileFilters(interp, &fl, objv[i + 1], 0) != TCL_OK) { - goto end; - } - break; - case SAVE_INITDIR: - str = Tcl_GetStringFromObj(objv[i + 1], &len); - if (len) { - directory = [[[NSString alloc] initWithUTF8String:str] - autorelease]; - } - break; - case SAVE_INITFILE: - str = Tcl_GetStringFromObj(objv[i + 1], &len); - if (len) { - filename = [[[NSString alloc] initWithUTF8String:str] - autorelease]; - [savepanel setNameFieldStringValue:filename]; - } - break; - case SAVE_MESSAGE: - message = [[NSString alloc] initWithUTF8String: - Tcl_GetString(objv[i + 1])]; - [savepanel setMessage:message]; + case SAVE_DEFAULT: + str = Tcl_GetStringFromObj(objv[i + 1], &len); + while (*str && (*str == '*' || *str == '.')) { + str++; + } + if (*str) { + defaultType = [[[NSString alloc] initWithUTF8String:str] + autorelease]; + } + break; + case SAVE_FILETYPES: + fileTypesPtr = objv[i + 1]; + break; + case SAVE_INITDIR: + str = Tcl_GetStringFromObj(objv[i + 1], &len); + if (len) { + directory = [[[NSString alloc] initWithUTF8String:str] + autorelease]; + } + break; + case SAVE_INITFILE: + str = Tcl_GetStringFromObj(objv[i + 1], &len); + if (len) { + filename = [[[NSString alloc] initWithUTF8String:str] + autorelease]; + [savepanel setNameFieldStringValue:filename]; + } + break; + case SAVE_MESSAGE: + message = [[NSString alloc] initWithUTF8String: + Tcl_GetString(objv[i + 1])]; + break; + case SAVE_PARENT: + str = Tcl_GetStringFromObj(objv[i + 1], &len); + tkwin = Tk_NameToWindow(interp, str, tkwin); + if (!tkwin) { + goto end; + } + haveParentOption = 1; + break; + case SAVE_TITLE: + title = [[NSString alloc] initWithUTF8String: + Tcl_GetString(objv[i + 1])]; + break; + case SAVE_TYPEVARIABLE: + typeVariablePtr = objv[i + 1]; + break; + case SAVE_COMMAND: + cmdObj = objv[i+1]; + break; + case SAVE_CONFIRMOW: + if (Tcl_GetBooleanFromObj(interp, objv[i + 1], + &confirmOverwrite) != TCL_OK) { + goto end; + } + break; + } + } + + if (title) { + [savepanel setTitle:title]; + if (message) { + NSString *fullmessage = [[NSString alloc] initWithFormat:@"%@\n%@",title,message]; [message release]; - break; - case SAVE_PARENT: - str = Tcl_GetStringFromObj(objv[i + 1], &len); - tkwin = Tk_NameToWindow(interp, str, tkwin); - if (!tkwin) { - goto end; - } - haveParentOption = 1; - break; - case SAVE_TITLE: - title = [[NSString alloc] initWithUTF8String: - Tcl_GetString(objv[i + 1])]; - [savepanel setTitle:title]; [title release]; - break; - case SAVE_TYPEVARIABLE: - break; - case SAVE_COMMAND: - cmdObj = objv[i+1]; - break; - case SAVE_CONFIRMOW: - if (Tcl_GetBooleanFromObj(interp, objv[i + 1], - &confirmOverwrite) != TCL_OK) { - goto end; - } - break; + message = fullmessage; + } else { + message = title; } } - if (fl.filters || defaultType) { - saveFileTypes = [NSMutableArray array]; - for (FileFilter *filterPtr = fl.filters; filterPtr; - filterPtr = filterPtr->next) { - for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr; - clausePtr = clausePtr->next) { - for (GlobPattern *globPtr = clausePtr->patterns; globPtr; - globPtr = globPtr->next) { - str = globPtr->pattern; - while (*str && (*str == '*' || *str == '.')) { - str++; - } - if (*str) { - type = [[NSString alloc] initWithUTF8String:str]; - if (![saveFileTypes containsObject:type]) { - [saveFileTypes addObject:type]; - } - [type release]; - } - } - } - } - - - NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)]; - NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)]; - [label setEditable:NO]; - [label setStringValue:@"Enable:"]; - [label setBordered:NO]; - [label setBezeled:NO]; - [label setDrawsBackground:NO]; - NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) pullsDown:NO]; - [popupButton addItemsWithTitles:saveFileTypes]; - [popupButton setAction:@selector(saveFormat:)]; + if (message) { + [savepanel setMessage:message]; + [message release]; + } - [accessoryView addSubview:label]; - [accessoryView addSubview:popupButton]; - [savepanel setAllowedFileTypes:saveFileTypes]; + if (parseFileFilters(interp, fileTypesPtr, typeVariablePtr) != TCL_OK) { + goto end; + } - [savepanel setAccessoryView:accessoryView]; - [savepanel setAllowsOtherFileTypes:YES]; + if (filterInfo.doFileTypes) { + NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)]; + NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)]; + [label setEditable:NO]; + [label setStringValue:NSLocalizedString(@"Format:", nil)]; + [label setBordered:NO]; + [label setBezeled:NO]; + [label setDrawsBackground:NO]; + + NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) pullsDown:NO]; + [popupButton addItemsWithTitles:filterInfo.fileTypeLabels]; + [popupButton selectItemAtIndex:filterInfo.fileTypeIndex]; + [popupButton setAction:@selector(saveFormat:)]; + + [accessoryView addSubview:label]; + [accessoryView addSubview:popupButton]; + + [savepanel setAccessoryView:accessoryView]; + + [savepanel setAllowedFileTypes:filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex]]; + [savepanel setAllowsOtherFileTypes:NO]; + } else if (defaultType) { + /* If no filetypes are given, defaultextension is an alternative way + * to specify the attached extension. Just propose this extension, + * but don't display an accessory view */ + NSMutableArray *AllowedFileTypes = [NSMutableArray array]; + [AllowedFileTypes addObject:defaultType]; + [savepanel setAllowedFileTypes:AllowedFileTypes]; + [savepanel setAllowsOtherFileTypes:YES]; } + [savepanel setCanSelectHiddenExtension:YES]; [savepanel setExtensionHidden:NO]; + if (cmdObj) { callbackInfo = ckalloc(sizeof(FilePanelCallbackInfo)); if (Tcl_IsShared(cmdObj)) { @@ -779,6 +892,7 @@ Tk_GetSaveFileObjCmd( callbackInfo->cmdObj = cmdObj; callbackInfo->interp = interp; callbackInfo->multiple = 0; + parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window); if (haveParentOption && parent && ![parent attachedSheet]) { parentIsKey = [parent isKeyWindow]; @@ -805,6 +919,9 @@ Tk_GetSaveFileObjCmd( #else [savepanel setDirectoryURL:getFileURL(directory, filename)]; modalReturnCode = [savepanel runModal]; + #if 0 + NSLog(@"modal: %li", modalReturnCode); + #endif #endif [NSApp tkFilePanelDidEnd:savepanel returnCode:modalReturnCode contextInfo:callbackInfo]; @@ -813,8 +930,21 @@ Tk_GetSaveFileObjCmd( if (parentIsKey) { [parent makeKeyWindow]; } + + if ((typeVariablePtr && (modalReturnCode == NSOKButton)) && filterInfo.doFileTypes) { + /* + * The -typevariable must be set to the selected file type, if the dialog was not cancelled + */ + #if 0 + NSLog(@"result: %i modal: %li", result, (long)modalReturnCode); + #endif + NSString * selectedFilter = filterInfo.fileTypeNames[filterInfo.fileTypeIndex]; + Tcl_ObjSetVar2(interp, typeVariablePtr, NULL, + Tcl_NewStringObj([selectedFilter UTF8String], -1), TCL_GLOBAL_ONLY); + } + + end: - TkFreeFileFilters(&fl); return result; } -- cgit v0.12 From 21e2160139d6fe5b918c1ebb724a4b3ffea34146 Mon Sep 17 00:00:00 2001 From: Kevin Walzer Date: Sat, 13 May 2017 16:35:47 +0000 Subject: Major reworking of tkMacOSXDialog.c to support -typevariable, improve file filtering, fix for 3588462; thanks to Christian Gollwitzer for patch --- macosx/tkMacOSXDialog.c | 490 ++++++++++++++++++++++++++++++------------------ 1 file changed, 310 insertions(+), 180 deletions(-) diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index 42cd1e5..2670b32 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.c @@ -6,6 +6,7 @@ * Copyright (c) 1996-1997 Sun Microsystems, Inc. * Copyright 2001-2009, Apple Inc. * Copyright (c) 2006-2009 Daniel A. Steffen + * Copyright (c) 2017 Christian Gollwitzer. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. @@ -25,8 +26,19 @@ #define modalError -2 /*Vars for filtering in "open file" and "save file" dialogs.*/ -NSMutableArray *openFileTypes; -NSMutableArray *saveFileTypes; +typedef struct { + bool doFileTypes; // show the accessory view which displays the filter menu + bool preselectFilter; // a filter was selected by the typevariable + bool userHasSelectedFilter; // The user has changed the filter in the accessory view + NSMutableArray *fileTypeNames; // array of names, e.g. "Text document" + NSMutableArray *fileTypeExtensions; // array of allowed extensions per name, e.g. "txt", "doc" + NSMutableArray *fileTypeLabels; // displayed string, e.g. "Text document (.txt, .doc)" + NSMutableArray *allAllowedExtensions; // set of all allowed extensions + NSInteger fileTypeIndex; // index of currently selected filter +} filepanelFilterInfo; + +filepanelFilterInfo filterInfo; + NSOpenPanel *openpanel; NSSavePanel *savepanel; @@ -256,22 +268,18 @@ static NSURL *getFileURL(NSString *directory, NSString *filename) { - (void)selectFormat:(id)sender { NSPopUpButton *button = (NSPopUpButton *)sender; - NSInteger selectedItemIndex = [button indexOfSelectedItem]; - openFileTypes = nil; - openFileTypes = [NSMutableArray array]; - [openFileTypes addObject:[button titleOfSelectedItem]]; - [openpanel setAllowedFileTypes:openFileTypes]; + filterInfo.fileTypeIndex = [button indexOfSelectedItem]; + NSMutableArray *allowedtypes = filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex]; + [openpanel setAllowedFileTypes:allowedtypes]; + filterInfo.userHasSelectedFilter = true; } - (void)saveFormat:(id)sender { NSPopUpButton *button = (NSPopUpButton *)sender; - NSInteger selectedItemIndex = [button indexOfSelectedItem]; - saveFileTypes = nil; - saveFileTypes = [NSMutableArray array]; - [saveFileTypes addObject:[button titleOfSelectedItem]]; - [savepanel setAllowedFileTypes:saveFileTypes]; - + filterInfo.fileTypeIndex = [button indexOfSelectedItem]; + NSMutableArray *allowedtypes = filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex]; + [savepanel setAllowedFileTypes:allowedtypes]; } @end @@ -387,6 +395,98 @@ Tk_ChooseColorObjCmd( end: return result; } + +/* dissect the -filetype nested lists and store the information + * in the filterInfo structure */ +int parseFileFilters(Tcl_Interp *interp, Tcl_Obj *fileTypesPtr, Tcl_Obj *typeVariablePtr) { + + if (!fileTypesPtr) { + filterInfo.doFileTypes = false; + return TCL_OK; + } + + FileFilterList fl; + TkInitFileFilters(&fl); + if (TkGetFileFilters(interp, &fl, fileTypesPtr, 0) != TCL_OK) { + TkFreeFileFilters(&fl); + return TCL_ERROR; + } + + filterInfo.doFileTypes = (fl.filters != NULL); + + filterInfo.fileTypeIndex = 0; + filterInfo.fileTypeExtensions = [NSMutableArray array]; + filterInfo.fileTypeNames = [NSMutableArray array]; + filterInfo.fileTypeLabels = [NSMutableArray array]; + filterInfo.allAllowedExtensions = [NSMutableArray array]; + + if (filterInfo.doFileTypes) { + for (FileFilter *filterPtr = fl.filters; filterPtr; + filterPtr = filterPtr->next) { + NSString * name = [[NSString alloc] initWithUTF8String: filterPtr -> name]; + [filterInfo.fileTypeNames addObject:name]; + [name release]; + NSMutableArray * clauseextensions = [NSMutableArray array]; + NSMutableArray * displayextensions = [NSMutableArray array]; + + for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr; + clausePtr = clausePtr->next) { + for (GlobPattern *globPtr = clausePtr->patterns; globPtr; + globPtr = globPtr->next) { + const char *str = globPtr->pattern; + while (*str && (*str == '*' || *str == '.')) { + str++; + } + if (*str) { + NSString *extension = [[NSString alloc] initWithUTF8String:str]; + if (![filterInfo.allAllowedExtensions containsObject:extension]) { + [filterInfo.allAllowedExtensions addObject:extension]; + } + + [clauseextensions addObject:extension]; + [displayextensions addObject:[@"." stringByAppendingString:extension]]; + + [extension release]; + } + } + } + [filterInfo.fileTypeExtensions addObject:clauseextensions]; + + NSMutableString * label = [[NSMutableString alloc] initWithString:name]; + [label appendString:@" ("]; + [label appendString:[displayextensions componentsJoinedByString:@", "]]; + [label appendString:@")"]; + [filterInfo.fileTypeLabels addObject:label]; + [label release]; + + } + + /* Check if the typevariable exists and matches one of the names */ + filterInfo.preselectFilter = false; + filterInfo.userHasSelectedFilter = false; + if (typeVariablePtr) { + /* extract the variable content as a NSString */ + Tcl_Obj *selectedFileTypeObj = Tcl_ObjGetVar2(interp, typeVariablePtr, NULL, TCL_GLOBAL_ONLY); + + /* check that the typevariable exists */ + if (selectedFileTypeObj != NULL) { + const char *selectedFileType = Tcl_GetString(selectedFileTypeObj); + NSString *selectedFileTypeStr = [[NSString alloc] initWithUTF8String:selectedFileType]; + NSUInteger index = [filterInfo.fileTypeNames indexOfObject:selectedFileTypeStr]; + + if (index != NSNotFound) { + filterInfo.fileTypeIndex = index; + filterInfo.preselectFilter = true; + } + } + } + + } + + TkFreeFileFilters(&fl); + return TCL_OK; +} + /* *---------------------------------------------------------------------- @@ -415,18 +515,16 @@ Tk_GetOpenFileObjCmd( char *str; int i, result = TCL_ERROR, haveParentOption = 0; int index, len, multiple = 0; - FileFilterList fl; - Tcl_Obj *cmdObj = NULL, *typeVariablePtr = NULL; + Tcl_Obj *cmdObj = NULL, *typeVariablePtr = NULL, *fileTypesPtr = NULL; FilePanelCallbackInfo callbackInfoStruct; FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct; NSString *directory = nil, *filename = nil; - NSString *message, *title, *type; + NSString *message = nil, *title = nil; NSWindow *parent; openpanel = [NSOpenPanel openPanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; - TkInitFileFilters(&fl); for (i = 1; i < objc; i += 2) { if (Tcl_GetIndexFromObjStruct(interp, objv[i], openOptionStrings, sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { @@ -442,9 +540,7 @@ Tk_GetOpenFileObjCmd( case OPEN_DEFAULT: break; case OPEN_FILETYPES: - if (TkGetFileFilters(interp, &fl, objv[i + 1], 0) != TCL_OK) { - goto end; - } + fileTypesPtr = objv[i + 1]; break; case OPEN_INITDIR: str = Tcl_GetStringFromObj(objv[i + 1], &len); @@ -464,8 +560,6 @@ Tk_GetOpenFileObjCmd( case OPEN_MESSAGE: message = [[NSString alloc] initWithUTF8String: Tcl_GetString(objv[i + 1])]; - [openpanel setMessage:message]; - [message release]; break; case OPEN_MULTIPLE: if (Tcl_GetBooleanFromObj(interp, objv[i + 1], @@ -484,8 +578,6 @@ Tk_GetOpenFileObjCmd( case OPEN_TITLE: title = [[NSString alloc] initWithUTF8String: Tcl_GetString(objv[i + 1])]; - [openpanel setTitle:title]; - [title release]; break; case OPEN_TYPEVARIABLE: typeVariablePtr = objv[i + 1]; @@ -495,57 +587,70 @@ Tk_GetOpenFileObjCmd( break; } } - [openpanel setAllowsMultipleSelection:multiple]; - if (fl.filters) { - openFileTypes = [NSMutableArray array]; - for (FileFilter *filterPtr = fl.filters; filterPtr; - filterPtr = filterPtr->next) { - for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr; - clausePtr = clausePtr->next) { - for (GlobPattern *globPtr = clausePtr->patterns; globPtr; - globPtr = globPtr->next) { - str = globPtr->pattern; - while (*str && (*str == '*' || *str == '.')) { - str++; - } - if (*str) { - type = [[NSString alloc] initWithUTF8String:str]; - if (![openFileTypes containsObject:type]) { - [openFileTypes addObject:type]; - } - [type release]; - } - } - for (MacFileType *mfPtr = clausePtr->macTypes; mfPtr; - mfPtr = mfPtr->next) { - if (mfPtr->type) { - type = NSFileTypeForHFSTypeCode(mfPtr->type); - if (![openFileTypes containsObject:type]) { - /*Do nothing here, type and creator codes now ignored on macOS.*/ - } - } - } - } + + /* From OSX 10.11, the title string is silently ignored. + * Prepend the title to the message + * NOTE should be conditional on OSX version, but + * -mmacosx-version-min does not revert this behaviour*/ + if (title) { + [openpanel setTitle:title]; + if (message) { + NSString *fullmessage = [[NSString alloc] initWithFormat:@"%@\n%@",title,message]; + [message release]; + [title release]; + message = fullmessage; + } else { + message = title; } } - NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)]; - NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)]; - [label setEditable:NO]; - [label setStringValue:@"Enable:"]; - [label setBordered:NO]; - [label setBezeled:NO]; - [label setDrawsBackground:NO]; + if (message) { + [openpanel setMessage:message]; + [message release]; + } - NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) pullsDown:NO]; - [popupButton addItemsWithTitles:openFileTypes]; - [popupButton setAction:@selector(selectFormat:)]; + [openpanel setAllowsMultipleSelection:multiple]; + + if (parseFileFilters(interp, fileTypesPtr, typeVariablePtr) != TCL_OK) { + goto end; + } - [accessoryView addSubview:label]; - [accessoryView addSubview:popupButton]; - [openpanel setAllowedFileTypes:openFileTypes]; + if (filterInfo.doFileTypes) { + NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)]; + NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)]; + [label setEditable:NO]; + [label setStringValue:@"Enable:"]; + [label setBordered:NO]; + [label setBezeled:NO]; + [label setDrawsBackground:NO]; + + NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) pullsDown:NO]; + [popupButton addItemsWithTitles:filterInfo.fileTypeLabels]; + [popupButton setAction:@selector(selectFormat:)]; + + [accessoryView addSubview:label]; + [accessoryView addSubview:popupButton]; + + if (filterInfo.preselectFilter) { + /* A specific filter was selected from the typevariable. Select it and + * open the accessory view */ + [popupButton selectItemAtIndex:filterInfo.fileTypeIndex]; + /* on OSX > 10.11, the optons are not visible by default. Ergo allow all file types + [openpanel setAllowedFileTypes:filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex]]; + */ + [openpanel setAllowedFileTypes:filterInfo.allAllowedExtensions]; + } else { + [openpanel setAllowedFileTypes:filterInfo.allAllowedExtensions]; + } + + [openpanel setAllowsOtherFileTypes:NO]; + + [openpanel setAccessoryView:accessoryView]; + } else { + /* No filters are given. Allow picking all files */ + [openpanel setAllowsOtherFileTypes:YES]; + } - [openpanel setAccessoryView:accessoryView]; if (cmdObj) { callbackInfo = ckalloc(sizeof(FilePanelCallbackInfo)); if (Tcl_IsShared(cmdObj)) { @@ -553,6 +658,7 @@ Tk_GetOpenFileObjCmd( } Tcl_IncrRefCount(cmdObj); } + callbackInfo->cmdObj = cmdObj; callbackInfo->interp = interp; callbackInfo->multiple = multiple; @@ -569,7 +675,6 @@ Tk_GetOpenFileObjCmd( @selector(tkFilePanelDidEnd:returnCode:contextInfo:) contextInfo:callbackInfo]; #else - [openpanel setAllowedFileTypes:openFileTypes]; [openpanel setDirectoryURL:getFileURL(directory, filename)]; [openpanel beginSheetModalForWindow:parent completionHandler:^(NSInteger returnCode) @@ -593,17 +698,22 @@ Tk_GetOpenFileObjCmd( if (parentIsKey) { [parent makeKeyWindow]; } - if (typeVariablePtr && result == TCL_OK) { + + if ((typeVariablePtr && (modalReturnCode == NSOKButton)) && + filterInfo.doFileTypes && filterInfo.userHasSelectedFilter) { /* - * The -typevariable option is not really supported. + * The -typevariable must be set to the selected file type, if the dialog was not cancelled */ - - Tcl_SetVar2(interp, Tcl_GetString(typeVariablePtr), NULL, - "", TCL_GLOBAL_ONLY); + #if 0 + NSLog(@"result: %i modal: %li", result, (long)modalReturnCode); + #endif + NSString * selectedFilter = filterInfo.fileTypeNames[filterInfo.fileTypeIndex]; + Tcl_ObjSetVar2(interp, typeVariablePtr, NULL, + Tcl_NewStringObj([selectedFilter UTF8String], -1), TCL_GLOBAL_ONLY); } + end: - TkFreeFileFilters(&fl); return result; } @@ -636,19 +746,16 @@ Tk_GetSaveFileObjCmd( int i, result = TCL_ERROR, haveParentOption = 0; int confirmOverwrite = 1; int index, len; - FileFilterList fl; - Tcl_Obj *cmdObj = NULL; + Tcl_Obj *cmdObj = NULL, *typeVariablePtr = NULL, *fileTypesPtr = NULL; FilePanelCallbackInfo callbackInfoStruct; FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct; NSString *directory = nil, *filename = nil, *defaultType = nil; - NSString *message, *title, *type; + NSString *message = nil, *title = nil; NSWindow *parent; - NSMutableArray *fileTypes = nil; savepanel = [NSSavePanel savePanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; - TkInitFileFilters(&fl); for (i = 1; i < objc; i += 2) { if (Tcl_GetIndexFromObjStruct(interp, objv[i], saveOptionStrings, sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { @@ -661,114 +768,120 @@ Tk_GetSaveFileObjCmd( goto end; } switch (index) { - case SAVE_DEFAULT: - str = Tcl_GetStringFromObj(objv[i + 1], &len); - while (*str && (*str == '*' || *str == '.')) { - str++; - } - if (*str) { - defaultType = [[[NSString alloc] initWithUTF8String:str] - autorelease]; - } - break; - case SAVE_FILETYPES: - if (TkGetFileFilters(interp, &fl, objv[i + 1], 0) != TCL_OK) { - goto end; - } - break; - case SAVE_INITDIR: - str = Tcl_GetStringFromObj(objv[i + 1], &len); - if (len) { - directory = [[[NSString alloc] initWithUTF8String:str] - autorelease]; - } - break; - case SAVE_INITFILE: - str = Tcl_GetStringFromObj(objv[i + 1], &len); - if (len) { - filename = [[[NSString alloc] initWithUTF8String:str] - autorelease]; - [savepanel setNameFieldStringValue:filename]; - } - break; - case SAVE_MESSAGE: - message = [[NSString alloc] initWithUTF8String: - Tcl_GetString(objv[i + 1])]; - [savepanel setMessage:message]; + case SAVE_DEFAULT: + str = Tcl_GetStringFromObj(objv[i + 1], &len); + while (*str && (*str == '*' || *str == '.')) { + str++; + } + if (*str) { + defaultType = [[[NSString alloc] initWithUTF8String:str] + autorelease]; + } + break; + case SAVE_FILETYPES: + fileTypesPtr = objv[i + 1]; + break; + case SAVE_INITDIR: + str = Tcl_GetStringFromObj(objv[i + 1], &len); + if (len) { + directory = [[[NSString alloc] initWithUTF8String:str] + autorelease]; + } + break; + case SAVE_INITFILE: + str = Tcl_GetStringFromObj(objv[i + 1], &len); + if (len) { + filename = [[[NSString alloc] initWithUTF8String:str] + autorelease]; + [savepanel setNameFieldStringValue:filename]; + } + break; + case SAVE_MESSAGE: + message = [[NSString alloc] initWithUTF8String: + Tcl_GetString(objv[i + 1])]; + break; + case SAVE_PARENT: + str = Tcl_GetStringFromObj(objv[i + 1], &len); + tkwin = Tk_NameToWindow(interp, str, tkwin); + if (!tkwin) { + goto end; + } + haveParentOption = 1; + break; + case SAVE_TITLE: + title = [[NSString alloc] initWithUTF8String: + Tcl_GetString(objv[i + 1])]; + break; + case SAVE_TYPEVARIABLE: + typeVariablePtr = objv[i + 1]; + break; + case SAVE_COMMAND: + cmdObj = objv[i+1]; + break; + case SAVE_CONFIRMOW: + if (Tcl_GetBooleanFromObj(interp, objv[i + 1], + &confirmOverwrite) != TCL_OK) { + goto end; + } + break; + } + } + + if (title) { + [savepanel setTitle:title]; + if (message) { + NSString *fullmessage = [[NSString alloc] initWithFormat:@"%@\n%@",title,message]; [message release]; - break; - case SAVE_PARENT: - str = Tcl_GetStringFromObj(objv[i + 1], &len); - tkwin = Tk_NameToWindow(interp, str, tkwin); - if (!tkwin) { - goto end; - } - haveParentOption = 1; - break; - case SAVE_TITLE: - title = [[NSString alloc] initWithUTF8String: - Tcl_GetString(objv[i + 1])]; - [savepanel setTitle:title]; [title release]; - break; - case SAVE_TYPEVARIABLE: - break; - case SAVE_COMMAND: - cmdObj = objv[i+1]; - break; - case SAVE_CONFIRMOW: - if (Tcl_GetBooleanFromObj(interp, objv[i + 1], - &confirmOverwrite) != TCL_OK) { - goto end; - } - break; + message = fullmessage; + } else { + message = title; } } - if (fl.filters || defaultType) { - saveFileTypes = [NSMutableArray array]; - for (FileFilter *filterPtr = fl.filters; filterPtr; - filterPtr = filterPtr->next) { - for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr; - clausePtr = clausePtr->next) { - for (GlobPattern *globPtr = clausePtr->patterns; globPtr; - globPtr = globPtr->next) { - str = globPtr->pattern; - while (*str && (*str == '*' || *str == '.')) { - str++; - } - if (*str) { - type = [[NSString alloc] initWithUTF8String:str]; - if (![saveFileTypes containsObject:type]) { - [saveFileTypes addObject:type]; - } - [type release]; - } - } - } - } - - - NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)]; - NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)]; - [label setEditable:NO]; - [label setStringValue:@"Enable:"]; - [label setBordered:NO]; - [label setBezeled:NO]; - [label setDrawsBackground:NO]; - NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) pullsDown:NO]; - [popupButton addItemsWithTitles:saveFileTypes]; - [popupButton setAction:@selector(saveFormat:)]; + if (message) { + [savepanel setMessage:message]; + [message release]; + } - [accessoryView addSubview:label]; - [accessoryView addSubview:popupButton]; - [savepanel setAllowedFileTypes:saveFileTypes]; + if (parseFileFilters(interp, fileTypesPtr, typeVariablePtr) != TCL_OK) { + goto end; + } - [savepanel setAccessoryView:accessoryView]; - [savepanel setAllowsOtherFileTypes:YES]; + if (filterInfo.doFileTypes) { + NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)]; + NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)]; + [label setEditable:NO]; + [label setStringValue:NSLocalizedString(@"Format:", nil)]; + [label setBordered:NO]; + [label setBezeled:NO]; + [label setDrawsBackground:NO]; + + NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) pullsDown:NO]; + [popupButton addItemsWithTitles:filterInfo.fileTypeLabels]; + [popupButton selectItemAtIndex:filterInfo.fileTypeIndex]; + [popupButton setAction:@selector(saveFormat:)]; + + [accessoryView addSubview:label]; + [accessoryView addSubview:popupButton]; + + [savepanel setAccessoryView:accessoryView]; + + [savepanel setAllowedFileTypes:filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex]]; + [savepanel setAllowsOtherFileTypes:NO]; + } else if (defaultType) { + /* If no filetypes are given, defaultextension is an alternative way + * to specify the attached extension. Just propose this extension, + * but don't display an accessory view */ + NSMutableArray *AllowedFileTypes = [NSMutableArray array]; + [AllowedFileTypes addObject:defaultType]; + [savepanel setAllowedFileTypes:AllowedFileTypes]; + [savepanel setAllowsOtherFileTypes:YES]; } + [savepanel setCanSelectHiddenExtension:YES]; [savepanel setExtensionHidden:NO]; + if (cmdObj) { callbackInfo = ckalloc(sizeof(FilePanelCallbackInfo)); if (Tcl_IsShared(cmdObj)) { @@ -779,6 +892,7 @@ Tk_GetSaveFileObjCmd( callbackInfo->cmdObj = cmdObj; callbackInfo->interp = interp; callbackInfo->multiple = 0; + parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window); if (haveParentOption && parent && ![parent attachedSheet]) { parentIsKey = [parent isKeyWindow]; @@ -805,6 +919,9 @@ Tk_GetSaveFileObjCmd( #else [savepanel setDirectoryURL:getFileURL(directory, filename)]; modalReturnCode = [savepanel runModal]; + #if 0 + NSLog(@"modal: %li", modalReturnCode); + #endif #endif [NSApp tkFilePanelDidEnd:savepanel returnCode:modalReturnCode contextInfo:callbackInfo]; @@ -813,8 +930,21 @@ Tk_GetSaveFileObjCmd( if (parentIsKey) { [parent makeKeyWindow]; } + + if ((typeVariablePtr && (modalReturnCode == NSOKButton)) && filterInfo.doFileTypes) { + /* + * The -typevariable must be set to the selected file type, if the dialog was not cancelled + */ + #if 0 + NSLog(@"result: %i modal: %li", result, (long)modalReturnCode); + #endif + NSString * selectedFilter = filterInfo.fileTypeNames[filterInfo.fileTypeIndex]; + Tcl_ObjSetVar2(interp, typeVariablePtr, NULL, + Tcl_NewStringObj([selectedFilter UTF8String], -1), TCL_GLOBAL_ONLY); + } + + end: - TkFreeFileFilters(&fl); return result; } -- cgit v0.12 From bb089fa3ae014082fd1642a5c932f8c0c7422924 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 15 May 2017 14:56:05 +0000 Subject: Another attempt to fix [434d294df8b053246ee86e7898d06bc3a6d1d771|434d294df8], this time (hopefully) suitable for 8.6. (less changes than the original attempt) --- generic/tkCanvPs.c | 2 +- generic/tkFont.c | 36 +++++++++++++++++++----------------- generic/tkFont.h | 6 +++--- macosx/tkMacOSXFont.c | 2 +- unix/tkUnixFont.c | 4 ++-- unix/tkUnixRFont.c | 21 ++++++++++++--------- win/tkWinDialog.c | 2 +- win/tkWinFont.c | 2 +- 8 files changed, 40 insertions(+), 35 deletions(-) diff --git a/generic/tkCanvPs.c b/generic/tkCanvPs.c index c6470dd..2bfdcc5 100644 --- a/generic/tkCanvPs.c +++ b/generic/tkCanvPs.c @@ -825,7 +825,7 @@ Tk_PostscriptFont( fontname = Tcl_DStringValue(&ds); Tcl_AppendPrintfToObj(GetPostscriptBuffer(interp), "/%s findfont %d scalefont%s setfont\n", - fontname, TkFontGetPoints(psInfoPtr->tkwin, points), + fontname, (int)(TkFontGetPoints(psInfoPtr->tkwin, points) + 0.5), strncasecmp(fontname, "Symbol", 7) ? " ISOEncode" : ""); Tcl_CreateHashEntry(&psInfoPtr->fontTable, Tcl_DStringValue(&ds), &i); Tcl_DStringFree(&ds); diff --git a/generic/tkFont.c b/generic/tkFont.c index bec8807..9a70a65 100644 --- a/generic/tkFont.c +++ b/generic/tkFont.c @@ -1228,7 +1228,7 @@ Tk_AllocFontFromObj( descent = fontPtr->fm.descent; fontPtr->underlinePos = descent / 2; - fontPtr->underlineHeight = TkFontGetPixels(tkwin, fontPtr->fa.size) / 10; + fontPtr->underlineHeight = (int) (TkFontGetPixels(tkwin, fontPtr->fa.size) / 10 + 0.5); if (fontPtr->underlineHeight == 0) { fontPtr->underlineHeight = 1; } @@ -3375,6 +3375,7 @@ ConfigAttributesObj( int i, n, index; Tcl_Obj *optionPtr, *valuePtr; const char *value; + double d; for (i = 0; i < objc; i += 2) { optionPtr = objv[i]; @@ -3406,10 +3407,10 @@ ConfigAttributesObj( faPtr->family = Tk_GetUid(value); break; case FONT_SIZE: - if (Tcl_GetIntFromObj(interp, valuePtr, &n) != TCL_OK) { + if (Tcl_GetDoubleFromObj(interp, valuePtr, &d) != TCL_OK) { return TCL_ERROR; } - faPtr->size = n; + faPtr->size = d; break; case FONT_WEIGHT: n = TkFindStateNumObj(interp, optionPtr, weightMap, valuePtr); @@ -3500,7 +3501,7 @@ GetAttributeInfoObj( break; case FONT_SIZE: - valuePtr = Tcl_NewIntObj(faPtr->size); + valuePtr = Tcl_NewDoubleObj(faPtr->size); break; case FONT_WEIGHT: @@ -3646,10 +3647,11 @@ ParseFontNameObj( faPtr->family = Tk_GetUid(Tcl_GetString(objv[0])); if (objc > 1) { - if (Tcl_GetIntFromObj(interp, objv[1], &n) != TCL_OK) { + double d; + if (Tcl_GetDoubleFromObj(interp, objv[1], &d) != TCL_OK) { return TCL_ERROR; } - faPtr->size = n; + faPtr->size = d; } i = 2; @@ -3893,7 +3895,7 @@ TkFontParseXLFD( * historical compatibility. */ - faPtr->size = 12; + faPtr->size = 12.0; if (FieldSpecified(field[XLFD_POINT_SIZE])) { if (field[XLFD_POINT_SIZE][0] == '[') { @@ -3907,8 +3909,8 @@ TkFontParseXLFD( * the purpose of, so I ignore them. */ - faPtr->size = atoi(field[XLFD_POINT_SIZE] + 1); - } else if (Tcl_GetInt(NULL, field[XLFD_POINT_SIZE], + faPtr->size = atof(field[XLFD_POINT_SIZE] + 1); + } else if (Tcl_GetDouble(NULL, field[XLFD_POINT_SIZE], &faPtr->size) == TCL_OK) { faPtr->size /= 10; } else { @@ -3932,8 +3934,8 @@ TkFontParseXLFD( * ignore them. */ - faPtr->size = atoi(field[XLFD_PIXEL_SIZE] + 1); - } else if (Tcl_GetInt(NULL, field[XLFD_PIXEL_SIZE], + faPtr->size = atof(field[XLFD_PIXEL_SIZE] + 1); + } else if (Tcl_GetDouble(NULL, field[XLFD_PIXEL_SIZE], &faPtr->size) != TCL_OK) { return TCL_ERROR; } @@ -4010,10 +4012,10 @@ FieldSpecified( *--------------------------------------------------------------------------- */ -int +double TkFontGetPixels( Tk_Window tkwin, /* For point->pixel conversion factor. */ - int size) /* Font size. */ + double size) /* Font size. */ { double d; @@ -4024,7 +4026,7 @@ TkFontGetPixels( d = size * 25.4 / 72.0; d *= WidthOfScreen(Tk_Screen(tkwin)); d /= WidthMMOfScreen(Tk_Screen(tkwin)); - return (int) (d + 0.5); + return d; } /* @@ -4044,10 +4046,10 @@ TkFontGetPixels( *--------------------------------------------------------------------------- */ -int +double TkFontGetPoints( Tk_Window tkwin, /* For pixel->point conversion factor. */ - int size) /* Font size. */ + double size) /* Font size. */ { double d; @@ -4058,7 +4060,7 @@ TkFontGetPoints( d = -size * 72.0 / 25.4; d *= WidthMMOfScreen(Tk_Screen(tkwin)); d /= WidthOfScreen(Tk_Screen(tkwin)); - return (int) (d + 0.5); + return d; } /* diff --git a/generic/tkFont.h b/generic/tkFont.h index b8de885..de479bf 100644 --- a/generic/tkFont.h +++ b/generic/tkFont.h @@ -23,7 +23,7 @@ struct TkFontAttributes { Tk_Uid family; /* Font family, or NULL to represent plaform- * specific default system font. */ - int size; /* Pointsize of font, 0 for default size, or + double size; /* Pointsize of font, 0.0 for default size, or * negative number meaning pixel size. */ int weight; /* Weight flag; see below for def'n. */ int slant; /* Slant flag; see below for def'n. */ @@ -198,8 +198,8 @@ MODULE_SCOPE int TkFontParseXLFD(const char *string, TkFontAttributes *faPtr, TkXLFDAttributes *xaPtr); MODULE_SCOPE const char *const * TkFontGetAliasList(const char *faceName); MODULE_SCOPE const char *const *const * TkFontGetFallbacks(void); -MODULE_SCOPE int TkFontGetPixels(Tk_Window tkwin, int size); -MODULE_SCOPE int TkFontGetPoints(Tk_Window tkwin, int size); +MODULE_SCOPE double TkFontGetPixels(Tk_Window tkwin, double size); +MODULE_SCOPE double TkFontGetPoints(Tk_Window tkwin, double size); MODULE_SCOPE const char *const * TkFontGetGlobalClass(void); MODULE_SCOPE const char *const * TkFontGetSymbolClass(void); MODULE_SCOPE int TkCreateNamedFont(Tcl_Interp *interp, Tk_Window tkwin, diff --git a/macosx/tkMacOSXFont.c b/macosx/tkMacOSXFont.c index b5ae1a3..fd4c19a 100644 --- a/macosx/tkMacOSXFont.c +++ b/macosx/tkMacOSXFont.c @@ -515,7 +515,7 @@ TkpGetFontFromAttributes( /* Set of attributes to match. */ { MacFont *fontPtr; - int points = TkFontGetPoints(tkwin, faPtr->size); + int points = (int)(TkFontGetPoints(tkwin, faPtr->size) + 0.5); NSFontTraitMask traits = GetNSFontTraitsFromTkFontAttributes(faPtr); NSInteger weight = (faPtr->weight == TK_FW_BOLD ? 9 : 5); NSFont *nsFont; diff --git a/unix/tkUnixFont.c b/unix/tkUnixFont.c index 0c663a3..a447ec7 100644 --- a/unix/tkUnixFont.c +++ b/unix/tkUnixFont.c @@ -1642,7 +1642,7 @@ InitFont( fmPtr->fixed = fixed; fontPtr->display = display; - fontPtr->pixelSize = TkFontGetPixels(tkwin, fa.fa.size); + fontPtr->pixelSize = (int)(TkFontGetPixels(tkwin, fa.fa.size) + 0.5); fontPtr->xa = fa.xa; fontPtr->numSubFonts = 1; @@ -2773,7 +2773,7 @@ GetScreenFont( } *str = '\0'; sprintf(buf, "%.200s-%d-*-*-*-*-*%s", nameList[bestIdx[1]], - -wantPtr->fa.size, rest); + (int)(-wantPtr->fa.size-0.5), rest); *str = '-'; fontStructPtr = XLoadQueryFont(display, buf); bestScore[1] = INT_MAX; diff --git a/unix/tkUnixRFont.c b/unix/tkUnixRFont.c index 41cd096..b818a70 100644 --- a/unix/tkUnixRFont.c +++ b/unix/tkUnixRFont.c @@ -170,18 +170,21 @@ GetTkFontAttributes( { const char *family = "Unknown"; const char *const *familyPtr = &family; - int weight, slant, size, pxsize; - double ptsize; + int weight, slant, pxsize; + double size, ptsize; (void) XftPatternGetString(ftFont->pattern, XFT_FAMILY, 0, familyPtr); if (XftPatternGetDouble(ftFont->pattern, XFT_SIZE, 0, &ptsize) == XftResultMatch) { - size = (int) ptsize; + size = ptsize; + } else if (XftPatternGetDouble(ftFont->pattern, XFT_PIXEL_SIZE, 0, + &ptsize) == XftResultMatch) { + size = -ptsize; } else if (XftPatternGetInteger(ftFont->pattern, XFT_PIXEL_SIZE, 0, &pxsize) == XftResultMatch) { size = -pxsize; } else { - size = 12; + size = 12.0; } if (XftPatternGetInteger(ftFont->pattern, XFT_WEIGHT, 0, &weight) != XftResultMatch) { @@ -194,7 +197,7 @@ GetTkFontAttributes( #if DEBUG_FONTSEL printf("family %s size %d weight %d slant %d\n", - family, size, weight, slant); + family, (int)size, weight, slant); #endif /* DEBUG_FONTSEL */ faPtr->family = Tk_GetUid(family); @@ -441,10 +444,10 @@ TkpGetFontFromAttributes( if (faPtr->family) { XftPatternAddString(pattern, XFT_FAMILY, faPtr->family); } - if (faPtr->size > 0) { - XftPatternAddDouble(pattern, XFT_SIZE, (double)faPtr->size); - } else if (faPtr->size < 0) { - XftPatternAddInteger(pattern, XFT_PIXEL_SIZE, -faPtr->size); + if (faPtr->size > 0.0) { + XftPatternAddDouble(pattern, XFT_SIZE, faPtr->size); + } else if (faPtr->size < 0.0) { + XftPatternAddDouble(pattern, XFT_PIXEL_SIZE, -faPtr->size); } else { XftPatternAddDouble(pattern, XFT_SIZE, 12.0); } diff --git a/win/tkWinDialog.c b/win/tkWinDialog.c index 635b9a3..62400bb 100644 --- a/win/tkWinDialog.c +++ b/win/tkWinDialog.c @@ -3487,7 +3487,7 @@ FontchooserShowCmd( LF_FACESIZE-1); Tcl_DStringFree(&ds); lf.lfFaceName[LF_FACESIZE-1] = 0; - lf.lfHeight = -MulDiv(TkFontGetPoints(tkwin, fontPtr->fa.size), + lf.lfHeight = -MulDiv((int)(TkFontGetPoints(tkwin, fontPtr->fa.size) + 0.5), GetDeviceCaps(hdc, LOGPIXELSY), 72); if (fontPtr->fa.weight == TK_FW_BOLD) { lf.lfWeight = FW_BOLD; diff --git a/win/tkWinFont.c b/win/tkWinFont.c index f342f7c..b7b0bec 100644 --- a/win/tkWinFont.c +++ b/win/tkWinFont.c @@ -562,7 +562,7 @@ TkpGetFontFromAttributes( ReleaseDC(hwnd, hdc); hFont = GetScreenFont(faPtr, faceName, - TkFontGetPixels(tkwin, faPtr->size), 0.0); + (int)(TkFontGetPixels(tkwin, faPtr->size) + 0.5), 0.0); if (tkFontPtr == NULL) { fontPtr = ckalloc(sizeof(WinFont)); } else { -- cgit v0.12 From 5f231b902eba1495a094fc95da03a5edcf470d1c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 18 May 2017 09:18:42 +0000 Subject: Cherry-pick [http://core.tcl.tk/tclconfig/info/18e79736d236d15d|All the world was a VAX] for OpenBSD. Also fix [84a27b1c67]: Tcl and Tk's tcl.m4 not synced? (configure script not re-generated yet, I'm sure Don will do that in the rc branch) --- macosx/tkMacOSXDialog.c | 50 ++++++++++++++++++++++++------------------------- unix/tcl.m4 | 45 +++++++++++--------------------------------- 2 files changed, 36 insertions(+), 59 deletions(-) diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index 2670b32..027a8e4 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.c @@ -6,7 +6,7 @@ * Copyright (c) 1996-1997 Sun Microsystems, Inc. * Copyright 2001-2009, Apple Inc. * Copyright (c) 2006-2009 Daniel A. Steffen - * Copyright (c) 2017 Christian Gollwitzer. + * Copyright (c) 2017 Christian Gollwitzer. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. @@ -34,7 +34,7 @@ typedef struct { NSMutableArray *fileTypeExtensions; // array of allowed extensions per name, e.g. "txt", "doc" NSMutableArray *fileTypeLabels; // displayed string, e.g. "Text document (.txt, .doc)" NSMutableArray *allAllowedExtensions; // set of all allowed extensions - NSInteger fileTypeIndex; // index of currently selected filter + NSInteger fileTypeIndex; // index of currently selected filter } filepanelFilterInfo; filepanelFilterInfo filterInfo; @@ -413,7 +413,7 @@ int parseFileFilters(Tcl_Interp *interp, Tcl_Obj *fileTypesPtr, Tcl_Obj *typeVar } filterInfo.doFileTypes = (fl.filters != NULL); - + filterInfo.fileTypeIndex = 0; filterInfo.fileTypeExtensions = [NSMutableArray array]; filterInfo.fileTypeNames = [NSMutableArray array]; @@ -442,7 +442,7 @@ int parseFileFilters(Tcl_Interp *interp, Tcl_Obj *fileTypesPtr, Tcl_Obj *typeVar if (![filterInfo.allAllowedExtensions containsObject:extension]) { [filterInfo.allAllowedExtensions addObject:extension]; } - + [clauseextensions addObject:extension]; [displayextensions addObject:[@"." stringByAppendingString:extension]]; @@ -458,7 +458,7 @@ int parseFileFilters(Tcl_Interp *interp, Tcl_Obj *fileTypesPtr, Tcl_Obj *typeVar [label appendString:@")"]; [filterInfo.fileTypeLabels addObject:label]; [label release]; - + } /* Check if the typevariable exists and matches one of the names */ @@ -467,21 +467,21 @@ int parseFileFilters(Tcl_Interp *interp, Tcl_Obj *fileTypesPtr, Tcl_Obj *typeVar if (typeVariablePtr) { /* extract the variable content as a NSString */ Tcl_Obj *selectedFileTypeObj = Tcl_ObjGetVar2(interp, typeVariablePtr, NULL, TCL_GLOBAL_ONLY); - + /* check that the typevariable exists */ - if (selectedFileTypeObj != NULL) { + if (selectedFileTypeObj != NULL) { const char *selectedFileType = Tcl_GetString(selectedFileTypeObj); NSString *selectedFileTypeStr = [[NSString alloc] initWithUTF8String:selectedFileType]; NSUInteger index = [filterInfo.fileTypeNames indexOfObject:selectedFileTypeStr]; - + if (index != NSNotFound) { filterInfo.fileTypeIndex = index; filterInfo.preselectFilter = true; } } - } + } - } + } TkFreeFileFilters(&fl); return TCL_OK; @@ -587,9 +587,9 @@ Tk_GetOpenFileObjCmd( break; } } - - /* From OSX 10.11, the title string is silently ignored. - * Prepend the title to the message + + /* From OSX 10.11, the title string is silently ignored. + * Prepend the title to the message * NOTE should be conditional on OSX version, but * -mmacosx-version-min does not revert this behaviour*/ if (title) { @@ -610,7 +610,7 @@ Tk_GetOpenFileObjCmd( } [openpanel setAllowsMultipleSelection:multiple]; - + if (parseFileFilters(interp, fileTypesPtr, typeVariablePtr) != TCL_OK) { goto end; } @@ -630,19 +630,19 @@ Tk_GetOpenFileObjCmd( [accessoryView addSubview:label]; [accessoryView addSubview:popupButton]; - + if (filterInfo.preselectFilter) { - /* A specific filter was selected from the typevariable. Select it and + /* A specific filter was selected from the typevariable. Select it and * open the accessory view */ [popupButton selectItemAtIndex:filterInfo.fileTypeIndex]; - /* on OSX > 10.11, the optons are not visible by default. Ergo allow all file types + /* on OSX > 10.11, the optons are not visible by default. Ergo allow all file types [openpanel setAllowedFileTypes:filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex]]; */ [openpanel setAllowedFileTypes:filterInfo.allAllowedExtensions]; } else { [openpanel setAllowedFileTypes:filterInfo.allAllowedExtensions]; } - + [openpanel setAllowsOtherFileTypes:NO]; [openpanel setAccessoryView:accessoryView]; @@ -658,7 +658,7 @@ Tk_GetOpenFileObjCmd( } Tcl_IncrRefCount(cmdObj); } - + callbackInfo->cmdObj = cmdObj; callbackInfo->interp = interp; callbackInfo->multiple = multiple; @@ -698,8 +698,8 @@ Tk_GetOpenFileObjCmd( if (parentIsKey) { [parent makeKeyWindow]; } - - if ((typeVariablePtr && (modalReturnCode == NSOKButton)) && + + if ((typeVariablePtr && (modalReturnCode == NSOKButton)) && filterInfo.doFileTypes && filterInfo.userHasSelectedFilter) { /* * The -typevariable must be set to the selected file type, if the dialog was not cancelled @@ -712,7 +712,7 @@ Tk_GetOpenFileObjCmd( Tcl_NewStringObj([selectedFilter UTF8String], -1), TCL_GLOBAL_ONLY); } - + end: return result; } @@ -826,7 +826,7 @@ Tk_GetSaveFileObjCmd( break; } } - + if (title) { [savepanel setTitle:title]; if (message) { @@ -866,7 +866,7 @@ Tk_GetSaveFileObjCmd( [accessoryView addSubview:popupButton]; [savepanel setAccessoryView:accessoryView]; - + [savepanel setAllowedFileTypes:filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex]]; [savepanel setAllowsOtherFileTypes:NO]; } else if (defaultType) { @@ -930,7 +930,7 @@ Tk_GetSaveFileObjCmd( if (parentIsKey) { [parent makeKeyWindow]; } - + if ((typeVariablePtr && (modalReturnCode == NSOKButton)) && filterInfo.doFileTypes) { /* * The -typevariable must be set to the selected file type, if the dialog was not cancelled diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 41b94ef..fc488e4 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -1467,44 +1467,21 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ OpenBSD-*) arch=`arch -s` case "$arch" in - vax) - # Equivalent using configure option --disable-load - # Step 4 will set the necessary variables - DL_OBJS="" - SHLIB_LD_LIBS="" - LDFLAGS="" + alpha|sparc64) + SHLIB_CFLAGS="-fPIC" ;; *) - case "$arch" in - alpha|sparc|sparc64) - SHLIB_CFLAGS="-fPIC" - ;; - *) - SHLIB_CFLAGS="-fpic" - ;; - esac - SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' - SHLIB_SUFFIX=".so" - DL_OBJS="tclLoadDl.o" - DL_LIBS="" - AS_IF([test $doRpath = yes], [ - CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) - LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' - LDFLAGS="-Wl,-export-dynamic" - ;; - esac - case "$arch" in - vax) - CFLAGS_OPTIMIZE="-O1" - ;; - sh) - CFLAGS_OPTIMIZE="-O0" - ;; - *) - CFLAGS_OPTIMIZE="-O2" + SHLIB_CFLAGS="-fpic" ;; esac + SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' + SHLIB_SUFFIX=".so" + AS_IF([test $doRpath = yes], [ + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' + LDFLAGS="-Wl,-export-dynamic" + CFLAGS_OPTIMIZE="-O2" AS_IF([test "${TCL_THREADS}" = "1"], [ # On OpenBSD: Compile with -pthread # Don't link with -lpthread -- cgit v0.12 From 6409149a9a89dbed7c247ed2b0e7e4317277da4a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 18 May 2017 11:11:55 +0000 Subject: minor gcc warning (const usage) --- win/tkWinDialog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/tkWinDialog.c b/win/tkWinDialog.c index 635b9a3..f9a7cfd 100644 --- a/win/tkWinDialog.c +++ b/win/tkWinDialog.c @@ -2808,7 +2808,7 @@ Tk_MessageBoxObjCmd( ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Tcl_DString titleBuf, tmpBuf; - WCHAR *titlePtr, *tmpPtr; + const WCHAR *titlePtr, *tmpPtr; const char *src; defaultBtn = -1; -- cgit v0.12 From 107e2400ee9876bbfd0b4712307f642290498194 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 18 May 2017 12:18:12 +0000 Subject: autoconf-2.59 --- unix/configure | 49 +++++++++++++------------------------------------ 1 file changed, 13 insertions(+), 36 deletions(-) diff --git a/unix/configure b/unix/configure index 565f915..442004d 100755 --- a/unix/configure +++ b/unix/configure @@ -5355,47 +5355,24 @@ fi OpenBSD-*) arch=`arch -s` case "$arch" in - vax) - # Equivalent using configure option --disable-load - # Step 4 will set the necessary variables - DL_OBJS="" - SHLIB_LD_LIBS="" - LDFLAGS="" + alpha|sparc64) + SHLIB_CFLAGS="-fPIC" ;; *) - case "$arch" in - alpha|sparc|sparc64) - SHLIB_CFLAGS="-fPIC" - ;; - *) - SHLIB_CFLAGS="-fpic" - ;; - esac - SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' - SHLIB_SUFFIX=".so" - DL_OBJS="tclLoadDl.o" - DL_LIBS="" - if test $doRpath = yes; then + SHLIB_CFLAGS="-fpic" + ;; + esac + SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' + SHLIB_SUFFIX=".so" + if test $doRpath = yes; then - CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' fi - LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' - LDFLAGS="-Wl,-export-dynamic" - ;; - esac - case "$arch" in - vax) - CFLAGS_OPTIMIZE="-O1" - ;; - sh) - CFLAGS_OPTIMIZE="-O0" - ;; - *) - CFLAGS_OPTIMIZE="-O2" - ;; - esac + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' + LDFLAGS="-Wl,-export-dynamic" + CFLAGS_OPTIMIZE="-O2" if test "${TCL_THREADS}" = "1"; then # On OpenBSD: Compile with -pthread -- cgit v0.12 From 93222e57379094d593fc30ffd12f32099789a060 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 19 May 2017 13:33:54 +0000 Subject: Eliminate empty if() statement, if DEBUG_LAYOUT_WITH_BASE_CHUNKS is not defined. (backported from androwish. Thanks, Christian!) --- generic/tkTextDisp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c index 371e910..9c2f536 100644 --- a/generic/tkTextDisp.c +++ b/generic/tkTextDisp.c @@ -8981,13 +8981,13 @@ RemoveFromBaseChunk( bciPtr = baseCharChunkPtr->clientData; +#ifdef DEBUG_LAYOUT_WITH_BASE_CHUNKS if ((ciPtr->baseOffset + ciPtr->numBytes) != Tcl_DStringLength(&bciPtr->baseChars)) { -#ifdef DEBUG_LAYOUT_WITH_BASE_CHUNKS fprintf(stderr,"RemoveFromBaseChunk called with wrong chunk " "(not last)\n"); -#endif } +#endif Tcl_DStringSetLength(&bciPtr->baseChars, ciPtr->baseOffset); -- cgit v0.12 From 5a0b86d31c2dbb1480e1692c7be6ac6944e27633 Mon Sep 17 00:00:00 2001 From: stu Date: Sat, 20 May 2017 12:49:55 +0000 Subject: Fix build on OpenBSD. [3439d04a] missed a couple of bits. Tcl/Tk's tcl.m4 isn't identical to TEA's tcl.m4 - be careful! --- unix/configure | 4 +++- unix/tcl.m4 | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/unix/configure b/unix/configure index a02e8c4..cf04ea2 100755 --- a/unix/configure +++ b/unix/configure @@ -5367,12 +5367,14 @@ fi esac SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="" if test $doRpath = yes; then : CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' fi LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' LDFLAGS="-Wl,-export-dynamic" CFLAGS_OPTIMIZE="-O2" if test "${TCL_THREADS}" = "1"; then : diff --git a/unix/tcl.m4 b/unix/tcl.m4 index a69715d..559d8f3 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -1476,10 +1476,12 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ esac SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' LDFLAGS="-Wl,-export-dynamic" CFLAGS_OPTIMIZE="-O2" AS_IF([test "${TCL_THREADS}" = "1"], [ -- cgit v0.12 From 090dff7eae2a557c2293d61f6a6dd7fce5da00c7 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sat, 20 May 2017 18:51:18 +0000 Subject: Bug-fix [434d294df] continuation: fix logic error detected by Christian Werner. Thanks! --- generic/tkFont.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tkFont.c b/generic/tkFont.c index 2e2a5b9..a4e47b1 100644 --- a/generic/tkFont.c +++ b/generic/tkFont.c @@ -3938,7 +3938,7 @@ TkFontParseXLFD( faPtr->size = atof(field[XLFD_PIXEL_SIZE] + 1); } else if (Tcl_GetInt(NULL, field[XLFD_PIXEL_SIZE], - &i) != TCL_OK) { + &i) == TCL_OK) { faPtr->size = (double)i; return TCL_ERROR; } -- cgit v0.12 From c474dae757819195f58b98303f5ceb73eba231f0 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sat, 20 May 2017 19:11:23 +0000 Subject: .... missing else ... in previous commit --- generic/tkFont.c | 1 + 1 file changed, 1 insertion(+) diff --git a/generic/tkFont.c b/generic/tkFont.c index a4e47b1..4183686 100644 --- a/generic/tkFont.c +++ b/generic/tkFont.c @@ -3940,6 +3940,7 @@ TkFontParseXLFD( } else if (Tcl_GetInt(NULL, field[XLFD_PIXEL_SIZE], &i) == TCL_OK) { faPtr->size = (double)i; + } else { return TCL_ERROR; } } -- cgit v0.12 From 867adb4c9850d67520f5bc9120a055efe7328318 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 21 May 2017 17:47:16 +0000 Subject: Cherrypick Fix build on OpenBSD. [82701b94c4] missed a couple of bits. Tcl/Tk's tcl.m4 isn't identical to TEA's tcl.m4 - be careful! --- unix/configure | 4 +++- unix/tcl.m4 | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/unix/configure b/unix/configure index 442004d..6300b1b 100755 --- a/unix/configure +++ b/unix/configure @@ -5364,13 +5364,15 @@ fi esac SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="" if test $doRpath = yes; then CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' fi LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' LDFLAGS="-Wl,-export-dynamic" CFLAGS_OPTIMIZE="-O2" if test "${TCL_THREADS}" = "1"; then diff --git a/unix/tcl.m4 b/unix/tcl.m4 index fc488e4..26b2a4a 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -1476,10 +1476,12 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ esac SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' LDFLAGS="-Wl,-export-dynamic" CFLAGS_OPTIMIZE="-O2" AS_IF([test "${TCL_THREADS}" = "1"], [ @@ -2683,7 +2685,7 @@ AC_DEFUN([SC_TCL_CFG_ENCODING], [ # advancedTest - the advanced test to run if the function is present # # Results: -# Might cause compatability versions of the function to be used. +# Might cause compatibility versions of the function to be used. # Might affect the following vars: # USE_COMPAT (implicit) # -- cgit v0.12 From b8bd50957127f5889bdae3f560c27549662de478 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 22 May 2017 09:54:01 +0000 Subject: Sync tcl.m4 with the version in Tcl's core-8-6-branch --- unix/configure | 13 ++++++++----- unix/tcl.m4 | 13 ++++++------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/unix/configure b/unix/configure index 6300b1b..d29cf7f 100755 --- a/unix/configure +++ b/unix/configure @@ -1429,8 +1429,9 @@ echo "$as_me: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" > for i in `ls -d ${libdir} 2>/dev/null` \ `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ - `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ + `ls -d /usr/local/lib 2>/dev/null` \ + `ls -d /usr/pkg/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ `ls -d /usr/lib64 2>/dev/null` \ ; do @@ -4489,8 +4490,10 @@ fi PLAT_OBJS="" PLAT_SRCS="" LDAIX_SRC="" - if test x"${SHLIB_VERSION}" = x; then - SHLIB_VERSION="1.0" + if test "x${SHLIB_VERSION}" = x; then + SHLIB_VERSION=".1.0" +else + SHLIB_VERSION=".${SHLIB_VERSION}" fi case $system in @@ -5372,7 +5375,7 @@ fi fi LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' LDFLAGS="-Wl,-export-dynamic" CFLAGS_OPTIMIZE="-O2" if test "${TCL_THREADS}" = "1"; then @@ -6113,7 +6116,7 @@ fi # requires an extra version number at the end of .so file names. # So, the library has to have a name like libtcl75.so.1.0 - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 26b2a4a..8a802fb 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -91,8 +91,9 @@ AC_DEFUN([SC_PATH_TCLCONFIG], [ for i in `ls -d ${libdir} 2>/dev/null` \ `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ - `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ + `ls -d /usr/local/lib 2>/dev/null` \ + `ls -d /usr/pkg/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ `ls -d /usr/lib64 2>/dev/null` \ ; do @@ -611,7 +612,6 @@ AC_DEFUN([SC_ENABLE_FRAMEWORK], [ # TCL_THREADS # _REENTRANT # _THREAD_SAFE -# #------------------------------------------------------------------------ AC_DEFUN([SC_ENABLE_THREADS], [ @@ -727,7 +727,6 @@ AC_DEFUN([SC_ENABLE_THREADS], [ # Sets to $(LDFLAGS_OPTIMIZE) if false # DBGX Formerly used as debug library extension; # always blank now. -# #------------------------------------------------------------------------ AC_DEFUN([SC_ENABLE_SYMBOLS], [ @@ -977,7 +976,7 @@ AC_DEFUN([SC_CONFIG_SYSTEM], [ # SHLIB_LD_LIBS - Dependent libraries for the linker to scan when # creating shared libraries. This symbol typically # goes at the end of the "ld" commands that build -# shared libraries. The value of the symbol is +# shared libraries. The value of the symbol defaults to # "${LIBS}" if all of the dependent libraries should # be specified when creating a shared library. If # dependent libraries should not be specified (as on @@ -1107,7 +1106,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ PLAT_OBJS="" PLAT_SRCS="" LDAIX_SRC="" - AS_IF([test x"${SHLIB_VERSION}" = x], [SHLIB_VERSION="1.0"]) + AS_IF([test "x${SHLIB_VERSION}" = x],[SHLIB_VERSION=".1.0"],[SHLIB_VERSION=".${SHLIB_VERSION}"]) case $system in AIX-*) AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [ @@ -1481,7 +1480,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' LDFLAGS="-Wl,-export-dynamic" CFLAGS_OPTIMIZE="-O2" AS_IF([test "${TCL_THREADS}" = "1"], [ @@ -1804,7 +1803,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ # requires an extra version number at the end of .so file names. # So, the library has to have a name like libtcl75.so.1.0 - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; -- cgit v0.12 From ce84448c05bb61135f0cebd1a812f3e4496f62bd Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 23 May 2017 10:45:34 +0000 Subject: Fix test-case font-44.1: It looks like XftPatternAddDouble(... XFT_PIXEL_SIZE ..) doesn't take scaling into account, so we have to do our own scaling. --- unix/tkUnixRFont.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unix/tkUnixRFont.c b/unix/tkUnixRFont.c index a08b95f..cce59a8 100644 --- a/unix/tkUnixRFont.c +++ b/unix/tkUnixRFont.c @@ -447,7 +447,7 @@ TkpGetFontFromAttributes( if (faPtr->size > 0.0) { XftPatternAddDouble(pattern, XFT_SIZE, faPtr->size); } else if (faPtr->size < 0.0) { - XftPatternAddDouble(pattern, XFT_PIXEL_SIZE, -faPtr->size); + XftPatternAddDouble(pattern, XFT_SIZE, TkFontGetPoints(tkwin, faPtr->size)); } else { XftPatternAddDouble(pattern, XFT_SIZE, 12.0); } -- cgit v0.12 From b94f5639e0d02222c409549af8dc464260afbfe6 Mon Sep 17 00:00:00 2001 From: Kevin Walzer Date: Mon, 29 May 2017 16:48:34 +0000 Subject: Fix for 5f44d4f5 in building Tk on macOS 10.6; thanks to Mojca Miklavec for patch --- macosx/tkMacOSXXStubs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/macosx/tkMacOSXXStubs.c b/macosx/tkMacOSXXStubs.c index 8d9820b..1c2d908 100644 --- a/macosx/tkMacOSXXStubs.c +++ b/macosx/tkMacOSXXStubs.c @@ -890,16 +890,18 @@ XGetImage( int bitmap_pad = 0; int bytes_per_row = 4*width; int size; - MacDrawable *macDraw = (MacDrawable *) d; + MacDrawable *macDraw = (MacDrawable *) d; // Where is this variable used? May it be removed? + int scalefactor = 1; +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 NSWindow *win = TkMacOSXDrawableWindow(d); /* This code assumes that backing scale factors are integers. Currently * Retina displays use a scale factor of 2.0 and normal displays use 1.0. * We do not support any other values here. */ - int scalefactor = 1; if (win && [win respondsToSelector:@selector(backingScaleFactor)]) { scalefactor = ([win backingScaleFactor] == 2.0) ? 2 : 1; } +#endif int scaled_height = height * scalefactor; int scaled_width = width * scalefactor; -- cgit v0.12 From 25d536cfb12de418f7be438d72122defb588aa18 Mon Sep 17 00:00:00 2001 From: Kevin Walzer Date: Mon, 29 May 2017 16:50:02 +0000 Subject: Fix for 5f44d4f5 in building Tk on macOS 10.6; thanks to Mojca Miklavec for patch --- macosx/tkMacOSXXStubs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/macosx/tkMacOSXXStubs.c b/macosx/tkMacOSXXStubs.c index 2251b8f..004ac1b 100644 --- a/macosx/tkMacOSXXStubs.c +++ b/macosx/tkMacOSXXStubs.c @@ -882,16 +882,18 @@ XGetImage( int bitmap_pad = 0; int bytes_per_row = 4*width; int size; - MacDrawable *macDraw = (MacDrawable *) d; + MacDrawable *macDraw = (MacDrawable *) d; // Where is this variable used? May it be removed? + int scalefactor = 1; +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 NSWindow *win = TkMacOSXDrawableWindow(d); /* This code assumes that backing scale factors are integers. Currently * Retina displays use a scale factor of 2.0 and normal displays use 1.0. * We do not support any other values here. */ - int scalefactor = 1; if (win && [win respondsToSelector:@selector(backingScaleFactor)]) { scalefactor = ([win backingScaleFactor] == 2.0) ? 2 : 1; } +#endif int scaled_height = height * scalefactor; int scaled_width = width * scalefactor; -- cgit v0.12 From 3b021463acb2e61f69f34968c211035dbc66eb56 Mon Sep 17 00:00:00 2001 From: stu Date: Wed, 31 May 2017 12:27:25 +0000 Subject: Sync with Tcl. --- unix/configure | 103 ++--------------------------------------------------- unix/tcl.m4 | 109 ++++----------------------------------------------------- 2 files changed, 9 insertions(+), 203 deletions(-) diff --git a/unix/configure b/unix/configure index 98a1cc7..ba3104d 100755 --- a/unix/configure +++ b/unix/configure @@ -4501,8 +4501,8 @@ if ${tcl_cv_sys_version+:} false; then : $as_echo_n "(cached) " >&6 else - if test -f /usr/lib/NextStep/software_version; then - tcl_cv_sys_version=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version` + if test "${TEA_PLATFORM}" = "windows" ; then + tcl_cv_sys_version=windows else tcl_cv_sys_version=`uname -s`-`uname -r` if test "$?" -ne 0 ; then @@ -4510,12 +4510,6 @@ else $as_echo "$as_me: WARNING: can't find uname command" >&2;} tcl_cv_sys_version=unknown else - # Special check for weird MP-RAS system (uname returns weird - # results, and the version is kept in special file). - - if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then - tcl_cv_sys_version=MP-RAS-`awk '{print $3}' /etc/.relid` - fi if test "`uname -s`" = "AIX" ; then tcl_cv_sys_version=AIX-`uname -v`.`uname -r` fi @@ -4702,9 +4696,7 @@ fi PLAT_SRCS="" LDAIX_SRC="" if test "x${SHLIB_VERSION}" = x; then : - SHLIB_VERSION=".1.0" -else - SHLIB_VERSION=".${SHLIB_VERSION}" + SHLIB_VERSION="1.0" fi case $system in AIX-*) @@ -5337,27 +5329,6 @@ fi LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' fi ;; - MP-RAS-02*) - SHLIB_CFLAGS="-K PIC" - SHLIB_LD='${CC} -G' - SHLIB_LD_LIBS="" - SHLIB_SUFFIX=".so" - DL_OBJS="tclLoadDl.o" - DL_LIBS="-ldl" - CC_SEARCH_FLAGS="" - LD_SEARCH_FLAGS="" - ;; - MP-RAS-*) - SHLIB_CFLAGS="-K PIC" - SHLIB_LD='${CC} -G' - SHLIB_LD_LIBS="" - SHLIB_SUFFIX=".so" - DL_OBJS="tclLoadDl.o" - DL_LIBS="-ldl" - LDFLAGS="$LDFLAGS -Wl,-Bexport" - CC_SEARCH_FLAGS="" - LD_SEARCH_FLAGS="" - ;; OpenBSD-*) arch=`arch -s` case "$arch" in @@ -5762,16 +5733,6 @@ fi fi ;; - NEXTSTEP-*) - SHLIB_CFLAGS="" - SHLIB_LD='${CC} -nostdlib -r' - SHLIB_LD_LIBS="" - SHLIB_SUFFIX=".so" - DL_OBJS="tclLoadNext.o" - DL_LIBS="" - CC_SEARCH_FLAGS="" - LD_SEARCH_FLAGS="" - ;; OS/390-*) SHLIB_LD_LIBS="" CFLAGS_OPTIMIZE="" # Optimizer is buggy @@ -5779,35 +5740,6 @@ fi $as_echo "#define _OE_SOCKETS 1" >>confdefs.h ;; - OSF1-1.0|OSF1-1.1|OSF1-1.2) - # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1 - SHLIB_CFLAGS="" - # Hack: make package name same as library name - SHLIB_LD='ld -R -export :' - SHLIB_LD_LIBS="" - SHLIB_SUFFIX=".so" - DL_OBJS="tclLoadOSF.o" - DL_LIBS="" - CC_SEARCH_FLAGS="" - LD_SEARCH_FLAGS="" - ;; - OSF1-1.*) - # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2 - SHLIB_CFLAGS="-fPIC" - if test "$SHARED_BUILD" = 1; then : - SHLIB_LD="ld -shared" -else - - SHLIB_LD="ld -non_shared" - -fi - SHLIB_LD_LIBS="" - SHLIB_SUFFIX=".so" - DL_OBJS="tclLoadDl.o" - DL_LIBS="" - CC_SEARCH_FLAGS="" - LD_SEARCH_FLAGS="" - ;; OSF1-V*) # Digital OSF/1 SHLIB_CFLAGS="" @@ -5889,35 +5821,6 @@ fi CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; - SINIX*5.4*) - SHLIB_CFLAGS="-K PIC" - SHLIB_LD='${CC} -G' - SHLIB_LD_LIBS="" - SHLIB_SUFFIX=".so" - DL_OBJS="tclLoadDl.o" - DL_LIBS="-ldl" - CC_SEARCH_FLAGS="" - LD_SEARCH_FLAGS="" - ;; - SunOS-4*) - SHLIB_CFLAGS="-PIC" - SHLIB_LD="ld" - SHLIB_LD_LIBS="" - SHLIB_SUFFIX=".so" - DL_OBJS="tclLoadDl.o" - DL_LIBS="-ldl" - CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' - LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - - # SunOS can't handle version numbers with dots in them in library - # specs, like -ltcl7.5, so use -ltcl75 instead. Also, it - # requires an extra version number at the end of .so file names. - # So, the library has to have a name like libtcl75.so.1.0 - - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' - UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' - TCL_LIB_VERSIONS_OK=nodots - ;; SunOS-5.[0-6]) # Careful to not let 5.10+ fall into this case diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 01f95e0..45922e0 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -891,8 +891,7 @@ AC_DEFUN([SC_CONFIG_MANPAGES], [ # # Determine what the system is (some things cannot be easily checked # on a feature-driven basis, alas). This can usually be done via the -# "uname" command, but there are a few systems, like Next, where -# this doesn't work. +# "uname" command. # # Arguments: # none @@ -901,25 +900,18 @@ AC_DEFUN([SC_CONFIG_MANPAGES], [ # Defines the following var: # # system - System/platform/version identification code. -# #-------------------------------------------------------------------- AC_DEFUN([SC_CONFIG_SYSTEM], [ AC_CACHE_CHECK([system version], tcl_cv_sys_version, [ - if test -f /usr/lib/NextStep/software_version; then - tcl_cv_sys_version=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version` + if test "${TEA_PLATFORM}" = "windows" ; then + tcl_cv_sys_version=windows else tcl_cv_sys_version=`uname -s`-`uname -r` if test "$?" -ne 0 ; then AC_MSG_WARN([can't find uname command]) tcl_cv_sys_version=unknown else - # Special check for weird MP-RAS system (uname returns weird - # results, and the version is kept in special file). - - if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then - tcl_cv_sys_version=MP-RAS-`awk '{print $[3]}' /etc/.relid` - fi if test "`uname -s`" = "AIX" ; then tcl_cv_sys_version=AIX-`uname -v`.`uname -r` fi @@ -979,8 +971,8 @@ AC_DEFUN([SC_CONFIG_SYSTEM], [ # shared libraries. The value of the symbol defaults to # "${LIBS}" if all of the dependent libraries should # be specified when creating a shared library. If -# dependent libraries should not be specified (as on -# SunOS 4.x, where they cause the link to fail, or in +# dependent libraries should not be specified (as on some +# SunOS systems, where they cause the link to fail, or in # general if Tcl and Tk aren't themselves shared # libraries), then this symbol has an empty string # as its value. @@ -1106,7 +1098,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ PLAT_OBJS="" PLAT_SRCS="" LDAIX_SRC="" - AS_IF([test "x${SHLIB_VERSION}" = x],[SHLIB_VERSION=".1.0"],[SHLIB_VERSION=".${SHLIB_VERSION}"]) + AS_IF([test "x${SHLIB_VERSION}" = x], [SHLIB_VERSION="1.0"]) case $system in AIX-*) AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [ @@ -1442,27 +1434,6 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) ;; - MP-RAS-02*) - SHLIB_CFLAGS="-K PIC" - SHLIB_LD='${CC} -G' - SHLIB_LD_LIBS="" - SHLIB_SUFFIX=".so" - DL_OBJS="tclLoadDl.o" - DL_LIBS="-ldl" - CC_SEARCH_FLAGS="" - LD_SEARCH_FLAGS="" - ;; - MP-RAS-*) - SHLIB_CFLAGS="-K PIC" - SHLIB_LD='${CC} -G' - SHLIB_LD_LIBS="" - SHLIB_SUFFIX=".so" - DL_OBJS="tclLoadDl.o" - DL_LIBS="-ldl" - LDFLAGS="$LDFLAGS -Wl,-Bexport" - CC_SEARCH_FLAGS="" - LD_SEARCH_FLAGS="" - ;; OpenBSD-*) arch=`arch -s` case "$arch" in @@ -1676,47 +1647,12 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ ]) ]) ;; - NEXTSTEP-*) - SHLIB_CFLAGS="" - SHLIB_LD='${CC} -nostdlib -r' - SHLIB_LD_LIBS="" - SHLIB_SUFFIX=".so" - DL_OBJS="tclLoadNext.o" - DL_LIBS="" - CC_SEARCH_FLAGS="" - LD_SEARCH_FLAGS="" - ;; OS/390-*) SHLIB_LD_LIBS="" CFLAGS_OPTIMIZE="" # Optimizer is buggy AC_DEFINE(_OE_SOCKETS, 1, # needed in sys/socket.h [Should OS/390 do the right thing with sockets?]) ;; - OSF1-1.0|OSF1-1.1|OSF1-1.2) - # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1 - SHLIB_CFLAGS="" - # Hack: make package name same as library name - SHLIB_LD='ld -R -export $@:' - SHLIB_LD_LIBS="" - SHLIB_SUFFIX=".so" - DL_OBJS="tclLoadOSF.o" - DL_LIBS="" - CC_SEARCH_FLAGS="" - LD_SEARCH_FLAGS="" - ;; - OSF1-1.*) - # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2 - SHLIB_CFLAGS="-fPIC" - AS_IF([test "$SHARED_BUILD" = 1], [SHLIB_LD="ld -shared"], [ - SHLIB_LD="ld -non_shared" - ]) - SHLIB_LD_LIBS="" - SHLIB_SUFFIX=".so" - DL_OBJS="tclLoadDl.o" - DL_LIBS="" - CC_SEARCH_FLAGS="" - LD_SEARCH_FLAGS="" - ;; OSF1-V*) # Digital OSF/1 SHLIB_CFLAGS="" @@ -1778,35 +1714,6 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; - SINIX*5.4*) - SHLIB_CFLAGS="-K PIC" - SHLIB_LD='${CC} -G' - SHLIB_LD_LIBS="" - SHLIB_SUFFIX=".so" - DL_OBJS="tclLoadDl.o" - DL_LIBS="-ldl" - CC_SEARCH_FLAGS="" - LD_SEARCH_FLAGS="" - ;; - SunOS-4*) - SHLIB_CFLAGS="-PIC" - SHLIB_LD="ld" - SHLIB_LD_LIBS="" - SHLIB_SUFFIX=".so" - DL_OBJS="tclLoadDl.o" - DL_LIBS="-ldl" - CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' - LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - - # SunOS can't handle version numbers with dots in them in library - # specs, like -ltcl7.5, so use -ltcl75 instead. Also, it - # requires an extra version number at the end of .so file names. - # So, the library has to have a name like libtcl75.so.1.0 - - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' - UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' - TCL_LIB_VERSIONS_OK=nodots - ;; SunOS-5.[[0-6]]) # Careful to not let 5.10+ fall into this case @@ -2315,10 +2222,6 @@ AC_DEFUN([SC_BLOCKING_STYLE], [ AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?]) AC_MSG_RESULT([FIONBIO]) ;; - SunOS-4*) - AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?]) - AC_MSG_RESULT([FIONBIO]) - ;; *) AC_MSG_RESULT([O_NONBLOCK]) ;; -- cgit v0.12 From fba5250f5a416261bcf0a772189ac7cf2eaabd20 Mon Sep 17 00:00:00 2001 From: fvogel Date: Wed, 31 May 2017 20:17:29 +0000 Subject: Fix [bc43fd20cf]: paneconfigure not working as expected --- generic/tkPanedWindow.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/generic/tkPanedWindow.c b/generic/tkPanedWindow.c index f350d0a..17e2b4a 100644 --- a/generic/tkPanedWindow.c +++ b/generic/tkPanedWindow.c @@ -1789,10 +1789,18 @@ ArrangePanes( */ if (horizontal) { - paneSize = slavePtr->paneWidth; + if (slavePtr->width > 0) { + paneSize = slavePtr->width; + } else { + paneSize = slavePtr->paneWidth; + } stretchReserve -= paneSize + (2 * slavePtr->padx); } else { - paneSize = slavePtr->paneHeight; + if (slavePtr->height > 0) { + paneSize = slavePtr->height; + } else { + paneSize = slavePtr->paneHeight; + } stretchReserve -= paneSize + (2 * slavePtr->pady); } if (IsStretchable(slavePtr->stretch,i,first,last) @@ -1842,10 +1850,18 @@ ArrangePanes( */ if (horizontal) { - paneSize = slavePtr->paneWidth; + if (slavePtr->width > 0) { + paneSize = slavePtr->width; + } else { + paneSize = slavePtr->paneWidth; + } pwSize = pwWidth; } else { - paneSize = slavePtr->paneHeight; + if (slavePtr->height > 0) { + paneSize = slavePtr->height; + } else { + paneSize = slavePtr->paneHeight; + } pwSize = pwHeight; } if (IsStretchable(slavePtr->stretch, i, first, last)) { -- cgit v0.12 From 6e4eb0606125762a717666ff72b145b0fc6d04a5 Mon Sep 17 00:00:00 2001 From: Kevin Walzer Date: Mon, 5 Jun 2017 01:52:53 +0000 Subject: Fix for 9eab541213, tk_getSave on macOS; thanks to Christian Gollwitzer for patch --- macosx/tkMacOSXDialog.c | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index 027a8e4..3397f71 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.c @@ -159,22 +159,6 @@ static const short alertNativeButtonIndexAndTypeToButtonIndex[][3] = { [TYPE_YESNOCANCEL] = {5, 6, 4}, }; -/* - * Construct a file URL from directory and filename. Either may - * be nil. If both are nil, returns nil. - */ -#if MAC_OS_X_VERSION_MIN_REQUIRED > 1050 -static NSURL *getFileURL(NSString *directory, NSString *filename) { - NSURL *url = nil; - if (directory) { - url = [NSURL fileURLWithPath:directory]; - } - if (filename) { - url = [NSURL URLWithString:filename relativeToURL:url]; - } - return url; -} -#endif #pragma mark TKApplication(TKDialog) @@ -675,7 +659,10 @@ Tk_GetOpenFileObjCmd( @selector(tkFilePanelDidEnd:returnCode:contextInfo:) contextInfo:callbackInfo]; #else - [openpanel setDirectoryURL:getFileURL(directory, filename)]; + if (directory) { + [openpanel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]]; + } + [openpanel setNameFieldStringValue:filename]; [openpanel beginSheetModalForWindow:parent completionHandler:^(NSInteger returnCode) { [NSApp tkFilePanelDidEnd:openpanel @@ -688,7 +675,10 @@ Tk_GetOpenFileObjCmd( modalReturnCode = [openpanel runModalForDirectory:directory file:filename]; #else - [openpanel setDirectoryURL:getFileURL(directory, filename)]; + if (directory) { + [openpanel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]]; + } + [openpanel setNameFieldStringValue:filename]; modalReturnCode = [openpanel runModal]; #endif [NSApp tkFilePanelDidEnd:openpanel returnCode:modalReturnCode @@ -905,7 +895,10 @@ Tk_GetSaveFileObjCmd( @selector(tkFilePanelDidEnd:returnCode:contextInfo:) contextInfo:callbackInfo]; #else - [savepanel setDirectoryURL:getFileURL(directory, filename)]; + if (directory) { + [savepanel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]]; + } + [savepanel setNameFieldStringValue:filename]; [savepanel beginSheetModalForWindow:parent completionHandler:^(NSInteger returnCode) { [NSApp tkFilePanelDidEnd:savepanel @@ -917,7 +910,10 @@ Tk_GetSaveFileObjCmd( #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 modalReturnCode = [savepanel runModalForDirectory:directory file:filename]; #else - [savepanel setDirectoryURL:getFileURL(directory, filename)]; + if (directory) { + [savepanel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]]; + } + [savepanel setNameFieldStringValue:filename]; modalReturnCode = [savepanel runModal]; #if 0 NSLog(@"modal: %li", modalReturnCode); @@ -980,7 +976,7 @@ Tk_ChooseDirectoryObjCmd( Tcl_Obj *cmdObj = NULL; FilePanelCallbackInfo callbackInfoStruct; FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct; - NSString *directory = nil, *filename = nil; + NSString *directory = nil; NSString *message, *title; NSWindow *parent; NSOpenPanel *panel = [NSOpenPanel openPanel]; @@ -1056,13 +1052,13 @@ Tk_ChooseDirectoryObjCmd( parentIsKey = [parent isKeyWindow]; #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 [panel beginSheetForDirectory:directory - file:filename + file:nil modalForWindow:parent modalDelegate:NSApp didEndSelector: @selector(tkFilePanelDidEnd:returnCode:contextInfo:) contextInfo:callbackInfo]; #else - [panel setDirectoryURL:getFileURL(directory, filename)]; + [panel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]]; [panel beginSheetModalForWindow:parent completionHandler:^(NSInteger returnCode) { [NSApp tkFilePanelDidEnd:panel @@ -1074,7 +1070,7 @@ Tk_ChooseDirectoryObjCmd( #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 modalReturnCode = [panel runModalForDirectory:directory file:nil]; #else - [panel setDirectoryURL:getFileURL(directory, filename)]; + [panel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]]; modalReturnCode = [panel runModal]; #endif [NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode -- cgit v0.12 From 3a718d1ca9c3c454928087f0167397af4d121c2e Mon Sep 17 00:00:00 2001 From: Kevin Walzer Date: Mon, 5 Jun 2017 01:54:53 +0000 Subject: Fix for 9eab541213, tk_getSave on macOS; thanks to Christian Gollwitzer for patch --- macosx/tkMacOSXDialog.c | 94 +++++++++++++++++++++++-------------------------- 1 file changed, 45 insertions(+), 49 deletions(-) diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index 2670b32..3397f71 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.c @@ -6,7 +6,7 @@ * Copyright (c) 1996-1997 Sun Microsystems, Inc. * Copyright 2001-2009, Apple Inc. * Copyright (c) 2006-2009 Daniel A. Steffen - * Copyright (c) 2017 Christian Gollwitzer. + * Copyright (c) 2017 Christian Gollwitzer. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. @@ -34,7 +34,7 @@ typedef struct { NSMutableArray *fileTypeExtensions; // array of allowed extensions per name, e.g. "txt", "doc" NSMutableArray *fileTypeLabels; // displayed string, e.g. "Text document (.txt, .doc)" NSMutableArray *allAllowedExtensions; // set of all allowed extensions - NSInteger fileTypeIndex; // index of currently selected filter + NSInteger fileTypeIndex; // index of currently selected filter } filepanelFilterInfo; filepanelFilterInfo filterInfo; @@ -159,22 +159,6 @@ static const short alertNativeButtonIndexAndTypeToButtonIndex[][3] = { [TYPE_YESNOCANCEL] = {5, 6, 4}, }; -/* - * Construct a file URL from directory and filename. Either may - * be nil. If both are nil, returns nil. - */ -#if MAC_OS_X_VERSION_MIN_REQUIRED > 1050 -static NSURL *getFileURL(NSString *directory, NSString *filename) { - NSURL *url = nil; - if (directory) { - url = [NSURL fileURLWithPath:directory]; - } - if (filename) { - url = [NSURL URLWithString:filename relativeToURL:url]; - } - return url; -} -#endif #pragma mark TKApplication(TKDialog) @@ -413,7 +397,7 @@ int parseFileFilters(Tcl_Interp *interp, Tcl_Obj *fileTypesPtr, Tcl_Obj *typeVar } filterInfo.doFileTypes = (fl.filters != NULL); - + filterInfo.fileTypeIndex = 0; filterInfo.fileTypeExtensions = [NSMutableArray array]; filterInfo.fileTypeNames = [NSMutableArray array]; @@ -442,7 +426,7 @@ int parseFileFilters(Tcl_Interp *interp, Tcl_Obj *fileTypesPtr, Tcl_Obj *typeVar if (![filterInfo.allAllowedExtensions containsObject:extension]) { [filterInfo.allAllowedExtensions addObject:extension]; } - + [clauseextensions addObject:extension]; [displayextensions addObject:[@"." stringByAppendingString:extension]]; @@ -458,7 +442,7 @@ int parseFileFilters(Tcl_Interp *interp, Tcl_Obj *fileTypesPtr, Tcl_Obj *typeVar [label appendString:@")"]; [filterInfo.fileTypeLabels addObject:label]; [label release]; - + } /* Check if the typevariable exists and matches one of the names */ @@ -467,21 +451,21 @@ int parseFileFilters(Tcl_Interp *interp, Tcl_Obj *fileTypesPtr, Tcl_Obj *typeVar if (typeVariablePtr) { /* extract the variable content as a NSString */ Tcl_Obj *selectedFileTypeObj = Tcl_ObjGetVar2(interp, typeVariablePtr, NULL, TCL_GLOBAL_ONLY); - + /* check that the typevariable exists */ - if (selectedFileTypeObj != NULL) { + if (selectedFileTypeObj != NULL) { const char *selectedFileType = Tcl_GetString(selectedFileTypeObj); NSString *selectedFileTypeStr = [[NSString alloc] initWithUTF8String:selectedFileType]; NSUInteger index = [filterInfo.fileTypeNames indexOfObject:selectedFileTypeStr]; - + if (index != NSNotFound) { filterInfo.fileTypeIndex = index; filterInfo.preselectFilter = true; } } - } + } - } + } TkFreeFileFilters(&fl); return TCL_OK; @@ -587,9 +571,9 @@ Tk_GetOpenFileObjCmd( break; } } - - /* From OSX 10.11, the title string is silently ignored. - * Prepend the title to the message + + /* From OSX 10.11, the title string is silently ignored. + * Prepend the title to the message * NOTE should be conditional on OSX version, but * -mmacosx-version-min does not revert this behaviour*/ if (title) { @@ -610,7 +594,7 @@ Tk_GetOpenFileObjCmd( } [openpanel setAllowsMultipleSelection:multiple]; - + if (parseFileFilters(interp, fileTypesPtr, typeVariablePtr) != TCL_OK) { goto end; } @@ -630,19 +614,19 @@ Tk_GetOpenFileObjCmd( [accessoryView addSubview:label]; [accessoryView addSubview:popupButton]; - + if (filterInfo.preselectFilter) { - /* A specific filter was selected from the typevariable. Select it and + /* A specific filter was selected from the typevariable. Select it and * open the accessory view */ [popupButton selectItemAtIndex:filterInfo.fileTypeIndex]; - /* on OSX > 10.11, the optons are not visible by default. Ergo allow all file types + /* on OSX > 10.11, the optons are not visible by default. Ergo allow all file types [openpanel setAllowedFileTypes:filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex]]; */ [openpanel setAllowedFileTypes:filterInfo.allAllowedExtensions]; } else { [openpanel setAllowedFileTypes:filterInfo.allAllowedExtensions]; } - + [openpanel setAllowsOtherFileTypes:NO]; [openpanel setAccessoryView:accessoryView]; @@ -658,7 +642,7 @@ Tk_GetOpenFileObjCmd( } Tcl_IncrRefCount(cmdObj); } - + callbackInfo->cmdObj = cmdObj; callbackInfo->interp = interp; callbackInfo->multiple = multiple; @@ -675,7 +659,10 @@ Tk_GetOpenFileObjCmd( @selector(tkFilePanelDidEnd:returnCode:contextInfo:) contextInfo:callbackInfo]; #else - [openpanel setDirectoryURL:getFileURL(directory, filename)]; + if (directory) { + [openpanel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]]; + } + [openpanel setNameFieldStringValue:filename]; [openpanel beginSheetModalForWindow:parent completionHandler:^(NSInteger returnCode) { [NSApp tkFilePanelDidEnd:openpanel @@ -688,7 +675,10 @@ Tk_GetOpenFileObjCmd( modalReturnCode = [openpanel runModalForDirectory:directory file:filename]; #else - [openpanel setDirectoryURL:getFileURL(directory, filename)]; + if (directory) { + [openpanel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]]; + } + [openpanel setNameFieldStringValue:filename]; modalReturnCode = [openpanel runModal]; #endif [NSApp tkFilePanelDidEnd:openpanel returnCode:modalReturnCode @@ -698,8 +688,8 @@ Tk_GetOpenFileObjCmd( if (parentIsKey) { [parent makeKeyWindow]; } - - if ((typeVariablePtr && (modalReturnCode == NSOKButton)) && + + if ((typeVariablePtr && (modalReturnCode == NSOKButton)) && filterInfo.doFileTypes && filterInfo.userHasSelectedFilter) { /* * The -typevariable must be set to the selected file type, if the dialog was not cancelled @@ -712,7 +702,7 @@ Tk_GetOpenFileObjCmd( Tcl_NewStringObj([selectedFilter UTF8String], -1), TCL_GLOBAL_ONLY); } - + end: return result; } @@ -826,7 +816,7 @@ Tk_GetSaveFileObjCmd( break; } } - + if (title) { [savepanel setTitle:title]; if (message) { @@ -866,7 +856,7 @@ Tk_GetSaveFileObjCmd( [accessoryView addSubview:popupButton]; [savepanel setAccessoryView:accessoryView]; - + [savepanel setAllowedFileTypes:filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex]]; [savepanel setAllowsOtherFileTypes:NO]; } else if (defaultType) { @@ -905,7 +895,10 @@ Tk_GetSaveFileObjCmd( @selector(tkFilePanelDidEnd:returnCode:contextInfo:) contextInfo:callbackInfo]; #else - [savepanel setDirectoryURL:getFileURL(directory, filename)]; + if (directory) { + [savepanel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]]; + } + [savepanel setNameFieldStringValue:filename]; [savepanel beginSheetModalForWindow:parent completionHandler:^(NSInteger returnCode) { [NSApp tkFilePanelDidEnd:savepanel @@ -917,7 +910,10 @@ Tk_GetSaveFileObjCmd( #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 modalReturnCode = [savepanel runModalForDirectory:directory file:filename]; #else - [savepanel setDirectoryURL:getFileURL(directory, filename)]; + if (directory) { + [savepanel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]]; + } + [savepanel setNameFieldStringValue:filename]; modalReturnCode = [savepanel runModal]; #if 0 NSLog(@"modal: %li", modalReturnCode); @@ -930,7 +926,7 @@ Tk_GetSaveFileObjCmd( if (parentIsKey) { [parent makeKeyWindow]; } - + if ((typeVariablePtr && (modalReturnCode == NSOKButton)) && filterInfo.doFileTypes) { /* * The -typevariable must be set to the selected file type, if the dialog was not cancelled @@ -980,7 +976,7 @@ Tk_ChooseDirectoryObjCmd( Tcl_Obj *cmdObj = NULL; FilePanelCallbackInfo callbackInfoStruct; FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct; - NSString *directory = nil, *filename = nil; + NSString *directory = nil; NSString *message, *title; NSWindow *parent; NSOpenPanel *panel = [NSOpenPanel openPanel]; @@ -1056,13 +1052,13 @@ Tk_ChooseDirectoryObjCmd( parentIsKey = [parent isKeyWindow]; #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 [panel beginSheetForDirectory:directory - file:filename + file:nil modalForWindow:parent modalDelegate:NSApp didEndSelector: @selector(tkFilePanelDidEnd:returnCode:contextInfo:) contextInfo:callbackInfo]; #else - [panel setDirectoryURL:getFileURL(directory, filename)]; + [panel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]]; [panel beginSheetModalForWindow:parent completionHandler:^(NSInteger returnCode) { [NSApp tkFilePanelDidEnd:panel @@ -1074,7 +1070,7 @@ Tk_ChooseDirectoryObjCmd( #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 modalReturnCode = [panel runModalForDirectory:directory file:nil]; #else - [panel setDirectoryURL:getFileURL(directory, filename)]; + [panel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]]; modalReturnCode = [panel runModal]; #endif [NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode -- cgit v0.12