diff options
author | dgp <dgp@users.sourceforge.net> | 2017-05-04 21:00:46 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2017-05-04 21:00:46 (GMT) |
commit | 1d8d022bbb6e739c99c55a2473ce5ada2cf61192 (patch) | |
tree | 60c6c287be59024d228447552dd8b9621002c3ca | |
parent | edacef3820f2d32f25d7a7b3139d02f0a579e325 (diff) | |
parent | 30e203aa908d2974306755ad15d3e93e95a9aee2 (diff) | |
download | tk-1d8d022bbb6e739c99c55a2473ce5ada2cf61192.zip tk-1d8d022bbb6e739c99c55a2473ce5ada2cf61192.tar.gz tk-1d8d022bbb6e739c99c55a2473ce5ada2cf61192.tar.bz2 |
merge 8.6
-rw-r--r-- | changes | 2 | ||||
-rw-r--r-- | doc/FindPhoto.3 | 57 | ||||
-rw-r--r-- | generic/tkImgPhInstance.c | 2 | ||||
-rw-r--r-- | generic/tkImgPhoto.c | 166 | ||||
-rw-r--r-- | generic/ttk/ttkNotebook.c | 9 | ||||
-rw-r--r-- | macosx/tkMacOSXDialog.c | 80 | ||||
-rw-r--r-- | macosx/tkMacOSXScrlbr.c | 4 | ||||
-rw-r--r-- | tests/imgBmap.test | 3 | ||||
-rw-r--r-- | tests/imgPhoto.test | 117 | ||||
-rw-r--r-- | xlib/xcolors.c | 4 | ||||
-rw-r--r-- | xlib/xgc.c | 2 |
11 files changed, 327 insertions, 119 deletions
@@ -7314,6 +7314,7 @@ Tk Cocoa 2.0: More drawing internals refinements (culler,walzer) --- Released 8.6.6, July 27, 2016 --- http://core.tcl.tk/tk/ for details +2016-08-23 (bug)[a2abc4] Wrong warp cursor position on 2nd display (vogel) @@ -7322,7 +7323,6 @@ Tk Cocoa 2.0: More drawing internals refinements (culler,walzer) -2016-08-23 (bug)[a2abc4] Wrong warp cursor position on 2nd display (vogel) diff --git a/doc/FindPhoto.3 b/doc/FindPhoto.3 index e4d83f0..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 @@ -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 @@ -184,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. @@ -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 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 +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, 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) { diff --git a/generic/tkImgPhoto.c b/generic/tkImgPhoto.c index 1bd0142..1fec208 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); + + if (memToFree) ckfree(memToFree); + return TCL_OK; + + errorExit: + if (memToFree) 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; @@ -3133,11 +3173,41 @@ Tk_PhotoPutZoomedBlock( 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); + + if (memToFree) ckfree(memToFree); + return TCL_OK; + + errorExit: + if (memToFree) ckfree(memToFree); + + return TCL_ERROR; } /* diff --git a/generic/ttk/ttkNotebook.c b/generic/ttk/ttkNotebook.c index 06aa275..83d7db9 100644 --- a/generic/ttk/ttkNotebook.c +++ b/generic/ttk/ttkNotebook.c @@ -4,7 +4,6 @@ #include <string.h> #include <ctype.h> -#include <math.h> #include <stdio.h> #include <tk.h> @@ -470,17 +469,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; } } } diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index 80a7a11..cd289d2 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: 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/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..86da23d 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 {<photo> 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 {<photo> 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 {} @@ -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 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); @@ -560,7 +560,7 @@ XDrawSegments( XSegment *segments, int nsegments) { - return Success; + return BadDrawable; } #endif |