summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorculler <culler@noemail.net>2017-11-08 17:43:14 (GMT)
committerculler <culler@noemail.net>2017-11-08 17:43:14 (GMT)
commit45aaf2f337ca35d0274658b4529a26ea67d42cb3 (patch)
treeba629df9ebb727b789b67ea49e19d29dbce481d1
parent0d631275c5fada0ab4369968366044b60f22c0c6 (diff)
downloadtk-45aaf2f337ca35d0274658b4529a26ea67d42cb3.zip
tk-45aaf2f337ca35d0274658b4529a26ea67d42cb3.tar.gz
tk-45aaf2f337ca35d0274658b4529a26ea67d42cb3.tar.bz2
Reorganization to put all code related to Ximages in the new
file tkMacOSXImage.c FossilOrigin-Name: 7915e840e2a7f008029cb9284c2fe4d2bd3117e8322795d624f409839eeb5fdc
-rw-r--r--macosx/tkMacOSXDraw.c187
-rw-r--r--macosx/tkMacOSXImage.c559
-rw-r--r--macosx/tkMacOSXPrivate.h8
-rw-r--r--macosx/tkMacOSXWm.c2
-rw-r--r--macosx/tkMacOSXXStubs.c396
-rw-r--r--unix/Makefile.in8
6 files changed, 586 insertions, 574 deletions
diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c
index 02ea812..274a2cd 100644
--- a/macosx/tkMacOSXDraw.c
+++ b/macosx/tkMacOSXDraw.c
@@ -16,7 +16,6 @@
#include "tkMacOSXPrivate.h"
#include "tkMacOSXDebug.h"
-#include "xbytes.h"
#include "tkButton.h"
/*
@@ -45,12 +44,6 @@ static int useThemedFrame = 0;
*/
static void ClipToGC(Drawable d, GC gc, HIShapeRef *clipRgnPtr);
-static CGImageRef CreateCGImageWithXImage(XImage *ximage);
-static CGContextRef GetCGContextForDrawable(Drawable d);
-static void DrawCGImage(Drawable d, GC gc, CGContextRef context, CGImageRef image,
- unsigned long imageForeground, unsigned long imageBackground,
- CGRect imageBounds, CGRect srcBounds, CGRect dstBounds);
-
/*
*----------------------------------------------------------------------
@@ -108,7 +101,7 @@ TkMacOSXInitCGDrawing(
/*
*----------------------------------------------------------------------
*
- * BitmapRepFromDrawableRect
+ * TkMacOSXBitmapRepFromDrawableRect
*
* Extract bitmap data from a MacOSX drawable as an NSBitmapImageRep.
*
@@ -126,7 +119,7 @@ TkMacOSXInitCGDrawing(
*----------------------------------------------------------------------
*/
NSBitmapImageRep*
-BitmapRepFromDrawableRect(
+TkMacOSXBitmapRepFromDrawableRect(
Drawable drawable,
int x,
int y,
@@ -143,7 +136,7 @@ BitmapRepFromDrawableRect(
This means that the MacDrawable is functioning as a Tk Pixmap, so its view
field is NULL.
*/
- cg_context = GetCGContextForDrawable(drawable);
+ cg_context = TkMacOSXGetCGContextForDrawable(drawable);
CGRect image_rect = CGRectMake(x, y, width, height);
cg_image = CGBitmapContextCreateImage( (CGContextRef) cg_context);
sub_cg_image = CGImageCreateWithImageInRect(cg_image, image_rect);
@@ -230,7 +223,7 @@ XCopyArea(
if (srcDraw->flags & TK_IS_PIXMAP) {
img = TkMacOSXCreateCGImageWithDrawable(src);
}else if (TkMacOSXDrawableWindow(src)) {
- bitmap_rep = BitmapRepFromDrawableRect(src, src_x, src_y, width, height);
+ bitmap_rep = TkMacOSXBitmapRepFromDrawableRect(src, src_x, src_y, width, height);
if ( bitmap_rep ) {
img = [bitmap_rep CGImage];
}
@@ -239,7 +232,7 @@ XCopyArea(
}
if (img) {
- DrawCGImage(dst, gc, dc.context, img, gc->foreground, gc->background,
+ TkMacOSXDrawCGImage(dst, gc, dc.context, img, gc->foreground, gc->background,
CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height),
CGRectMake(src_x, src_y, width, height),
CGRectMake(dest_x, dest_y, width, height));
@@ -339,7 +332,7 @@ XCopyPlane(
CGImageRelease(submask);
CGImageRelease(subimage);
} else {
- DrawCGImage(dst, gc, dc.context, img, gc->foreground, imageBackground,
+ TkMacOSXDrawCGImage(dst, gc, dc.context, img, gc->foreground, imageBackground,
CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height),
CGRectMake(src_x, src_y, width, height),
CGRectMake(dest_x, dest_y, width, height));
@@ -360,158 +353,6 @@ XCopyPlane(
/*
*----------------------------------------------------------------------
*
- * TkPutImage --
- *
- * Copies a subimage from an in-memory image to a rectangle of
- * of the specified drawable.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Draws the image on the specified drawable.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TkPutImage(
- unsigned long *colors, /* Unused on Macintosh. */
- int ncolors, /* Unused on Macintosh. */
- Display* display, /* Display. */
- Drawable d, /* Drawable to place image on. */
- GC gc, /* GC to use. */
- XImage* image, /* Image to place. */
- int src_x, /* Source X & Y. */
- int src_y,
- int dest_x, /* Destination X & Y. */
- int dest_y,
- unsigned int width, /* Same width & height for both */
- unsigned int height) /* distination and source. */
-{
- TkMacOSXDrawingContext dc;
-
- display->request++;
- if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
- return BadDrawable;
- }
- if (dc.context) {
- CGImageRef img = CreateCGImageWithXImage(image);
-
- if (img) {
- /* If the XImage has big pixels, rescale the source dimensions.*/
- int pp = image->pixelpower;
- DrawCGImage(d, gc, dc.context, img, gc->foreground, gc->background,
- CGRectMake(0, 0, image->width<<pp, image->height<<pp),
- CGRectMake(src_x<<pp, src_y<<pp, width<<pp, height<<pp),
- CGRectMake(dest_x, dest_y, width, height));
- CFRelease(img);
- } else {
- TkMacOSXDbgMsg("Invalid source drawable");
- }
- } else {
- TkMacOSXDbgMsg("Invalid destination drawable");
- }
- TkMacOSXRestoreDrawingContext(&dc);
- return Success;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * CreateCGImageWithXImage --
- *
- * Create CGImage from XImage, copying the image data.
- *
- * Results:
- * CGImage, release after use.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-static void ReleaseData(void *info, const void *data, size_t size) {
- ckfree(info);
-}
-
-CGImageRef
-CreateCGImageWithXImage(
- XImage *image)
-{
- CGImageRef img = NULL;
- size_t bitsPerComponent, bitsPerPixel;
- size_t len = image->bytes_per_line * image->height;
- const CGFloat *decode = NULL;
- CGBitmapInfo bitmapInfo;
- CGDataProviderRef provider = NULL;
- char *data = NULL;
- CGDataProviderReleaseDataCallback releaseData = ReleaseData;
-
- if (image->bits_per_pixel == 1) {
- /*
- * BW image
- */
-
- /* Reverses the sense of the bits */
- static const CGFloat decodeWB[2] = {1, 0};
- decode = decodeWB;
-
- bitsPerComponent = 1;
- bitsPerPixel = 1;
- if (image->bitmap_bit_order != MSBFirst) {
- char *srcPtr = image->data + image->xoffset;
- char *endPtr = srcPtr + len;
- char *destPtr = (data = ckalloc(len));
-
- while (srcPtr < endPtr) {
- *destPtr++ = xBitReverseTable[(unsigned char)(*(srcPtr++))];
- }
- } else {
- data = memcpy(ckalloc(len), image->data + image->xoffset, len);
- }
- if (data) {
- provider = CGDataProviderCreateWithData(data, data, len, releaseData);
- }
- if (provider) {
- img = CGImageMaskCreate(image->width, image->height, bitsPerComponent,
- bitsPerPixel, image->bytes_per_line, provider, decode, 0);
- }
- } else if (image->format == ZPixmap && image->bits_per_pixel == 32) {
- /*
- * Color image
- */
-
- CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
-
- bitsPerComponent = 8;
- bitsPerPixel = 32;
- bitmapInfo = (image->byte_order == MSBFirst ?
- kCGBitmapByteOrder32Big : kCGBitmapByteOrder32Little) |
- kCGImageAlphaNoneSkipFirst;
- data = memcpy(ckalloc(len), image->data + image->xoffset, len);
- if (data) {
- provider = CGDataProviderCreateWithData(data, data, len, releaseData);
- }
- if (provider) {
- img = CGImageCreate(image->width, image->height, bitsPerComponent,
- bitsPerPixel, image->bytes_per_line, colorspace, bitmapInfo,
- provider, decode, 0, kCGRenderingIntentDefault);
- CFRelease(provider);
- }
- if (colorspace) {
- CFRelease(colorspace);
- }
- } else {
- TkMacOSXDbgMsg("Unsupported image type");
- }
- return img;
-}
-
-/*
- *----------------------------------------------------------------------
- *
* TkMacOSXCreateCGImageWithDrawable --
*
* Create a CGImage from the given Drawable.
@@ -530,7 +371,7 @@ TkMacOSXCreateCGImageWithDrawable(
Drawable drawable)
{
CGImageRef img = NULL;
- CGContextRef context = GetCGContextForDrawable(drawable);
+ CGContextRef context = TkMacOSXGetCGContextForDrawable(drawable);
if (context) {
img = CGBitmapContextCreateImage(context);
@@ -649,7 +490,7 @@ TkMacOSXGetNSImageWithBitmap(
/*
*----------------------------------------------------------------------
*
- * GetCGContextForDrawable --
+ * TkMacOSXGetCGContextForDrawable --
*
* Get CGContext for given Drawable, creating one if necessary.
*
@@ -663,10 +504,10 @@ TkMacOSXGetNSImageWithBitmap(
*/
CGContextRef
-GetCGContextForDrawable(
- Drawable d)
+TkMacOSXGetCGContextForDrawable(
+ Drawable drawable)
{
- MacDrawable *macDraw = (MacDrawable *) d;
+ MacDrawable *macDraw = (MacDrawable *) drawable;
if (macDraw && (macDraw->flags & TK_IS_PIXMAP) && !macDraw->context) {
const size_t bitsPerComponent = 8;
@@ -711,7 +552,7 @@ GetCGContextForDrawable(
/*
*----------------------------------------------------------------------
*
- * DrawCGImage --
+ * TkMacOSXDrawCGImage --
*
* Draw CG image into drawable.
*
@@ -725,7 +566,7 @@ GetCGContextForDrawable(
*/
void
-DrawCGImage(
+TkMacOSXDrawCGImage(
Drawable d,
GC gc,
CGContextRef context,
@@ -1625,7 +1466,7 @@ TkMacOSXSetupDrawingContext(
goto end;
}
if (useCG) {
- dc.context = GetCGContextForDrawable(d);
+ dc.context = TkMacOSXGetCGContextForDrawable(d);
}
if (!dc.context || !(macDraw->flags & TK_IS_PIXMAP)) {
isWin = (TkMacOSXDrawableWindow(d) != nil);
diff --git a/macosx/tkMacOSXImage.c b/macosx/tkMacOSXImage.c
new file mode 100644
index 0000000..ac842f9
--- /dev/null
+++ b/macosx/tkMacOSXImage.c
@@ -0,0 +1,559 @@
+/*
+ * tkMacOSXImage.c --
+ *
+ * The code in this file provides an interface for XImages,
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright 2001-2009, Apple Inc.
+ * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
+ * Copyright 2017 Marc Culler.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tkMacOSXPrivate.h"
+#include "xbytes.h"
+
+#pragma mark XImage handling
+
+int
+_XInitImageFuncPtrs(
+ XImage *image)
+{
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXCreateCGImageWithXImage --
+ *
+ * Create CGImage from XImage, copying the image data.
+ *
+ * Results:
+ * CGImage, release after use.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void ReleaseData(void *info, const void *data, size_t size) {
+ ckfree(info);
+}
+
+CGImageRef
+TkMacOSXCreateCGImageWithXImage(
+ XImage *image)
+{
+ CGImageRef img = NULL;
+ size_t bitsPerComponent, bitsPerPixel;
+ size_t len = image->bytes_per_line * image->height;
+ const CGFloat *decode = NULL;
+ CGBitmapInfo bitmapInfo;
+ CGDataProviderRef provider = NULL;
+ char *data = NULL;
+ CGDataProviderReleaseDataCallback releaseData = ReleaseData;
+
+ if (image->bits_per_pixel == 1) {
+ /*
+ * BW image
+ */
+
+ /* Reverses the sense of the bits */
+ static const CGFloat decodeWB[2] = {1, 0};
+ decode = decodeWB;
+
+ bitsPerComponent = 1;
+ bitsPerPixel = 1;
+ if (image->bitmap_bit_order != MSBFirst) {
+ char *srcPtr = image->data + image->xoffset;
+ char *endPtr = srcPtr + len;
+ char *destPtr = (data = ckalloc(len));
+
+ while (srcPtr < endPtr) {
+ *destPtr++ = xBitReverseTable[(unsigned char)(*(srcPtr++))];
+ }
+ } else {
+ data = memcpy(ckalloc(len), image->data + image->xoffset, len);
+ }
+ if (data) {
+ provider = CGDataProviderCreateWithData(data, data, len, releaseData);
+ }
+ if (provider) {
+ img = CGImageMaskCreate(image->width, image->height, bitsPerComponent,
+ bitsPerPixel, image->bytes_per_line, provider, decode, 0);
+ }
+ } else if (image->format == ZPixmap && image->bits_per_pixel == 32) {
+ /*
+ * Color image
+ */
+
+ CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
+
+ bitsPerComponent = 8;
+ bitsPerPixel = 32;
+ bitmapInfo = (image->byte_order == MSBFirst ?
+ kCGBitmapByteOrder32Big : kCGBitmapByteOrder32Little) |
+ kCGImageAlphaNoneSkipFirst;
+ data = memcpy(ckalloc(len), image->data + image->xoffset, len);
+ if (data) {
+ provider = CGDataProviderCreateWithData(data, data, len, releaseData);
+ }
+ if (provider) {
+ img = CGImageCreate(image->width, image->height, bitsPerComponent,
+ bitsPerPixel, image->bytes_per_line, colorspace, bitmapInfo,
+ provider, decode, 0, kCGRenderingIntentDefault);
+ CFRelease(provider);
+ }
+ if (colorspace) {
+ CFRelease(colorspace);
+ }
+ } else {
+ TkMacOSXDbgMsg("Unsupported image type");
+ }
+ return img;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XGetImage --
+ *
+ * This function copies data from a pixmap or window into an XImage.
+ *
+ * Results:
+ * Returns a newly allocated XImage containing the data from the given
+ * rectangle of the given drawable, or NULL if the XImage could not be
+ * constructed. NOTE: If we are copying from a window on a Retina
+ * display, the dimensions of the XImage will be 2*width x 2*height.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+XImage *
+XGetImage(
+ Display *display,
+ Drawable d,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height,
+ unsigned long plane_mask,
+ int format)
+{
+ NSBitmapImageRep *bitmap_rep;
+ NSUInteger bitmap_fmt;
+ XImage * imagePtr = NULL;
+ char * bitmap = NULL;
+ char * image_data=NULL;
+ int depth = 32;
+ int offset = 0;
+ int bitmap_pad = 0;
+ int bytes_per_row = 4*width;
+ int size;
+ 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.
+ */
+ if (win && [win respondsToSelector:@selector(backingScaleFactor)]) {
+ scalefactor = ([win backingScaleFactor] == 2.0) ? 2 : 1;
+ }
+#endif
+ int scaled_height = height * scalefactor;
+ int scaled_width = width * scalefactor;
+
+ if (format == ZPixmap) {
+ if (width == 0 || height == 0) {
+ /* This happens all the time.
+ TkMacOSXDbgMsg("XGetImage: empty image requested");
+ */
+ return NULL;
+ }
+
+ bitmap_rep = TkMacOSXBitmapRepFromDrawableRect(d, x, y, width, height);
+ bitmap_fmt = [bitmap_rep bitmapFormat];
+
+ if ( bitmap_rep == Nil ||
+ (bitmap_fmt != 0 && bitmap_fmt != 1) ||
+ [bitmap_rep samplesPerPixel] != 4 ||
+ [bitmap_rep isPlanar] != 0 ) {
+ TkMacOSXDbgMsg("XGetImage: Failed to construct NSBitmapRep");
+ return NULL;
+ }
+
+ NSSize image_size = NSMakeSize(width, height);
+ NSImage* ns_image = [[NSImage alloc]initWithSize:image_size];
+ [ns_image addRepresentation:bitmap_rep];
+
+ /* Assume premultiplied nonplanar data with 4 bytes per pixel.*/
+ if ( [bitmap_rep isPlanar ] == 0 &&
+ [bitmap_rep samplesPerPixel] == 4 ) {
+ bytes_per_row = [bitmap_rep bytesPerRow];
+ assert(bytes_per_row == 4 * scaled_width);
+ assert([bitmap_rep bytesPerPlane] == bytes_per_row * scaled_height);
+ size = bytes_per_row*scaled_height;
+ image_data = (char*)[bitmap_rep bitmapData];
+ if ( image_data ) {
+ int row, n, m;
+ bitmap = ckalloc(size);
+ /*
+ Oddly enough, the bitmap has the top row at the beginning,
+ and the pixels are in BGRA or ABGR format.
+ */
+ if (bitmap_fmt == 0) {
+ /* BGRA */
+ for (row=0, n=0; row<scaled_height; row++, n+=bytes_per_row) {
+ for (m=n; m<n+bytes_per_row; m+=4) {
+ *(bitmap+m) = *(image_data+m+2);
+ *(bitmap+m+1) = *(image_data+m+1);
+ *(bitmap+m+2) = *(image_data+m);
+ *(bitmap+m+3) = *(image_data+m+3);
+ }
+ }
+ } else {
+ /* ABGR */
+ for (row=0, n=0; row<scaled_height; row++, n+=bytes_per_row) {
+ for (m=n; m<n+bytes_per_row; m+=4) {
+ *(bitmap+m) = *(image_data+m+3);
+ *(bitmap+m+1) = *(image_data+m+2);
+ *(bitmap+m+2) = *(image_data+m+1);
+ *(bitmap+m+3) = *(image_data+m);
+ }
+ }
+ }
+ }
+ }
+ if (bitmap) {
+ imagePtr = XCreateImage(display, NULL, depth, format, offset,
+ (char*)bitmap, scaled_width, scaled_height,
+ bitmap_pad, bytes_per_row);
+ if (scalefactor == 2) {
+ imagePtr->pixelpower = 1;
+ }
+ [ns_image removeRepresentation:bitmap_rep]; /*releases the rep*/
+ [ns_image release];
+ }
+ } else {
+ TkMacOSXDbgMsg("Could not extract image from drawable.");
+ }
+ return imagePtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DestroyImage --
+ *
+ * Destroys storage associated with an image.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Deallocates the image.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DestroyImage(
+ XImage *image)
+{
+ if (image) {
+ if (image->data) {
+ ckfree(image->data);
+ }
+ ckfree(image);
+ }
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ImageGetPixel --
+ *
+ * Get a single pixel from an image.
+ *
+ * Results:
+ * Returns the 32 bit pixel value.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static unsigned long
+ImageGetPixel(
+ XImage *image,
+ int x,
+ int y)
+{
+ unsigned char r = 0, g = 0, b = 0;
+
+ if (image && image->data) {
+ unsigned char *srcPtr = ((unsigned char*) image->data)
+ + (y * image->bytes_per_line)
+ + (((image->xoffset + x) * image->bits_per_pixel) / NBBY);
+
+ switch (image->bits_per_pixel) {
+ case 32: {
+ r = (*((unsigned int*) srcPtr) >> 16) & 0xff;
+ g = (*((unsigned int*) srcPtr) >> 8) & 0xff;
+ b = (*((unsigned int*) srcPtr) ) & 0xff;
+ /*if (image->byte_order == LSBFirst) {
+ r = srcPtr[2]; g = srcPtr[1]; b = srcPtr[0];
+ } else {
+ r = srcPtr[1]; g = srcPtr[2]; b = srcPtr[3];
+ }*/
+ break;
+ }
+ case 16:
+ r = (*((unsigned short*) srcPtr) >> 7) & 0xf8;
+ g = (*((unsigned short*) srcPtr) >> 2) & 0xf8;
+ b = (*((unsigned short*) srcPtr) << 3) & 0xf8;
+ break;
+ case 8:
+ r = (*srcPtr << 2) & 0xc0;
+ g = (*srcPtr << 4) & 0xc0;
+ b = (*srcPtr << 6) & 0xc0;
+ r |= r >> 2 | r >> 4 | r >> 6;
+ g |= g >> 2 | g >> 4 | g >> 6;
+ b |= b >> 2 | b >> 4 | b >> 6;
+ break;
+ case 4: {
+ unsigned char c = (x % 2) ? *srcPtr : (*srcPtr >> 4);
+ r = (c & 0x04) ? 0xff : 0;
+ g = (c & 0x02) ? 0xff : 0;
+ b = (c & 0x01) ? 0xff : 0;
+ break;
+ }
+ case 1:
+ r = g = b = ((*srcPtr) & (0x80 >> (x % 8))) ? 0xff : 0;
+ break;
+ }
+ }
+ return (PIXEL_MAGIC << 24) | (r << 16) | (g << 8) | b;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ImagePutPixel --
+ *
+ * Set a single pixel in an image.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ImagePutPixel(
+ XImage *image,
+ int x,
+ int y,
+ unsigned long pixel)
+{
+ if (image && image->data) {
+ unsigned char r = ((pixel & image->red_mask) >> 16) & 0xff;
+ unsigned char g = ((pixel & image->green_mask) >> 8) & 0xff;
+ unsigned char b = ((pixel & image->blue_mask) ) & 0xff;
+ unsigned char *dstPtr = ((unsigned char*) image->data)
+ + (y * image->bytes_per_line)
+ + (((image->xoffset + x) * image->bits_per_pixel) / NBBY);
+
+ switch (image->bits_per_pixel) {
+ case 32:
+ *((unsigned int*) dstPtr) = (0xff << 24) | (r << 16) |
+ (g << 8) | b;
+ /*if (image->byte_order == LSBFirst) {
+ dstPtr[3] = 0xff; dstPtr[2] = r; dstPtr[1] = g; dstPtr[0] = b;
+ } else {
+ dstPtr[0] = 0xff; dstPtr[1] = r; dstPtr[2] = g; dstPtr[3] = b;
+ }*/
+ break;
+ case 16:
+ *((unsigned short*) dstPtr) = ((r & 0xf8) << 7) |
+ ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
+ break;
+ case 8:
+ *dstPtr = ((r & 0xc0) >> 2) | ((g & 0xc0) >> 4) |
+ ((b & 0xc0) >> 6);
+ break;
+ case 4: {
+ unsigned char c = ((r & 0x80) >> 5) | ((g & 0x80) >> 6) |
+ ((b & 0x80) >> 7);
+ *dstPtr = (x % 2) ? ((*dstPtr & 0xf0) | (c & 0x0f)) :
+ ((*dstPtr & 0x0f) | ((c << 4) & 0xf0));
+ break;
+ }
+ case 1:
+ *dstPtr = ((r|g|b) & 0x80) ? (*dstPtr | (0x80 >> (x % 8))) :
+ (*dstPtr & ~(0x80 >> (x % 8)));
+ break;
+ }
+ }
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * XCreateImage --
+ *
+ * Allocates storage for a new XImage.
+ *
+ * Results:
+ * Returns a newly allocated XImage.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+XImage *
+XCreateImage(
+ Display* display,
+ Visual* visual,
+ unsigned int depth,
+ int format,
+ int offset,
+ char* data,
+ unsigned int width,
+ unsigned int height,
+ int bitmap_pad,
+ int bytes_per_line)
+{
+ XImage *ximage;
+ display->request++;
+ ximage = ckalloc(sizeof(XImage));
+
+ ximage->height = height;
+ ximage->width = width;
+ ximage->depth = depth;
+ ximage->xoffset = offset;
+ ximage->format = format;
+ ximage->data = data;
+ ximage->obdata = NULL;
+ /* The default pixelpower is 0. This must be explicitly set to 1 in the
+ * case of an XImage extracted from a Retina display.
+ */
+ ximage->pixelpower = 0;
+
+ if (format == ZPixmap) {
+ ximage->bits_per_pixel = 32;
+ ximage->bitmap_unit = 32;
+ } else {
+ ximage->bits_per_pixel = 1;
+ ximage->bitmap_unit = 8;
+ }
+ if (bitmap_pad) {
+ ximage->bitmap_pad = bitmap_pad;
+ } else {
+ /* Use 16 byte alignment for best Quartz perfomance */
+ ximage->bitmap_pad = 128;
+ }
+ if (bytes_per_line) {
+ ximage->bytes_per_line = bytes_per_line;
+ } else {
+ ximage->bytes_per_line = ((width * ximage->bits_per_pixel +
+ (ximage->bitmap_pad - 1)) >> 3) &
+ ~((ximage->bitmap_pad >> 3) - 1);
+ }
+#ifdef WORDS_BIGENDIAN
+ ximage->byte_order = MSBFirst;
+ ximage->bitmap_bit_order = MSBFirst;
+#else
+ ximage->byte_order = LSBFirst;
+ ximage->bitmap_bit_order = LSBFirst;
+#endif
+ ximage->red_mask = 0x00FF0000;
+ ximage->green_mask = 0x0000FF00;
+ ximage->blue_mask = 0x000000FF;
+ ximage->f.create_image = NULL;
+ ximage->f.destroy_image = DestroyImage;
+ ximage->f.get_pixel = ImageGetPixel;
+ ximage->f.put_pixel = ImagePutPixel;
+ ximage->f.sub_image = NULL;
+ ximage->f.add_pixel = NULL;
+
+ return ximage;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkPutImage --
+ *
+ * Copies a subimage from an in-memory image to a rectangle of
+ * of the specified drawable.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Draws the image on the specified drawable.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkPutImage(
+ unsigned long *colors, /* Unused on Macintosh. */
+ int ncolors, /* Unused on Macintosh. */
+ Display* display, /* Display. */
+ Drawable d, /* Drawable to place image on. */
+ GC gc, /* GC to use. */
+ XImage* image, /* Image to place. */
+ int src_x, /* Source X & Y. */
+ int src_y,
+ int dest_x, /* Destination X & Y. */
+ int dest_y,
+ unsigned int width, /* Same width & height for both */
+ unsigned int height) /* distination and source. */
+{
+ TkMacOSXDrawingContext dc;
+
+ display->request++;
+ if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
+ return BadDrawable;
+ }
+ if (dc.context) {
+ CGImageRef img = TkMacOSXCreateCGImageWithXImage(image);
+
+ if (img) {
+ /* If the XImage has big pixels, rescale the source dimensions.*/
+ int pp = image->pixelpower;
+ TkMacOSXDrawCGImage(d, gc, dc.context,
+ img, gc->foreground, gc->background,
+ CGRectMake(0, 0, image->width<<pp, image->height<<pp),
+ CGRectMake(src_x<<pp, src_y<<pp, width<<pp, height<<pp),
+ CGRectMake(dest_x, dest_y, width, height));
+ CFRelease(img);
+ } else {
+ TkMacOSXDbgMsg("Invalid source drawable");
+ }
+ } else {
+ TkMacOSXDbgMsg("Invalid destination drawable");
+ }
+ TkMacOSXRestoreDrawingContext(&dc);
+ return Success;
+}
+
diff --git a/macosx/tkMacOSXPrivate.h b/macosx/tkMacOSXPrivate.h
index e3c9464..16bb9ea 100644
--- a/macosx/tkMacOSXPrivate.h
+++ b/macosx/tkMacOSXPrivate.h
@@ -209,8 +209,13 @@ MODULE_SCOPE WindowClass TkMacOSXWindowClass(TkWindow *winPtr);
MODULE_SCOPE int TkMacOSXIsWindowZoomed(TkWindow *winPtr);
MODULE_SCOPE int TkGenerateButtonEventForXPointer(Window window);
MODULE_SCOPE EventModifiers TkMacOSXModifierState(void);
-MODULE_SCOPE NSBitmapImageRep* BitmapRepFromDrawableRect(Drawable drawable,
+MODULE_SCOPE NSBitmapImageRep* TkMacOSXBitmapRepFromDrawableRect(Drawable drawable,
int x, int y, unsigned int width, unsigned int height);
+MODULE_SCOPE CGImageRef TkMacOSXCreateCGImageWithXImage(XImage *image);
+MODULE_SCOPE void TkMacOSXDrawCGImage(Drawable d, GC gc, CGContextRef context,
+ CGImageRef image, unsigned long imageForeground,
+ unsigned long imageBackground, CGRect imageBounds,
+ CGRect srcBounds, CGRect dstBounds);
MODULE_SCOPE int TkMacOSXSetupDrawingContext(Drawable d, GC gc,
int useCG, TkMacOSXDrawingContext *dcPtr);
MODULE_SCOPE void TkMacOSXRestoreDrawingContext(
@@ -228,6 +233,7 @@ MODULE_SCOPE void TkMacOSXWinCGBounds(TkWindow *winPtr, CGRect *bounds);
MODULE_SCOPE HIShapeRef TkMacOSXGetClipRgn(Drawable drawable);
MODULE_SCOPE void TkMacOSXInvalidateViewRegion(NSView *view,
HIShapeRef rgn);
+MODULE_SCOPE CGContextRef TkMacOSXGetCGContextForDrawable(Drawable drawable);
MODULE_SCOPE CGImageRef TkMacOSXCreateCGImageWithDrawable(Drawable drawable);
MODULE_SCOPE NSImage* TkMacOSXGetNSImageWithTkImage(Display *display,
Tk_Image image, int width, int height);
diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c
index 750fca8..c7fc6ce 100644
--- a/macosx/tkMacOSXWm.c
+++ b/macosx/tkMacOSXWm.c
@@ -57,8 +57,6 @@
/*Objects for use in setting background color and opacity of window.*/
NSColor *colorName = NULL;
BOOL opaqueTag = FALSE;
-extern CGImageRef CreateCGImageWithXImage(
- XImage *image);
static const struct {
const UInt64 validAttrs, defaultAttrs, forceOnAttrs, forceOffAttrs;
diff --git a/macosx/tkMacOSXXStubs.c b/macosx/tkMacOSXXStubs.c
index 00940b5..4197266 100644
--- a/macosx/tkMacOSXXStubs.c
+++ b/macosx/tkMacOSXXStubs.c
@@ -53,14 +53,6 @@ static XID MacXIdAlloc(Display *display);
static int DefaultErrorHandler(Display *display,
XErrorEvent *err_evt);
-/*
- * Other declarations
- */
-
-static int DestroyImage(XImage *image);
-static unsigned long ImageGetPixel(XImage *image, int x, int y);
-static int ImagePutPixel(XImage *image, int x, int y,
- unsigned long pixel);
/*
*----------------------------------------------------------------------
@@ -383,13 +375,6 @@ XGetAtomName(
return NULL;
}
-int
-_XInitImageFuncPtrs(
- XImage *image)
-{
- return 0;
-}
-
XErrorHandler
XSetErrorHandler(
XErrorHandler handler)
@@ -763,387 +748,6 @@ TkGetServerInfo(
buffer2, NULL);
}
-#pragma mark XImage handling
-
-/*
- *----------------------------------------------------------------------
- *
- * XCreateImage --
- *
- * Allocates storage for a new XImage.
- *
- * Results:
- * Returns a newly allocated XImage.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-XImage *
-XCreateImage(
- Display* display,
- Visual* visual,
- unsigned int depth,
- int format,
- int offset,
- char* data,
- unsigned int width,
- unsigned int height,
- int bitmap_pad,
- int bytes_per_line)
-{
- XImage *ximage;
- display->request++;
- ximage = ckalloc(sizeof(XImage));
-
- ximage->height = height;
- ximage->width = width;
- ximage->depth = depth;
- ximage->xoffset = offset;
- ximage->format = format;
- ximage->data = data;
- ximage->obdata = NULL;
- /* The default pixelpower is 0. This must be explicitly set to 1 in the
- * case of an XImage extracted from a Retina display.
- */
- ximage->pixelpower = 0;
-
- if (format == ZPixmap) {
- ximage->bits_per_pixel = 32;
- ximage->bitmap_unit = 32;
- } else {
- ximage->bits_per_pixel = 1;
- ximage->bitmap_unit = 8;
- }
- if (bitmap_pad) {
- ximage->bitmap_pad = bitmap_pad;
- } else {
- /* Use 16 byte alignment for best Quartz perfomance */
- ximage->bitmap_pad = 128;
- }
- if (bytes_per_line) {
- ximage->bytes_per_line = bytes_per_line;
- } else {
- ximage->bytes_per_line = ((width * ximage->bits_per_pixel +
- (ximage->bitmap_pad - 1)) >> 3) &
- ~((ximage->bitmap_pad >> 3) - 1);
- }
-#ifdef WORDS_BIGENDIAN
- ximage->byte_order = MSBFirst;
- ximage->bitmap_bit_order = MSBFirst;
-#else
- ximage->byte_order = LSBFirst;
- ximage->bitmap_bit_order = LSBFirst;
-#endif
- ximage->red_mask = 0x00FF0000;
- ximage->green_mask = 0x0000FF00;
- ximage->blue_mask = 0x000000FF;
- ximage->f.create_image = NULL;
- ximage->f.destroy_image = DestroyImage;
- ximage->f.get_pixel = ImageGetPixel;
- ximage->f.put_pixel = ImagePutPixel;
- ximage->f.sub_image = NULL;
- ximage->f.add_pixel = NULL;
-
- return ximage;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * XGetImage --
- *
- * This function copies data from a pixmap or window into an XImage.
- *
- * Results:
- * Returns a newly allocated XImage containing the data from the given
- * rectangle of the given drawable, or NULL if the XImage could not be
- * constructed. NOTE: If we are copying from a window on a Retina
- * display, the dimensions of the XImage will be 2*width x 2*height.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-XImage *
-XGetImage(
- Display *display,
- Drawable d,
- int x,
- int y,
- unsigned int width,
- unsigned int height,
- unsigned long plane_mask,
- int format)
-{
- NSBitmapImageRep *bitmap_rep;
- NSUInteger bitmap_fmt;
- XImage * imagePtr = NULL;
- char * bitmap = NULL;
- char * image_data=NULL;
- int depth = 32;
- int offset = 0;
- int bitmap_pad = 0;
- int bytes_per_row = 4*width;
- int size;
- 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.
- */
- if (win && [win respondsToSelector:@selector(backingScaleFactor)]) {
- scalefactor = ([win backingScaleFactor] == 2.0) ? 2 : 1;
- }
-#endif
- int scaled_height = height * scalefactor;
- int scaled_width = width * scalefactor;
-
- if (format == ZPixmap) {
- if (width == 0 || height == 0) {
- /* This happens all the time.
- TkMacOSXDbgMsg("XGetImage: empty image requested");
- */
- return NULL;
- }
-
- bitmap_rep = BitmapRepFromDrawableRect(d, x, y, width, height);
- bitmap_fmt = [bitmap_rep bitmapFormat];
-
- if ( bitmap_rep == Nil ||
- (bitmap_fmt != 0 && bitmap_fmt != 1) ||
- [bitmap_rep samplesPerPixel] != 4 ||
- [bitmap_rep isPlanar] != 0 ) {
- TkMacOSXDbgMsg("XGetImage: Failed to construct NSBitmapRep");
- return NULL;
- }
-
- NSSize image_size = NSMakeSize(width, height);
- NSImage* ns_image = [[NSImage alloc]initWithSize:image_size];
- [ns_image addRepresentation:bitmap_rep];
-
- /* Assume premultiplied nonplanar data with 4 bytes per pixel.*/
- if ( [bitmap_rep isPlanar ] == 0 &&
- [bitmap_rep samplesPerPixel] == 4 ) {
- bytes_per_row = [bitmap_rep bytesPerRow];
- assert(bytes_per_row == 4 * scaled_width);
- assert([bitmap_rep bytesPerPlane] == bytes_per_row * scaled_height);
- size = bytes_per_row*scaled_height;
- image_data = (char*)[bitmap_rep bitmapData];
- if ( image_data ) {
- int row, n, m;
- bitmap = ckalloc(size);
- /*
- Oddly enough, the bitmap has the top row at the beginning,
- and the pixels are in BGRA or ABGR format.
- */
- if (bitmap_fmt == 0) {
- /* BGRA */
- for (row=0, n=0; row<scaled_height; row++, n+=bytes_per_row) {
- for (m=n; m<n+bytes_per_row; m+=4) {
- *(bitmap+m) = *(image_data+m+2);
- *(bitmap+m+1) = *(image_data+m+1);
- *(bitmap+m+2) = *(image_data+m);
- *(bitmap+m+3) = *(image_data+m+3);
- }
- }
- } else {
- /* ABGR */
- for (row=0, n=0; row<scaled_height; row++, n+=bytes_per_row) {
- for (m=n; m<n+bytes_per_row; m+=4) {
- *(bitmap+m) = *(image_data+m+3);
- *(bitmap+m+1) = *(image_data+m+2);
- *(bitmap+m+2) = *(image_data+m+1);
- *(bitmap+m+3) = *(image_data+m);
- }
- }
- }
- }
- }
- if (bitmap) {
- imagePtr = XCreateImage(display, NULL, depth, format, offset,
- (char*)bitmap, scaled_width, scaled_height,
- bitmap_pad, bytes_per_row);
- if (scalefactor == 2) {
- imagePtr->pixelpower = 1;
- }
- [ns_image removeRepresentation:bitmap_rep]; /*releases the rep*/
- [ns_image release];
- }
- } else {
- TkMacOSXDbgMsg("Could not extract image from drawable.");
- }
- return imagePtr;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * DestroyImage --
- *
- * Destroys storage associated with an image.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Deallocates the image.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-DestroyImage(
- XImage *image)
-{
- if (image) {
- if (image->data) {
- ckfree(image->data);
- }
- ckfree(image);
- }
- return 0;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * ImageGetPixel --
- *
- * Get a single pixel from an image.
- *
- * Results:
- * Returns the 32 bit pixel value.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-static unsigned long
-ImageGetPixel(
- XImage *image,
- int x,
- int y)
-{
- unsigned char r = 0, g = 0, b = 0;
-
- if (image && image->data) {
- unsigned char *srcPtr = ((unsigned char*) image->data)
- + (y * image->bytes_per_line)
- + (((image->xoffset + x) * image->bits_per_pixel) / NBBY);
-
- switch (image->bits_per_pixel) {
- case 32: {
- r = (*((unsigned int*) srcPtr) >> 16) & 0xff;
- g = (*((unsigned int*) srcPtr) >> 8) & 0xff;
- b = (*((unsigned int*) srcPtr) ) & 0xff;
- /*if (image->byte_order == LSBFirst) {
- r = srcPtr[2]; g = srcPtr[1]; b = srcPtr[0];
- } else {
- r = srcPtr[1]; g = srcPtr[2]; b = srcPtr[3];
- }*/
- break;
- }
- case 16:
- r = (*((unsigned short*) srcPtr) >> 7) & 0xf8;
- g = (*((unsigned short*) srcPtr) >> 2) & 0xf8;
- b = (*((unsigned short*) srcPtr) << 3) & 0xf8;
- break;
- case 8:
- r = (*srcPtr << 2) & 0xc0;
- g = (*srcPtr << 4) & 0xc0;
- b = (*srcPtr << 6) & 0xc0;
- r |= r >> 2 | r >> 4 | r >> 6;
- g |= g >> 2 | g >> 4 | g >> 6;
- b |= b >> 2 | b >> 4 | b >> 6;
- break;
- case 4: {
- unsigned char c = (x % 2) ? *srcPtr : (*srcPtr >> 4);
- r = (c & 0x04) ? 0xff : 0;
- g = (c & 0x02) ? 0xff : 0;
- b = (c & 0x01) ? 0xff : 0;
- break;
- }
- case 1:
- r = g = b = ((*srcPtr) & (0x80 >> (x % 8))) ? 0xff : 0;
- break;
- }
- }
- return (PIXEL_MAGIC << 24) | (r << 16) | (g << 8) | b;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * ImagePutPixel --
- *
- * Set a single pixel in an image.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-ImagePutPixel(
- XImage *image,
- int x,
- int y,
- unsigned long pixel)
-{
- if (image && image->data) {
- unsigned char r = ((pixel & image->red_mask) >> 16) & 0xff;
- unsigned char g = ((pixel & image->green_mask) >> 8) & 0xff;
- unsigned char b = ((pixel & image->blue_mask) ) & 0xff;
- unsigned char *dstPtr = ((unsigned char*) image->data)
- + (y * image->bytes_per_line)
- + (((image->xoffset + x) * image->bits_per_pixel) / NBBY);
-
- switch (image->bits_per_pixel) {
- case 32:
- *((unsigned int*) dstPtr) = (0xff << 24) | (r << 16) |
- (g << 8) | b;
- /*if (image->byte_order == LSBFirst) {
- dstPtr[3] = 0xff; dstPtr[2] = r; dstPtr[1] = g; dstPtr[0] = b;
- } else {
- dstPtr[0] = 0xff; dstPtr[1] = r; dstPtr[2] = g; dstPtr[3] = b;
- }*/
- break;
- case 16:
- *((unsigned short*) dstPtr) = ((r & 0xf8) << 7) |
- ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
- break;
- case 8:
- *dstPtr = ((r & 0xc0) >> 2) | ((g & 0xc0) >> 4) |
- ((b & 0xc0) >> 6);
- break;
- case 4: {
- unsigned char c = ((r & 0x80) >> 5) | ((g & 0x80) >> 6) |
- ((b & 0x80) >> 7);
- *dstPtr = (x % 2) ? ((*dstPtr & 0xf0) | (c & 0x0f)) :
- ((*dstPtr & 0x0f) | ((c << 4) & 0xf0));
- break;
- }
- case 1:
- *dstPtr = ((r|g|b) & 0x80) ? (*dstPtr | (0x80 >> (x % 8))) :
- (*dstPtr & ~(0x80 >> (x % 8)));
- break;
- }
- }
- return 0;
-}
-
/*
*----------------------------------------------------------------------
*
diff --git a/unix/Makefile.in b/unix/Makefile.in
index 96f1408..54f947e 100644
--- a/unix/Makefile.in
+++ b/unix/Makefile.in
@@ -394,8 +394,8 @@ X11_OBJS = tkUnix.o tkUnix3d.o tkUnixButton.o tkUnixColor.o tkUnixConfig.o \
AQUA_OBJS = tkMacOSXBitmap.o tkMacOSXButton.o tkMacOSXClipboard.o \
tkMacOSXColor.o tkMacOSXConfig.o tkMacOSXCursor.o tkMacOSXDebug.o \
tkMacOSXDialog.o tkMacOSXDraw.o tkMacOSXEmbed.o tkMacOSXEntry.o \
- tkMacOSXEvent.o tkMacOSXFont.o tkMacOSXHLEvents.o tkMacOSXInit.o \
- tkMacOSXKeyboard.o tkMacOSXKeyEvent.o tkMacOSXMenu.o \
+ tkMacOSXEvent.o tkMacOSXFont.o tkMacOSXHLEvents.o tkMacOSXImage.o \
+ tkMacOSXInit.o tkMacOSXKeyboard.o tkMacOSXKeyEvent.o tkMacOSXMenu.o \
tkMacOSXMenubutton.o tkMacOSXMenus.o tkMacOSXMouseEvent.o \
tkMacOSXNotify.o tkMacOSXRegion.o tkMacOSXScrlbr.o tkMacOSXSend.o \
tkMacOSXSubwindows.o tkMacOSXWindowEvent.o \
@@ -519,6 +519,7 @@ AQUA_SRCS = \
$(MAC_OSX_DIR)/tkMacOSXDraw.c $(MAC_OSX_DIR)/tkMacOSXEmbed.c \
$(MAC_OSX_DIR)/tkMacOSXEntry.c $(MAC_OSX_DIR)/tkMacOSXEvent.c \
$(MAC_OSX_DIR)/tkMacOSXFont.c $(MAC_OSX_DIR)/tkMacOSXHLEvents.c \
+ $(MAC_OSX_DIR)/tkMacOSXImage.c \
$(MAC_OSX_DIR)/tkMacOSXInit.c $(MAC_OSX_DIR)/tkMacOSXKeyboard.c \
$(MAC_OSX_DIR)/tkMacOSXKeyEvent.c $(MAC_OSX_DIR)/tkMacOSXMenu.c \
$(MAC_OSX_DIR)/tkMacOSXMenubutton.c $(MAC_OSX_DIR)/tkMacOSXMenus.c \
@@ -1272,6 +1273,9 @@ tkMacOSXFont.o: $(MAC_OSX_DIR)/tkMacOSXFont.c
tkMacOSXHLEvents.o: $(MAC_OSX_DIR)/tkMacOSXHLEvents.c
$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXHLEvents.c
+tkMacOSXImage.o: $(MAC_OSX_DIR)/tkMacOSXImage.c
+ $(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXImage.c
+
tkMacOSXInit.o: $(MAC_OSX_DIR)/tkMacOSXInit.c tkConfig.sh
$(CC) -c $(CC_SWITCHES) -DTK_LIBRARY=\"${TK_LIBRARY}\" \
$(MAC_OSX_DIR)/tkMacOSXInit.c