head	1.14;
access;
symbols
	core-8-5-9:1.11
	core-8-5-8:1.11
	macosx-cocoa-merge:1.12
	macosx-cocoa-premerge:1.12
	macosx-carbon-freeze:1.12
	core-8-5-7:1.11
	core-8-5-6:1.11
	core-8-6-b1:1.12
	core-8-6-a3:1.11
	core-8-5-5:1.11
	core-8-6-a2:1.11
	core-8-5-4:1.11
	core-8-5-3:1.11
	core-8-6-a1:1.11
	core-8-4-19:1.6.2.2
	core-8-5-branch:1.11.0.4
	core-8-5-2:1.11
	core-8-4-18:1.6.2.2
	core-8-5-1:1.11
	core-8-4-17:1.6.2.2
	core-8-5-0:1.11
	core-8-5-b3:1.11
	core-8-5-b2:1.11
	core-8-4-16:1.6.2.2
	core-8-5-b1:1.11
	core-stablilizer-merge:1.11
	core-stabilizer-branch:1.11.0.2
	core-stabilizer-merge:1.11
	core-8-4-15:1.6.2.2
	core-8-5-a6:1.11
	core-8-5-a5:1.9
	core-8-4-14:1.6.2.2
	core-8-5-a4:1.9
	core-8-4-13:1.6.2.2
	core-8-4-12:1.6.2.2
	core-8-4-11:1.6.2.2
	core-8-5-a3:1.8
	core-8-4-10:1.6.2.2
	core-8-4-9-branch:1.6.2.2.0.2
	core-8-5-a2:1.8
	core-8-4-9:1.6.2.2
	core-8-4-8:1.6.2.2
	core-8-4-7:1.6.2.2
	core-8-5-a1:1.8
	core-8-4-6:1.6.2.2
	core-8-4-5:1.6.2.2
	mistachkin-dev-branch:1.7.0.2
	core-8-4-4:1.6.2.1
	core-8-4-3:1.6
	core-8-4-branch:1.6.0.2
	core-8-4-2:1.6
	core-8-4-1:1.6
	core-8-3-5:1.3.2.2
	core-8-4-0:1.4
	macosx-8-4-merge-2002-08-31-trunk:1.4
	macosx-8-4-premerge-2002-08-31-branch:1.3.8.1
	macosx-8-4-premerge-2002-08-31-trunk:1.4
	macosx-8-4-merge-2002-08-30-branch:1.3.8.1
	macosx-8-4-merge-2002-08-30-trunk:1.4
	macosx-8-4-merge-2002-08-20-branch:1.3.8.1
	macosx-8-4-merge-2002-08-20-trunk:1.4
	core-8-4-b2:1.4
	core-8-4-b1:1.4
	macosx-premerge-6-9-02:1.3
	core-8-4-a4:1.3
	core-8-3-4:1.3
	macosx-8-4-branch:1.3.0.8
	macosx-8-4-branchpoint:1.3
	core-8-4-a3:1.3
	core-8-3-3:1.3
	dgp-privates-into-namespace:1.3.0.6
	tclpro-1-5-0:1.3
	core-8-4-win-speedup:1.3.0.4
	core-8-4-a2:1.3
	tclpro-1-4-1:1.3
	tclpro-1-4-0:1.3
	core-8-3-2:1.3
	ajuba-ajuba2-2-1-base:1.3
	ajuba-ajuba2-2-0:1.3
	core-8-4-a1:1.3
	core-8-3-1-branch:1.3.0.2
	core-8-3-1:1.3
	scriptics-sc-2-0-b5:1.3
	scriptics-sc-2-0-fixed:1.3
	scriptics-sc-2-0-b2:1.3
	scriptics-sc-2-0-b1:1.3
	core-8-3-0:1.3
	core-8-3-b2:1.3
	core-8-3-b1:1.2
	scriptics-sc-1-1:1.2
	scriptics-sc-1-1-b1:1.2
	core-8-2-3:1.2
	scriptics-sc-1-1-branch:1.2.0.16
	scriptics-sc-1-1-base:1.2
	scriptics-sc-1-0:1.2
	scriptics-sc-1-0-branch:1.2.0.14
	scriptics-sc-1-0-base:1.2
	core-8-2-2:1.2
	core-8-2-1:1.2
	scriptics-bc-1-0-b1:1.2
	core-8-2-1-branch:1.2.0.12
	scriptics-tclpro-1-3-0:1.2
	core-8-2-0:1.2
	core-8-2-b3-branch:1.2.0.10
	core-8-2-b3-base:1.2
	scriptics-tclpro-1-3-b4:1.2
	core-8-2-b2:1.2
	scriptics-tclpro-1-3-b3:1.2
	core-8-2-b1:1.2
	scriptics-tclpro-1-3-b2:1.2
	merge-to-mainline-5/21/99:1.2
	scriptics-tclpro-1-3-b2-branch:1.2.0.8
	core-8-1-1:1.2
	scriptics-tclpro-1-3-b1:1.2
	core-8-1-1-base:1.2
	core-8-1-0:1.2
	merge-to-mainline-4-29-99:1.2
	merge-to-mainline-4-23-99:1.2
	core-8-1-branch-old:1.1.0.4
	core-8-0-6-branch:1.2.0.6
	core-8-0-6-base:1.2
	core-8-0-5:1.2
	core-8-1-b3:1.1.4.1
	core-8-1-b2:1.1.4.1
	dev-8-1-stubs-branch:1.1.4.1.0.2
	dev-stubs-branch:1.2.0.4
	scriptics-tclpro-1-2:1.2
	scriptics-tclpro-1-2-b2:1.2
	core-8-1-merge-2/10/99:1.2
	core-8-0-5-branch:1.2.0.2
	core-8-0-5-base:1.2
	scriptics-tclpro-1-2-b1:1.2
	scriptics-tclpro-1-2-a1:1.2
	core-8-1-b1:1.1.4.1
	core-8-0-4:1.2
	core-8-1-a2:1.1
	core-8-0-2:1.1
	core-8-0-3:1.2;
locks; strict;
comment	@ * @;


1.14
date	2010.12.17.15.14.22;	author nijtmans;	state Exp;
branches;
next	1.13;

1.13
date	2009.08.02.21.40.17;	author nijtmans;	state Exp;
branches;
next	1.12;

1.12
date	2008.10.17.23.18.38;	author nijtmans;	state Exp;
branches;
next	1.11;

1.11
date	2007.01.12.10.41.23;	author dkf;	state Exp;
branches;
next	1.10;

1.10
date	2007.01.11.15.35.40;	author dkf;	state Exp;
branches;
next	1.9;

1.9
date	2005.12.02.00.19.04;	author dkf;	state Exp;
branches;
next	1.8;

1.8
date	2003.10.28.22.52.01;	author hobbs;	state Exp;
branches;
next	1.7;

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

1.6
date	2002.10.10.21.01.18;	author hobbs;	state Exp;
branches
	1.6.2.1;
next	1.5;

1.5
date	2002.10.10.07.25.24;	author hobbs;	state Exp;
branches;
next	1.4;

1.4
date	2002.03.26.20.13.39;	author chengyemao;	state Exp;
branches;
next	1.3;

1.3
date	2000.01.06.02.22.51;	author hobbs;	state Exp;
branches
	1.3.2.1
	1.3.4.1
	1.3.8.1;
next	1.2;

1.2
date	98.09.14.18.24.00;	author stanton;	state Exp;
branches;
next	1.1;

1.1
date	98.04.01.10.00.30;	author rjohnson;	state Exp;
branches
	1.1.4.1;
next	;

1.1.4.1
date	98.09.30.02.19.33;	author stanton;	state Exp;
branches;
next	;

1.3.2.1
date	2002.10.10.07.27.12;	author hobbs;	state Exp;
branches;
next	1.3.2.2;

1.3.2.2
date	2002.10.10.21.02.09;	author hobbs;	state Exp;
branches;
next	;

1.3.4.1
date	2000.11.03.22.49.27;	author hobbs;	state Exp;
branches;
next	1.3.4.2;

1.3.4.2
date	2002.04.02.21.17.04;	author hobbs;	state Exp;
branches;
next	;

1.3.8.1
date	2002.06.10.05.38.28;	author wolfsuit;	state Exp;
branches;
next	;

1.6.2.1
date	2003.07.17.01.02.47;	author hobbs;	state Exp;
branches;
next	1.6.2.2;

1.6.2.2
date	2003.10.29.01.08.02;	author hobbs;	state Exp;
branches;
next	;


desc
@@


1.14
log
@refactor isatty() function for Windows
Let TkpDisplayWarning() send the message directly to the debugger, if available, otherwise do as before
@
text
@/*
 * tkWinImage.c --
 *
 *	This file contains routines for manipulation full-color images.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @@(#) $Id: tkWinImage.c,v 1.13 2009/08/02 21:40:17 nijtmans Exp $
 */

#include "tkWinInt.h"

static int		DestroyImage(XImage* data);
static unsigned long	ImageGetPixel(XImage *image, int x, int y);
static int		PutPixel(XImage *image, int x, int y,
			    unsigned long pixel);

/*
 *----------------------------------------------------------------------
 *
 * DestroyImage --
 *
 *	This is a trivial wrapper around ckfree to make it possible to pass
 *	ckfree as a pointer.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Deallocates the image.
 *
 *----------------------------------------------------------------------
 */

static int
DestroyImage(
    XImage *imagePtr)		/* Image to free. */
{
    if (imagePtr) {
	if (imagePtr->data) {
	    ckfree((char*)imagePtr->data);
	}
	ckfree((char*)imagePtr);
    }
    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 long pixel = 0;
    unsigned char *srcPtr = (unsigned char *) &(image->data[(y * image->bytes_per_line)
	    + ((x * image->bits_per_pixel) / NBBY)]);

    switch (image->bits_per_pixel) {
    case 32:
    case 24:
	pixel = RGB(srcPtr[2], srcPtr[1], srcPtr[0]);
	break;
    case 16:
	pixel = RGB(((((WORD*)srcPtr)[0]) >> 7) & 0xf8,
		((((WORD*)srcPtr)[0]) >> 2) & 0xf8,
		((((WORD*)srcPtr)[0]) << 3) & 0xf8);
	break;
    case 8:
	pixel = srcPtr[0];
	break;
    case 4:
	pixel = ((x%2) ? (*srcPtr) : ((*srcPtr) >> 4)) & 0x0f;
	break;
    case 1:
	pixel = ((*srcPtr) & (0x80 >> (x%8))) ? 1 : 0;
	break;
    }
    return pixel;
}

/*
 *----------------------------------------------------------------------
 *
 * PutPixel --
 *
 *	Set a single pixel in an image.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
PutPixel(
    XImage *image,
    int x, int y,
    unsigned long pixel)
{
    unsigned char *destPtr = (unsigned char *) &(image->data[(y * image->bytes_per_line)
	    + ((x * image->bits_per_pixel) / NBBY)]);

    switch  (image->bits_per_pixel) {
    case 32:
	/*
	 * Pixel is DWORD: 0x00BBGGRR
	 */

	destPtr[3] = 0;
    case 24:
	/*
	 * Pixel is triplet: 0xBBGGRR.
	 */

	destPtr[0] = (unsigned char) GetBValue(pixel);
	destPtr[1] = (unsigned char) GetGValue(pixel);
	destPtr[2] = (unsigned char) GetRValue(pixel);
	break;
    case 16:
	/*
	 * Pixel is WORD: 5-5-5 (R-G-B)
	 */

	(*(WORD*)destPtr) = ((GetRValue(pixel) & 0xf8) << 7)
		| ((GetGValue(pixel) & 0xf8) <<2)
		| ((GetBValue(pixel) & 0xf8) >> 3);
	break;
    case 8:
	/*
	 * Pixel is 8-bit index into color table.
	 */

	(*destPtr) = (unsigned char) pixel;
	break;
    case 4:
	/*
	 * Pixel is 4-bit index in MSBFirst order.
	 */

	if (x%2) {
	    (*destPtr) = (unsigned char) (((*destPtr) & 0xf0)
		    | (pixel & 0x0f));
	} else {
	    (*destPtr) = (unsigned char) (((*destPtr) & 0x0f)
		    | ((pixel << 4) & 0xf0));
	}
	break;
    case 1: {
	/*
	 * Pixel is bit in MSBFirst order.
	 */

	int mask = (0x80 >> (x%8));

	if (pixel) {
	    (*destPtr) |= mask;
	} else {
	    (*destPtr) &= ~mask;
	}
	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* imagePtr = (XImage *) ckalloc(sizeof(XImage));
    imagePtr->width = width;
    imagePtr->height = height;
    imagePtr->xoffset = offset;
    imagePtr->format = format;
    imagePtr->data = data;
    imagePtr->byte_order = LSBFirst;
    imagePtr->bitmap_unit = 8;
    imagePtr->bitmap_bit_order = LSBFirst;
    imagePtr->bitmap_pad = bitmap_pad;
    imagePtr->bits_per_pixel = depth;
    imagePtr->depth = depth;

    /*
     * Under Windows, bitmap_pad must be on an LONG data-type boundary.
     */

#define LONGBITS    (sizeof(LONG) * 8)

    bitmap_pad = (bitmap_pad + LONGBITS - 1) / LONGBITS * LONGBITS;

    /*
     * Round to the nearest bitmap_pad boundary.
     */

    if (bytes_per_line) {
	imagePtr->bytes_per_line = bytes_per_line;
    } else {
	imagePtr->bytes_per_line = (((depth * width)
		+ (bitmap_pad - 1)) >> 3) & ~((bitmap_pad >> 3) - 1);
    }

    imagePtr->red_mask = 0;
    imagePtr->green_mask = 0;
    imagePtr->blue_mask = 0;

    imagePtr->f.put_pixel = PutPixel;
    imagePtr->f.get_pixel = ImageGetPixel;
    imagePtr->f.destroy_image = DestroyImage;
    imagePtr->f.create_image = NULL;
    imagePtr->f.sub_image = NULL;
    imagePtr->f.add_pixel = NULL;

    return imagePtr;
}

/*
 *----------------------------------------------------------------------
 *
 * XGetImageZPixmap --
 *
 *	This function copies data from a pixmap or window into an XImage. This
 *	handles the ZPixmap case only.
 *
 * Results:
 *	Returns a newly allocated image containing the data from the given
 *	rectangle of the given drawable.
 *
 * Side effects:
 *	None.
 *
 * This procedure is adapted from the XGetImage implementation in TkNT. That
 * code is Copyright (c) 1994 Software Research Associates, Inc.
 *
 *----------------------------------------------------------------------
 */

static XImage *
XGetImageZPixmap(
    Display *display,
    Drawable d,
    int x, int y,
    unsigned int width, unsigned int height,
    unsigned long plane_mask,
    int	format)
{
    TkWinDrawable *twdPtr = (TkWinDrawable *)d;
    XImage *ret_image;
    HDC hdc, hdcMem;
    HBITMAP hbmp, hbmpPrev;
    BITMAPINFO *bmInfo = NULL;
    HPALETTE hPal, hPalPrev1 = 0, hPalPrev2 = 0;
    int size;
    unsigned int n;
    unsigned int depth;
    unsigned char *data;
    TkWinDCState state;
    BOOL ret;

    if (format != ZPixmap) {
	TkpDisplayWarning("Only ZPixmap types are implemented",
		"XGetImageZPixmap Failure");
	return NULL;
    }

    hdc = TkWinGetDrawableDC(display, d, &state);

    /*
     * Need to do a Blt operation to copy into a new bitmap.
     */

    hbmp = CreateCompatibleBitmap(hdc, (int) width, (int) height);
    hdcMem = CreateCompatibleDC(hdc);
    hbmpPrev = SelectObject(hdcMem, hbmp);
    hPal = state.palette;
    if (hPal) {
	hPalPrev1 = SelectPalette(hdcMem, hPal, FALSE);
	n = RealizePalette(hdcMem);
	if (n > 0) {
	    UpdateColors(hdcMem);
	}
	hPalPrev2 = SelectPalette(hdc, hPal, FALSE);
	n = RealizePalette(hdc);
	if (n > 0) {
	    UpdateColors(hdc);
	}
    }

    ret = BitBlt(hdcMem, 0, 0, (int) width, (int) height, hdc, x, y, SRCCOPY);
    if (hPal) {
	SelectPalette(hdc, hPalPrev2, FALSE);
    }
    SelectObject(hdcMem, hbmpPrev);
    TkWinReleaseDrawableDC(d, hdc, &state);
    if (ret == FALSE) {
	ret_image = NULL;
	goto cleanup;
    }
    if (twdPtr->type == TWD_WINDOW) {
	depth = Tk_Depth((Tk_Window) twdPtr->window.winPtr);
    } else {
	depth = twdPtr->bitmap.depth;
    }

    size = sizeof(BITMAPINFO);
    if (depth <= 8) {
	size += sizeof(unsigned short) * (1 << depth);
    }
    bmInfo = (BITMAPINFO *) ckalloc((unsigned)size);

    bmInfo->bmiHeader.biSize		= sizeof(BITMAPINFOHEADER);
    bmInfo->bmiHeader.biWidth		= width;
    bmInfo->bmiHeader.biHeight		= -(int) height;
    bmInfo->bmiHeader.biPlanes		= 1;
    bmInfo->bmiHeader.biBitCount	= depth;
    bmInfo->bmiHeader.biCompression	= BI_RGB;
    bmInfo->bmiHeader.biSizeImage	= 0;
    bmInfo->bmiHeader.biXPelsPerMeter	= 0;
    bmInfo->bmiHeader.biYPelsPerMeter	= 0;
    bmInfo->bmiHeader.biClrUsed		= 0;
    bmInfo->bmiHeader.biClrImportant	= 0;

    if (depth == 1) {
	unsigned char *p, *pend;

	GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_PAL_COLORS);
	data = (unsigned char *) ckalloc(bmInfo->bmiHeader.biSizeImage);
	if (!data) {
	    /* printf("Failed to allocate data area for XImage.\n"); */
	    ret_image = NULL;
	    goto cleanup;
	}
	ret_image = XCreateImage(display, NULL, depth, ZPixmap, 0, (char *) data,
		width, height, 32, (int) ((width + 31) >> 3) & ~1);
	if (ret_image == NULL) {
	    ckfree((char *) data);
	    goto cleanup;
	}

	/*
	 * Get the BITMAP info into the Image.
	 */

	if (GetDIBits(hdcMem, hbmp, 0, height, data, bmInfo,
		DIB_PAL_COLORS) == 0) {
	    ckfree((char *) ret_image->data);
	    ckfree((char *) ret_image);
	    ret_image = NULL;
	    goto cleanup;
	}
	p = data;
	pend = data + bmInfo->bmiHeader.biSizeImage;
	while (p < pend) {
	    *p = ~*p;
	    p++;
	}
    } else if (depth == 8) {
	unsigned short *palette;
	unsigned int i;
	unsigned char *p;

	GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_PAL_COLORS);
	data = (unsigned char *) ckalloc(bmInfo->bmiHeader.biSizeImage);
	if (!data) {
	    /* printf("Failed to allocate data area for XImage.\n"); */
	    ret_image = NULL;
	    goto cleanup;
	}
	ret_image = XCreateImage(display, NULL, 8, ZPixmap, 0, (char *) data,
		width, height, 8, (int) width);
	if (ret_image == NULL) {
	    ckfree((char *) data);
	    goto cleanup;
	}

	/*
	 * Get the BITMAP info into the Image.
	 */

	if (GetDIBits(hdcMem, hbmp, 0, height, data, bmInfo,
		DIB_PAL_COLORS) == 0) {
	    ckfree((char *) ret_image->data);
	    ckfree((char *) ret_image);
	    ret_image = NULL;
	    goto cleanup;
	}
	p = data;
	palette = (unsigned short *) bmInfo->bmiColors;
	for (i = 0; i < bmInfo->bmiHeader.biSizeImage; i++, p++) {
	    *p = (unsigned char) palette[*p];
	}
    } else if (depth == 16) {
	GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_RGB_COLORS);
	data = (unsigned char *) ckalloc(bmInfo->bmiHeader.biSizeImage);
	if (!data) {
	    /* printf("Failed to allocate data area for XImage.\n"); */
	    ret_image = NULL;
	    goto cleanup;
	}
	ret_image = XCreateImage(display, NULL, 16, ZPixmap, 0, (char *) data,
		width, height, 16, 0 /* will be calc'ed from bitmap_pad */);
	if (ret_image == NULL) {
	    ckfree((char *) data);
	    goto cleanup;
	}

	/*
	 * Get the BITMAP info directly into the Image.
	 */

	if (GetDIBits(hdcMem, hbmp, 0, height, ret_image->data, bmInfo,
		DIB_RGB_COLORS) == 0) {
	    ckfree((char *) ret_image->data);
	    ckfree((char *) ret_image);
	    ret_image = NULL;
	    goto cleanup;
	}
    } else {
	GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_RGB_COLORS);
	data = (unsigned char *) ckalloc(width * height * 4);
	if (!data) {
	    /* printf("Failed to allocate data area for XImage.\n"); */
	    ret_image = NULL;
	    goto cleanup;
	}
	ret_image = XCreateImage(display, NULL, 32, ZPixmap, 0, (char *) data,
		width, height, 0, (int) width * 4);
	if (ret_image == NULL) {
	    ckfree((char *) data);
	    goto cleanup;
	}

	if (depth <= 24) {
	    /*
	     * This used to handle 16 and 24 bpp, but now just handles 24. It
	     * can likely be optimized for that. -- hobbs
	     */

	    unsigned char *smallBitData, *smallBitBase, *bigBitData;
	    unsigned int byte_width, h, w;

	    byte_width = ((width * 3 + 3) & ~(unsigned)3);
	    smallBitBase = (unsigned char *) ckalloc(byte_width * height);
	    if (!smallBitBase) {
		ckfree((char *) ret_image->data);
		ckfree((char *) ret_image);
		ret_image = NULL;
		goto cleanup;
	    }
	    smallBitData = smallBitBase;

	    /*
	     * Get the BITMAP info into the Image.
	     */

	    if (GetDIBits(hdcMem, hbmp, 0, height, smallBitData, bmInfo,
		    DIB_RGB_COLORS) == 0) {
		ckfree((char *) ret_image->data);
		ckfree((char *) ret_image);
		ckfree((char *) smallBitBase);
		ret_image = NULL;
		goto cleanup;
	    }

	    /*
	     * Copy the 24 Bit Pixmap to a 32-Bit one.
	     */

	    for (h = 0; h < height; h++) {
		bigBitData   = (unsigned char *) ret_image->data + h * ret_image->bytes_per_line;
		smallBitData = smallBitBase + h * byte_width;

		for (w = 0; w < width; w++) {
		    *bigBitData++ = ((*smallBitData++));
		    *bigBitData++ = ((*smallBitData++));
		    *bigBitData++ = ((*smallBitData++));
		    *bigBitData++ = 0;
		}
	    }

	    /*
	     * Free the Device contexts, and the Bitmap.
	     */

	    ckfree((char *) smallBitBase);
	} else {
	    /*
	     * Get the BITMAP info directly into the Image.
	     */

	    if (GetDIBits(hdcMem, hbmp, 0, height, ret_image->data, bmInfo,
		    DIB_RGB_COLORS) == 0) {
		ckfree((char *) ret_image->data);
		ckfree((char *) ret_image);
		ret_image = NULL;
		goto cleanup;
	    }
	}
    }

  cleanup:
    if (bmInfo) {
	ckfree((char *) bmInfo);
    }
    if (hPal) {
	SelectPalette(hdcMem, hPalPrev1, FALSE);
    }
    DeleteDC(hdcMem);
    DeleteObject(hbmp);

    return ret_image;
}

/*
 *----------------------------------------------------------------------
 *
 * XGetImage --
 *
 *	This function copies data from a pixmap or window into an XImage.
 *
 * Results:
 *	Returns a newly allocated image containing the data from the given
 *	rectangle of the given drawable.
 *
 * 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)
{
    TkWinDrawable *twdPtr = (TkWinDrawable *)d;
    XImage *imagePtr;
    HDC dc;

    display->request++;

    if (twdPtr == NULL) {
	/*
	 * Avoid unmapped windows or bad drawables
	 */

	return NULL;
    }

    if (twdPtr->type != TWD_BITMAP) {
	/*
	 * This handles TWD_WINDOW or TWD_WINDC, always creating a 32bit
	 * image. If the window being copied isn't visible (unmapped or
	 * obscured), we quietly stop copying (no user error). The user will
	 * see black where the widget should be. This branch is likely
	 * followed in favor of XGetImageZPixmap as postscript printed widgets
	 * require RGB data.
	 */

	TkWinDCState state;
	unsigned int xx, yy, size;
	COLORREF pixel;

	dc = TkWinGetDrawableDC(display, d, &state);

	imagePtr = XCreateImage(display, NULL, 32, format, 0, NULL,
		width, height, 32, 0);
	size = imagePtr->bytes_per_line * imagePtr->height;
	imagePtr->data = ckalloc(size);
	ZeroMemory(imagePtr->data, size);

	for (yy = 0; yy < height; yy++) {
	    for (xx = 0; xx < width; xx++) {
		pixel = GetPixel(dc, x+(int)xx, y+(int)yy);
		if (pixel == CLR_INVALID) {
		    break;
		}
		PutPixel(imagePtr, (int) xx, (int) yy, pixel);
	    }
	}

	TkWinReleaseDrawableDC(d, dc, &state);
    } else if (format == ZPixmap) {
	/*
	 * This actually handles most TWD_WINDOW requests, but it varies from
	 * the above in that it really does a screen capture of an area, which
	 * is consistent with the Unix behavior, but does not appear to handle
	 * all bit depths correctly. -- hobbs
	 */

	imagePtr = XGetImageZPixmap(display, d, x, y,
		width, height, plane_mask, format);
    } else {
	const char *errMsg = NULL;
	char infoBuf[sizeof(BITMAPINFO) + sizeof(RGBQUAD)];
	BITMAPINFO *infoPtr = (BITMAPINFO*)infoBuf;

	if (twdPtr->bitmap.handle == NULL) {
	    errMsg = "XGetImage: not implemented for empty bitmap handles";
	} else if (format != XYPixmap) {
	    errMsg = "XGetImage: not implemented for format != XYPixmap";
	} else if (plane_mask != 1) {
	    errMsg = "XGetImage: not implemented for plane_mask != 1";
	}
	if (errMsg != NULL) {
	    /*
	     * Do a soft warning for the unsupported XGetImage types.
	     */

	    TkpDisplayWarning(errMsg, "XGetImage Failure");
	    return NULL;
	}

	imagePtr = XCreateImage(display, NULL, 1, XYBitmap, 0, NULL,
		width, height, 32, 0);
	imagePtr->data =
		ckalloc((unsigned) imagePtr->bytes_per_line*imagePtr->height);

	dc = GetDC(NULL);

	GetDIBits(dc, twdPtr->bitmap.handle, 0, height, NULL,
		infoPtr, DIB_RGB_COLORS);

	infoPtr->bmiHeader.biSize		= sizeof(BITMAPINFOHEADER);
	infoPtr->bmiHeader.biWidth		= width;
	infoPtr->bmiHeader.biHeight		= -(LONG)height;
	infoPtr->bmiHeader.biPlanes		= 1;
	infoPtr->bmiHeader.biBitCount		= 1;
	infoPtr->bmiHeader.biCompression	= BI_RGB;
	infoPtr->bmiHeader.biSizeImage		= 0;
	infoPtr->bmiHeader.biXPelsPerMeter	= 0;
	infoPtr->bmiHeader.biYPelsPerMeter	= 0;
	infoPtr->bmiHeader.biClrUsed		= 0;
	infoPtr->bmiHeader.biClrImportant	= 0;

	GetDIBits(dc, twdPtr->bitmap.handle, 0, height, imagePtr->data,
		infoPtr, DIB_RGB_COLORS);
	ReleaseDC(NULL, dc);
    }

    return imagePtr;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
@


1.13
log
@eliminate various gcc and msvc compiler warnings
@
text
@d11 1
a11 1
 * RCS: @@(#) $Id: tkWinImage.c,v 1.12 2008/10/17 23:18:38 nijtmans Exp $
d306 1
a306 2
	TkpDisplayWarning(
		"XGetImageZPixmap: only ZPixmap types are implemented",
@


1.12
log
@Add "const" to many internal
const tables, so those will be
put by the C-compiler in the
TEXT segment in stead of the
DATA segment. This makes those
table sharable in shared libraries.
@
text
@d11 1
a11 1
 * RCS: @@(#) $Id: tkWinImage.c,v 1.11 2007/01/12 10:41:23 dkf Exp $
d73 1
a73 1
    unsigned char *srcPtr = &(image->data[(y * image->bytes_per_line)
d121 1
a121 1
    unsigned char *destPtr = &(image->data[(y * image->bytes_per_line)
d373 1
a373 1
	data = ckalloc(bmInfo->bmiHeader.biSizeImage);
d379 1
a379 1
	ret_image = XCreateImage(display, NULL, depth, ZPixmap, 0, data,
d382 1
a382 1
	    ckfree(data);
d409 1
a409 1
	data = ckalloc(bmInfo->bmiHeader.biSizeImage);
d415 1
a415 1
	ret_image = XCreateImage(display, NULL, 8, ZPixmap, 0, data,
d440 1
a440 1
	data = ckalloc(bmInfo->bmiHeader.biSizeImage);
d446 1
a446 1
	ret_image = XCreateImage(display, NULL, 16, ZPixmap, 0, data,
d466 1
a466 1
	data = ckalloc(width * height * 4);
d472 1
a472 1
	ret_image = XCreateImage(display, NULL, 32, ZPixmap, 0, data,
d489 1
a489 1
	    smallBitBase = ckalloc(byte_width * height);
d516 1
a516 1
		bigBitData   = ret_image->data + h * ret_image->bytes_per_line;
@


1.11
log
@More warning squelching (mostly uninit variable warnings)
@
text
@d11 1
a11 1
 * RCS: @@(#) $Id: tkWinImage.c,v 1.10 2007/01/11 15:35:40 dkf Exp $
d644 1
a644 1
	char *errMsg = NULL;
@


1.10
log
@Many minute fixes to reduce number of minor warnings from GCC.
@
text
@d11 1
a11 1
 * RCS: @@(#) $Id: tkWinImage.c,v 1.9 2005/12/02 00:19:04 dkf Exp $
d297 1
a297 1
    HPALETTE hPal, hPalPrev1, hPalPrev2;
d326 1
a326 1
	    UpdateColors (hdcMem);
d331 1
a331 1
	    UpdateColors (hdc);
d342 1
d458 1
a458 1
		    DIB_RGB_COLORS) == 0) {
@


1.9
log
@ANSIfication
@
text
@d11 1
a11 1
 * RCS: @@(#) $Id: tkWinImage.c,v 1.8 2003/10/28 22:52:01 hobbs Exp $
d318 1
a318 1
    hbmp = CreateCompatibleBitmap(hdc, width, height);
d335 1
a335 1
    ret = BitBlt(hdcMem, 0, 0, width, height, hdc, x, y, SRCCOPY);
d354 1
a354 1
    bmInfo = (BITMAPINFO *) ckalloc(size);
d379 1
a379 1
		width, height, 32, ((width + 31) >> 3) & ~1);
d415 1
a415 1
		width, height, 8, width);
d472 1
a472 1
		width, height, 0, width * 4);
d487 1
a487 1
	    byte_width = ((width * 3 + 3) & ~3);
d627 1
a627 1
		PutPixel(imagePtr, xx, yy, pixel);
d665 2
a666 1
	imagePtr->data = ckalloc(imagePtr->bytes_per_line * imagePtr->height);
@


1.8
log
@        * win/tkWinImage.c (XGetImageZPixmap): add separate 16bpp
        XGetImage code to correctly handle 16bpp requests.  This appears
        to never have worked correctly.
@
text
@d1 1
a1 1
/* 
d11 1
a11 1
 * RCS: @@(#) $Id: tkWinImage.c,v 1.7 2003/07/17 01:02:32 hobbs Exp $
d16 4
a19 4
static int		DestroyImage _ANSI_ARGS_((XImage* data));
static unsigned long	ImageGetPixel _ANSI_ARGS_((XImage *image, int x, int y));
static int		PutPixel _ANSI_ARGS_((XImage *image, int x, int y,
			    unsigned long pixel));
d26 2
a27 2
 *	This is a trivial wrapper around ckfree to make it possible to
 *	pass ckfree as a pointer.
d39 2
a40 2
DestroyImage(imagePtr)
     XImage *imagePtr;		/* image to free */
d68 3
a70 3
ImageGetPixel(image, x, y)
    XImage *image;
    int x, y;
d77 18
a94 18
	case 32:
	case 24:
	    pixel = RGB(srcPtr[2], srcPtr[1], srcPtr[0]);
	    break;
	case 16:
	    pixel = RGB(((((WORD*)srcPtr)[0]) >> 7) & 0xf8,
		    ((((WORD*)srcPtr)[0]) >> 2) & 0xf8,
		    ((((WORD*)srcPtr)[0]) << 3) & 0xf8);
	    break;
	case 8:
	    pixel = srcPtr[0];
	    break;
	case 4:
	    pixel = ((x%2) ? (*srcPtr) : ((*srcPtr) >> 4)) & 0x0f;
	    break;
	case 1:
	    pixel = ((*srcPtr) & (0x80 >> (x%8))) ? 1 : 0;
	    break;
d116 4
a119 4
PutPixel(image, x, y, pixel)
    XImage *image;
    int x, y;
    unsigned long pixel;
d125 4
a128 4
	case 32:
	    /*
	     * Pixel is DWORD: 0x00BBGGRR
	     */
d130 5
a134 5
	    destPtr[3] = 0;
	case 24:
	    /*
	     * Pixel is triplet: 0xBBGGRR.
	     */
d136 8
a143 8
	    destPtr[0] = (unsigned char) GetBValue(pixel);
	    destPtr[1] = (unsigned char) GetGValue(pixel);
	    destPtr[2] = (unsigned char) GetRValue(pixel);
	    break;
	case 16:
	    /*
	     * Pixel is WORD: 5-5-5 (R-G-B)
	     */
d145 1
a145 2
	    (*(WORD*)destPtr) = 
		((GetRValue(pixel) & 0xf8) << 7)
d148 12
a159 5
	    break;
	case 8:
	    /*
	     * Pixel is 8-bit index into color table.
	     */
d161 2
a162 8
	    (*destPtr) = (unsigned char) pixel;
	    break;
	case 4:
	    /*
	     * Pixel is 4-bit index in MSBFirst order.
	     */
	    if (x%2) {
		(*destPtr) = (unsigned char) (((*destPtr) & 0xf0)
d164 2
a165 2
	    } else {
		(*destPtr) = (unsigned char) (((*destPtr) & 0x0f)
d167 8
a174 6
	    }
	    break;
	case 1: {
	    /*
	     * Pixel is bit in MSBFirst order.
	     */
d176 4
a179 6
	    int mask = (0x80 >> (x%8));
	    if (pixel) {
		(*destPtr) |= mask;
	    } else {
		(*destPtr) &= ~mask;
	    }
d183 1
d204 11
a214 12
XCreateImage(display, visual, depth, format, offset, data, width, height,
	bitmap_pad, bytes_per_line)
    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;
d258 1
a258 1
    
d264 1
d267 2
a268 2
 *	This function copies data from a pixmap or window into an
 *	XImage.  This handles the ZPixmap case only.
d271 2
a272 2
 *	Returns a newly allocated image containing the data from the
 *	given rectangle of the given drawable.
d277 2
a278 2
 * This procedure is adapted from the XGetImage implementation in TkNT.
 * That code is Copyright (c) 1994 Software Research Associates, Inc.
d284 7
a290 9
XGetImageZPixmap(display, d, x, y, width, height, plane_mask, format)
    Display* display;
    Drawable d;
    int x;
    int y;
    unsigned int width;
    unsigned int height;
    unsigned long plane_mask;
    int	format;
d307 2
a308 2
	    "XGetImageZPixmap: only ZPixmap types are implemented",
	    "XGetImageZPixmap Failure");
d314 4
a317 1
    /* Need to do a Blt operation to copy into a new bitmap */
d323 5
a327 5
        hPalPrev1 = SelectPalette(hdcMem, hPal, FALSE);
        n = RealizePalette(hdcMem);
        if (n > 0) {
            UpdateColors (hdcMem);
        }
d329 4
a332 4
        n = RealizePalette(hdc);
        if (n > 0) {
            UpdateColors (hdc);
        }
d356 11
a366 11
    bmInfo->bmiHeader.biSize               = sizeof(BITMAPINFOHEADER);
    bmInfo->bmiHeader.biWidth              = width;
    bmInfo->bmiHeader.biHeight             = -(int) height;
    bmInfo->bmiHeader.biPlanes             = 1;
    bmInfo->bmiHeader.biBitCount           = depth;
    bmInfo->bmiHeader.biCompression        = BI_RGB;
    bmInfo->bmiHeader.biSizeImage          = 0;
    bmInfo->bmiHeader.biXPelsPerMeter      = 0;
    bmInfo->bmiHeader.biYPelsPerMeter      = 0;
    bmInfo->bmiHeader.biClrUsed            = 0;
    bmInfo->bmiHeader.biClrImportant       = 0;
d370 1
d385 4
a388 1
	/* Get the BITMAP info into the Image. */
d421 4
a424 1
	/* Get the BITMAP info into the Image. */
d452 4
a455 1
	/* Get the BITMAP info directly into the Image. */
d480 2
a481 2
	     * This used to handle 16 and 24 bpp, but now just handles 24.
	     * It can likely be optimized for that. -- hobbs
d483 1
d497 4
a500 1
	    /* Get the BITMAP info into the Image. */
d510 4
a513 1
	    /* Copy the 24 Bit Pixmap to a 32-Bit one. */
d517 1
a517 1
		
d525 5
a529 1
	    /* Free the Device contexts, and the Bitmap */
d532 4
a535 1
	    /* Get the BITMAP info directly into the Image. */
d564 1
a564 2
 *	This function copies data from a pixmap or window into an
 *	XImage.
d567 2
a568 2
 *	Returns a newly allocated image containing the data from the
 *	given rectangle of the given drawable.
d577 7
a583 9
XGetImage(display, d, x, y, width, height, plane_mask, format)
    Display* display;
    Drawable d;
    int x;
    int y;
    unsigned int width;
    unsigned int height;
    unsigned long plane_mask;
    int	format;
d595 1
d602 5
a606 5
	 * image.  If the window being copied isn't visible (unmapped or
	 * obscured), we quietly stop copying (no user error).
	 * The user will see black where the widget should be.
	 * This branch is likely followed in favor of XGetImageZPixmap as
	 * postscript printed widgets require RGB data.
d608 1
d615 2
a616 2
	imagePtr = XCreateImage(display, NULL, 32,
		format, 0, NULL, width, height, 32, 0);
d634 4
a637 4
	 * This actually handles most TWD_WINDOW requests, but it varies
	 * from the above in that it really does a screen capture of
	 * an area, which is consistent with the Unix behavior, but does
	 * not appear to handle all bit depths correctly. -- hobbs
d639 1
d658 1
d691 8
@


1.7
log
@	* win/tkWinImage.c (XGetImage): correct init of biSizeImage in
	bitmap header. [Bug 703697] (cap)
@
text
@d11 1
a11 1
 * RCS: @@(#) $Id: tkWinImage.c,v 1.6 2002/10/10 21:01:18 hobbs Exp $
d428 23
d467 4
@


1.6
log
@	* generic/tkCanvPs.c (TkImageGetColor): corrected bogus use of
	TkColormapData on Windows (Windows now requires RGB pixel data
	from image).
	* win/tkWinImage.c (XGetImage, XGetImageZPixmap): added support
	for generating ps for embedded widgets on canvases on Windows,
	tested for 8, 16, 24 and 32-bit depths (XGetImageZPixmap not used).
@
text
@d11 1
a11 1
 * RCS: @@(#) $Id: tkWinImage.c,v 1.5 2002/10/10 07:25:24 hobbs Exp $
d624 1
a624 1
	infoPtr->bmiHeader.biCompression	= 0;
@


1.6.2.1
log
@	* win/tkWinImage.c (XGetImage): correct init of biSizeImage in
	bitmap header. [Bug 703697] (cap)
@
text
@d11 1
a11 1
 * RCS: @@(#) $Id: tkWinImage.c,v 1.6 2002/10/10 21:01:18 hobbs Exp $
d624 1
a624 1
	infoPtr->bmiHeader.biSizeImage          = 0;
@


1.6.2.2
log
@        * win/tkWinImage.c (XGetImageZPixmap): add separate 16bpp
        XGetImage code to correctly handle 16bpp requests.  This appears
        to never have worked correctly.
@
text
@d11 1
a11 1
 * RCS: @@(#) $Id: tkWinImage.c,v 1.6.2.1 2003/07/17 01:02:47 hobbs Exp $
a427 23
    } else if (depth == 16) {
	GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_RGB_COLORS);
	data = ckalloc(bmInfo->bmiHeader.biSizeImage);
	if (!data) {
	    /* printf("Failed to allocate data area for XImage.\n"); */
	    ret_image = NULL;
	    goto cleanup;
	}
	ret_image = XCreateImage(display, NULL, 16, ZPixmap, 0, data,
		width, height, 16, 0 /* will be calc'ed from bitmap_pad */);
	if (ret_image == NULL) {
	    ckfree((char *) data);
	    goto cleanup;
	}

	/* Get the BITMAP info directly into the Image. */
	if (GetDIBits(hdcMem, hbmp, 0, height, ret_image->data, bmInfo,
		    DIB_RGB_COLORS) == 0) {
	    ckfree((char *) ret_image->data);
	    ckfree((char *) ret_image);
	    ret_image = NULL;
	    goto cleanup;
	}
a443 4
	    /*
	     * This used to handle 16 and 24 bpp, but now just handles 24.
	     * It can likely be optimized for that. -- hobbs
	     */
d459 1
a459 1
			DIB_RGB_COLORS) == 0) {
d466 1
d471 1
a471 1

@


1.5
log
@	* tests/canvPs.test: tests for canvas embedded window ps generation
	* generic/tkCanvWind.c (CanvasPsWindow): removed dead code loop.
	* generic/tkCanvas.h: moved TkColormapData struct to tkCanvPs.c
	* generic/tkCanvPs.c (TkImageGetColor): corrected bogus use of
	TkColormapData on Windows.  Non-separated data may need correction
	as well.
	* win/tkWinImage.c (XGetImage, XGetImageZPixmap): added support
	for generating ps for embedded windows on canvases.
@
text
@d11 1
a11 1
 * RCS: @@(#) $Id: tkWinImage.c,v 1.4 2002/03/26 20:13:39 chengyemao Exp $
a294 1
    unsigned char *smallBitData, *smallBitBase, *bigBitData;
a298 4
    unsigned int byte_width;
    unsigned int h, w, n;
    unsigned char plmr, plmg, plmb;
    unsigned char *data;
d300 1
d302 1
d443 13
a455 9
	byte_width = ((width * 3 + 3) & ~3);
	smallBitBase = ckalloc(byte_width * height);
	if (!smallBitBase) {
	    ckfree((char *) ret_image->data);
	    ckfree((char *) ret_image);
	    ret_image = NULL;
	    goto cleanup;
	}
	smallBitData = smallBitBase;
d457 9
a465 8
	/* Get the BITMAP info into the Image. */
	if (GetDIBits(hdcMem, hbmp, 0, height, smallBitData, bmInfo,
		DIB_RGB_COLORS) == 0) {
	    ckfree((char *) ret_image->data);
	    ckfree((char *) ret_image);
	    ret_image = NULL;
	    goto cleanup;
	}
d467 22
a488 14
	plmr = (unsigned char) (plane_mask & 0xff0000) >> 16;
	plmg = (unsigned char) (plane_mask & 0x00ff00) >> 8;
	plmb = (unsigned char) (plane_mask & 0x0000ff);

	/* Copy the 24 Bit Pixmap to a 32-Bit one. */
	for (h = 0; h < height; h++) {
	    bigBitData = ret_image->data + h * ret_image->bytes_per_line;
	    smallBitData = smallBitBase + h * byte_width;

	    for (w = 0; w < width; w++) {
		*bigBitData++ = ((*smallBitData++)) /* & plmr */;
		*bigBitData++ = ((*smallBitData++)) /* & plmg */;
		*bigBitData++ = ((*smallBitData++)) /* & plmb */;
		*bigBitData++ = 0;
a490 2
	/* Free the Device contexts, and the Bitmap */
	ckfree((char *) smallBitBase);
d548 1
a548 1
    if (format == ZPixmap) {
d550 6
a555 3
	 * This actually handles most TWD_WINDOW requests, but it varies
	 * from the one below in that it really does a screen capture of
	 * an area, but that is consistent with the Unix behavior -- hobbs
a556 11
	imagePtr = XGetImageZPixmap(display, d, x, y,
		width, height, plane_mask, format);
    } else if (twdPtr->type != TWD_BITMAP) {
	/*
	 * This handles TWD_WINDOW or TWD_WINDC.
	 * If the window being copied isn't visible (unmapped or obscured),
	 * we quietly stop copying (no user error).  The user will see black
	 * where the widget should be.
	 * This branch is likely not followed in favor of XGetImageZPixmap.
	 */
	Tk_Window tkwin = (Tk_Window) TkWinGetWinPtr(d);
d563 1
a563 1
	imagePtr = XCreateImage(display, NULL, Tk_Depth(tkwin),
d580 9
@


1.4
log
@Changed bitmap_bit_order to LSBFirst in XCreateImage (bug 481255)
@
text
@d11 1
a11 1
 * RCS: @@(#) $Id: tkWinImage.c,v 1.3 2000/01/06 02:22:51 hobbs Exp $
d264 236
a529 2
    char infoBuf[sizeof(BITMAPINFO) + sizeof(RGBQUAD)];
    BITMAPINFO *infoPtr = (BITMAPINFO*)infoBuf;
d531 7
a537 3
    if ((twdPtr->type != TWD_BITMAP) || (twdPtr->bitmap.handle == NULL)
	    || (format != XYPixmap) || (plane_mask != 1)) {
	panic("XGetImage: not implemented");
d540 38
d579 46
a624 24
    imagePtr = XCreateImage(display, NULL, 1, XYBitmap, 0, NULL,
	    width, height, 32, 0);
    imagePtr->data = ckalloc(imagePtr->bytes_per_line * imagePtr->height);

    dc = GetDC(NULL);

    GetDIBits(dc, twdPtr->bitmap.handle, 0, height, NULL,
	    infoPtr, DIB_RGB_COLORS);

    infoPtr->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    infoPtr->bmiHeader.biWidth = width;
    infoPtr->bmiHeader.biHeight = -(LONG)height;
    infoPtr->bmiHeader.biPlanes = 1;
    infoPtr->bmiHeader.biBitCount = 1;
    infoPtr->bmiHeader.biCompression = BI_RGB;
    infoPtr->bmiHeader.biCompression = 0;
    infoPtr->bmiHeader.biXPelsPerMeter = 0;
    infoPtr->bmiHeader.biYPelsPerMeter = 0;
    infoPtr->bmiHeader.biClrUsed = 0;
    infoPtr->bmiHeader.biClrImportant = 0;

    GetDIBits(dc, twdPtr->bitmap.handle, 0, height, imagePtr->data,
	    infoPtr, DIB_RGB_COLORS);
    ReleaseDC(NULL, dc);
@


1.3
log
@	* win/tkWinImage.c: added static declaration to function
@
text
@d11 1
a11 1
 * RCS: @@(#) $Id: tkWinImage.c,v 1.2 1998/09/14 18:24:00 stanton Exp $
d224 1
a224 1
    imagePtr->bitmap_bit_order = MSBFirst;
@


1.3.2.1
log
@	* generic/tkCanvas.h: moved TkColormapData struct to tkCanvPs.c
	* generic/tkCanvPs.c (TkImageGetColor): corrected bogus use of
	TkColormapData on Windows.  Non-separated data may need correction
	as well.
	* win/tkWinImage.c (XGetImage, XGetImageZPixmap): added support
	for generating ps for embedded windows on canvases.
@
text
@d11 1
a11 1
 * RCS: @@(#) $Id: tkWinImage.c,v 1.3 2000/01/06 02:22:51 hobbs Exp $
d224 1
a224 1
    imagePtr->bitmap_bit_order = LSBFirst;
a263 236
 * XGetImageZPixmap --
 *
 *	This function copies data from a pixmap or window into an
 *	XImage.  This handles the ZPixmap case only.
 *
 * Results:
 *	Returns a newly allocated image containing the data from the
 *	given rectangle of the given drawable.
 *
 * Side effects:
 *	None.
 *
 * This procedure is adapted from the XGetImage implementation in TkNT.
 * That code is Copyright (c) 1994 Software Research Associates, Inc.
 *
 *----------------------------------------------------------------------
 */

static XImage *
XGetImageZPixmap(display, d, x, y, width, height, plane_mask, format)
    Display* display;
    Drawable d;
    int x;
    int y;
    unsigned int width;
    unsigned int height;
    unsigned long plane_mask;
    int	format;
{
    TkWinDrawable *twdPtr = (TkWinDrawable *)d;
    XImage *ret_image;
    unsigned char *smallBitData, *smallBitBase, *bigBitData;
    HDC hdc, hdcMem;
    HBITMAP hbmp, hbmpPrev;
    BITMAPINFO *bmInfo = NULL;
    HPALETTE hPal, hPalPrev1, hPalPrev2;
    unsigned int byte_width;
    unsigned int h, w, n;
    unsigned char plmr, plmg, plmb;
    unsigned char *data;
    int size;
    unsigned int depth;
    TkWinDCState state;
    BOOL ret;

    if (format != ZPixmap) {
	TkpDisplayWarning(
	    "XGetImageZPixmap: only ZPixmap types are implemented",
	    "XGetImageZPixmap Failure");
	return NULL;
    }

    hdc = TkWinGetDrawableDC(display, d, &state);

    /* Need to do a Blt operation to copy into a new bitmap */
    hbmp = CreateCompatibleBitmap(hdc, width, height);
    hdcMem = CreateCompatibleDC(hdc);
    hbmpPrev = SelectObject(hdcMem, hbmp);
    hPal = state.palette;
    if (hPal) {
        hPalPrev1 = SelectPalette(hdcMem, hPal, FALSE);
        n = RealizePalette(hdcMem);
        if (n > 0) {
            UpdateColors (hdcMem);
        }
	hPalPrev2 = SelectPalette(hdc, hPal, FALSE);
        n = RealizePalette(hdc);
        if (n > 0) {
            UpdateColors (hdc);
        }
    }

    ret = BitBlt(hdcMem, 0, 0, width, height, hdc, x, y, SRCCOPY);
    if (hPal) {
	SelectPalette(hdc, hPalPrev2, FALSE);
    }
    SelectObject(hdcMem, hbmpPrev);
    TkWinReleaseDrawableDC(d, hdc, &state);
    if (ret == FALSE) {
	goto cleanup;
    }
    if (twdPtr->type == TWD_WINDOW) {
	depth = Tk_Depth((Tk_Window) twdPtr->window.winPtr);
    } else {
	depth = twdPtr->bitmap.depth;
    }

    size = sizeof(BITMAPINFO);
    if (depth <= 8) {
	size += sizeof(unsigned short) * (1 << depth);
    }
    bmInfo = (BITMAPINFO *) ckalloc(size);

    bmInfo->bmiHeader.biSize               = sizeof(BITMAPINFOHEADER);
    bmInfo->bmiHeader.biWidth              = width;
    bmInfo->bmiHeader.biHeight             = -(int) height;
    bmInfo->bmiHeader.biPlanes             = 1;
    bmInfo->bmiHeader.biBitCount           = depth;
    bmInfo->bmiHeader.biCompression        = BI_RGB;
    bmInfo->bmiHeader.biSizeImage          = 0;
    bmInfo->bmiHeader.biXPelsPerMeter      = 0;
    bmInfo->bmiHeader.biYPelsPerMeter      = 0;
    bmInfo->bmiHeader.biClrUsed            = 0;
    bmInfo->bmiHeader.biClrImportant       = 0;

    if (depth == 1) {
	unsigned char *p, *pend;
	GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_PAL_COLORS);
	data = ckalloc(bmInfo->bmiHeader.biSizeImage);
	if (!data) {
	    /* printf("Failed to allocate data area for XImage.\n"); */
	    ret_image = NULL;
	    goto cleanup;
	}
	ret_image = XCreateImage(display, NULL, depth, ZPixmap, 0, data,
		width, height, 32, ((width + 31) >> 3) & ~1);
	if (ret_image == NULL) {
	    ckfree(data);
	    goto cleanup;
	}

	/* Get the BITMAP info into the Image. */
	if (GetDIBits(hdcMem, hbmp, 0, height, data, bmInfo,
		DIB_PAL_COLORS) == 0) {
	    ckfree((char *) ret_image->data);
	    ckfree((char *) ret_image);
	    ret_image = NULL;
	    goto cleanup;
	}
	p = data;
	pend = data + bmInfo->bmiHeader.biSizeImage;
	while (p < pend) {
	    *p = ~*p;
	    p++;
	}
    } else if (depth == 8) {
	unsigned short *palette;
	unsigned int i;
	unsigned char *p;

	GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_PAL_COLORS);
	data = ckalloc(bmInfo->bmiHeader.biSizeImage);
	if (!data) {
	    /* printf("Failed to allocate data area for XImage.\n"); */
	    ret_image = NULL;
	    goto cleanup;
	}
	ret_image = XCreateImage(display, NULL, 8, ZPixmap, 0, data,
		width, height, 8, width);
	if (ret_image == NULL) {
	    ckfree((char *) data);
	    goto cleanup;
	}

	/* Get the BITMAP info into the Image. */
	if (GetDIBits(hdcMem, hbmp, 0, height, data, bmInfo,
		DIB_PAL_COLORS) == 0) {
	    ckfree((char *) ret_image->data);
	    ckfree((char *) ret_image);
	    ret_image = NULL;
	    goto cleanup;
	}
	p = data;
	palette = (unsigned short *) bmInfo->bmiColors;
	for (i = 0; i < bmInfo->bmiHeader.biSizeImage; i++, p++) {
	    *p = (unsigned char) palette[*p];
	}
    } else {
	GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_RGB_COLORS);
	data = ckalloc(width * height * 4);
	if (!data) {
	    /* printf("Failed to allocate data area for XImage.\n"); */
	    ret_image = NULL;
	    goto cleanup;
	}
	ret_image = XCreateImage(display, NULL, 32, ZPixmap, 0, data,
		width, height, 0, width * 4);
	if (ret_image == NULL) {
	    ckfree((char *) data);
	    goto cleanup;
	}

	byte_width = ((width * 3 + 3) & ~3);
	smallBitBase = ckalloc(byte_width * height);
	if (!smallBitBase) {
	    ckfree((char *) ret_image->data);
	    ckfree((char *) ret_image);
	    ret_image = NULL;
	    goto cleanup;
	}
	smallBitData = smallBitBase;

	/* Get the BITMAP info into the Image. */
	if (GetDIBits(hdcMem, hbmp, 0, height, smallBitData, bmInfo,
		DIB_RGB_COLORS) == 0) {
	    ckfree((char *) ret_image->data);
	    ckfree((char *) ret_image);
	    ret_image = NULL;
	    goto cleanup;
	}

	plmr = (unsigned char) (plane_mask & 0xff0000) >> 16;
	plmg = (unsigned char) (plane_mask & 0x00ff00) >> 8;
	plmb = (unsigned char) (plane_mask & 0x0000ff);

	/* Copy the 24 Bit Pixmap to a 32-Bit one. */
	for (h = 0; h < height; h++) {
	    bigBitData = ret_image->data + h * ret_image->bytes_per_line;
	    smallBitData = smallBitBase + h * byte_width;

	    for (w = 0; w < width; w++) {
		*bigBitData++ = ((*smallBitData++)) /* & plmr */;
		*bigBitData++ = ((*smallBitData++)) /* & plmg */;
		*bigBitData++ = ((*smallBitData++)) /* & plmb */;
		*bigBitData++ = 0;
	    }
	}
	/* Free the Device contexts, and the Bitmap */
	ckfree((char *) smallBitBase);
    }

  cleanup:
    if (bmInfo) {
	ckfree((char *) bmInfo);
    }
    if (hPal) {
	SelectPalette(hdcMem, hPalPrev1, FALSE);
    }
    DeleteDC(hdcMem);
    DeleteObject(hbmp);

    return ret_image;
}

/*
 *----------------------------------------------------------------------
d294 2
d297 3
a299 7
    display->request++;

    if (twdPtr == NULL) {
	/*
	 * Avoid unmapped windows or bad drawables
	 */
	return NULL;
a301 37
    if (format == ZPixmap) {
	/*
	 * This actually handles most TWD_WINDOW requests, but it varies
	 * from the one below in that it really does a screen capture of
	 * an area, but that is consistent with the Unix behavior -- hobbs
	 */
	imagePtr = XGetImageZPixmap(display, d, x, y,
		width, height, plane_mask, format);
    } else if (twdPtr->type != TWD_BITMAP) {
	/*
	 * This handles TWD_WINDOW or TWD_WINDC.
	 * If the window being copied isn't visible (unmapped or obscured),
	 * we quietly stop copying (no user error).  The user will see black
	 * where the widget should be.
	 * This branch is likely not followed in favor of XGetImageZPixmap.
	 */
	TkWinDCState state;
	unsigned int xx, yy, size;
	COLORREF pixel;

	dc = TkWinGetDrawableDC(display, d, &state);

	imagePtr = XCreateImage(display, NULL, (TkWinGetWinPtr(d))->depth,
		format, 0, NULL, width, height, 32, 0);
	size = imagePtr->bytes_per_line * imagePtr->height;
	imagePtr->data = ckalloc(size);
	ZeroMemory(imagePtr->data, size);

	for (yy = 0; yy < height; yy++) {
	    for (xx = 0; xx < width; xx++) {
		pixel = GetPixel(dc, x+(int)xx, y+(int)yy);
		if (pixel == CLR_INVALID) {
		    break;
		}
		PutPixel(imagePtr, xx, yy, pixel);
	    }
	}
d303 24
a326 46
	TkWinReleaseDrawableDC(d, dc, &state);
    } else {
	char *errMsg = NULL;
	char infoBuf[sizeof(BITMAPINFO) + sizeof(RGBQUAD)];
	BITMAPINFO *infoPtr = (BITMAPINFO*)infoBuf;

	if (twdPtr->bitmap.handle == NULL) {
	    errMsg = "XGetImage: not implemented for empty bitmap handles";
	} else if (format != XYPixmap) {
	    errMsg = "XGetImage: not implemented for format != XYPixmap";
	} else if (plane_mask != 1) {
	    errMsg = "XGetImage: not implemented for plane_mask != 1";
	}
	if (errMsg != NULL) {
	    /*
	     * Do a soft warning for the unsupported XGetImage types.
	     */
	    TkpDisplayWarning(errMsg, "XGetImage Failure");
	    return NULL;
	}

	imagePtr = XCreateImage(display, NULL, 1, XYBitmap, 0, NULL,
		width, height, 32, 0);
	imagePtr->data = ckalloc(imagePtr->bytes_per_line * imagePtr->height);

	dc = GetDC(NULL);

	GetDIBits(dc, twdPtr->bitmap.handle, 0, height, NULL,
		infoPtr, DIB_RGB_COLORS);

	infoPtr->bmiHeader.biSize		= sizeof(BITMAPINFOHEADER);
	infoPtr->bmiHeader.biWidth		= width;
	infoPtr->bmiHeader.biHeight		= -(LONG)height;
	infoPtr->bmiHeader.biPlanes		= 1;
	infoPtr->bmiHeader.biBitCount		= 1;
	infoPtr->bmiHeader.biCompression	= BI_RGB;
	infoPtr->bmiHeader.biCompression	= 0;
	infoPtr->bmiHeader.biXPelsPerMeter	= 0;
	infoPtr->bmiHeader.biYPelsPerMeter	= 0;
	infoPtr->bmiHeader.biClrUsed		= 0;
	infoPtr->bmiHeader.biClrImportant	= 0;

	GetDIBits(dc, twdPtr->bitmap.handle, 0, height, imagePtr->data,
		infoPtr, DIB_RGB_COLORS);
	ReleaseDC(NULL, dc);
    }
@


1.3.2.2
log
@	* generic/tkCanvPs.c (TkImageGetColor): corrected bogus use of
	TkColormapData on Windows (Windows now requires RGB pixel data
	from image).
	* win/tkWinImage.c (XGetImage, XGetImageZPixmap): added support
	for generating ps for embedded widgets on canvases on Windows,
	tested for 8, 16, 24 and 32-bit depths (XGetImageZPixmap not used).
@
text
@d11 1
a11 1
 * RCS: @@(#) $Id: tkWinImage.c,v 1.3.2.1 2002/10/10 07:27:12 hobbs Exp $
d295 1
d300 4
a304 1
    unsigned int n;
a305 1
    unsigned char *data;
d446 9
a454 13
	if (depth <= 24) {
	    unsigned char *smallBitData, *smallBitBase, *bigBitData;
	    unsigned int byte_width, h, w;

	    byte_width = ((width * 3 + 3) & ~3);
	    smallBitBase = ckalloc(byte_width * height);
	    if (!smallBitBase) {
		ckfree((char *) ret_image->data);
		ckfree((char *) ret_image);
		ret_image = NULL;
		goto cleanup;
	    }
	    smallBitData = smallBitBase;
d456 8
a463 9
	    /* Get the BITMAP info into the Image. */
	    if (GetDIBits(hdcMem, hbmp, 0, height, smallBitData, bmInfo,
		    DIB_RGB_COLORS) == 0) {
		ckfree((char *) ret_image->data);
		ckfree((char *) ret_image);
		ckfree((char *) smallBitBase);
		ret_image = NULL;
		goto cleanup;
	    }
d465 14
a478 22
	    /* Copy the 24 Bit Pixmap to a 32-Bit one. */
	    for (h = 0; h < height; h++) {
		bigBitData   = ret_image->data + h * ret_image->bytes_per_line;
		smallBitData = smallBitBase + h * byte_width;
		
		for (w = 0; w < width; w++) {
		    *bigBitData++ = ((*smallBitData++));
		    *bigBitData++ = ((*smallBitData++));
		    *bigBitData++ = ((*smallBitData++));
		    *bigBitData++ = 0;
		}
	    }
	    /* Free the Device contexts, and the Bitmap */
	    ckfree((char *) smallBitBase);
	} else {
	    /* Get the BITMAP info directly into the Image. */
	    if (GetDIBits(hdcMem, hbmp, 0, height, ret_image->data, bmInfo,
		    DIB_RGB_COLORS) == 0) {
		ckfree((char *) ret_image->data);
		ckfree((char *) ret_image);
		ret_image = NULL;
		goto cleanup;
d481 2
d540 1
a540 1
    if (twdPtr->type != TWD_BITMAP) {
d542 13
a554 6
	 * This handles TWD_WINDOW or TWD_WINDC, always creating a 32bit
	 * image.  If the window being copied isn't visible (unmapped or
	 * obscured), we quietly stop copying (no user error).
	 * The user will see black where the widget should be.
	 * This branch is likely followed in favor of XGetImageZPixmap as
	 * postscript printed widgets require RGB data.
d562 1
a562 1
	imagePtr = XCreateImage(display, NULL, 32,
a578 9
    } else if (format == ZPixmap) {
	/*
	 * This actually handles most TWD_WINDOW requests, but it varies
	 * from the above in that it really does a screen capture of
	 * an area, which is consistent with the Unix behavior, but does
	 * not appear to handle all bit depths correctly. -- hobbs
	 */
	imagePtr = XGetImageZPixmap(display, d, x, y,
		width, height, plane_mask, format);
@


1.3.8.1
log
@Merging with TOT as of 06/09/2002.
@
text
@d11 1
a11 1
 * RCS: @@(#) $Id$
d224 1
a224 1
    imagePtr->bitmap_bit_order = LSBFirst;
@


1.3.4.1
log
@	* generic/tk.decls:
	* generic/tkInt.decls:
	* generic/tkIntPlatDecls.h:
	* generic/tkPlatDecls.h:
	* generic/tkStubInit.c:
	* win/Makefile.in:
	* win/makefile.vc:
	* win/tkWin3d.c:
	* win/tkWinButton.c:
	* win/tkWinColor.c:
	* win/tkWinDraw.c:
	* win/tkWinFont.c:
	* win/tkWinGdi.c (new):
	* win/tkWinGdi.h (new):
	* win/tkWinImage.c:
	* win/tkWinInt.h:
	* win/tkWinMenu.c:
	* win/tkWinPixmap.c:
	* win/tkWinUtil.c (new):
	* win/tkWinWindow.c:
	* win/tkWinWm.c:
	* win/tkWinX.c:
	* win/winMain.c:
	* xlib/xgc.c:
	* xlib/X11/Xlib.h: first cut at Windows speedup improvements by
	Leo Schubert.  Needs to be streamlined, but the code is correct
	and passes all tests.
@
text
@d11 1
a11 1
 * RCS: @@(#) $Id: tkWinImage.c,v 1.3 2000/01/06 02:22:51 hobbs Exp $
d307 1
a307 1
    dc = TkWinGetNULLDC();
d326 1
a326 1
    TkWinReleaseNULLDC(dc);
@


1.3.4.2
log
@sync with head
@
text
@d11 1
a11 1
 * RCS: @@(#) $Id: tkWinImage.c,v 1.4 2002/03/26 20:13:39 chengyemao Exp $
d224 1
a224 1
    imagePtr->bitmap_bit_order = LSBFirst;
@


1.2
log
@Replaced SCCS strings, fixed binary files
@
text
@d11 1
a11 1
 * RCS: @@(#) $Id$
d38 1
a38 1
int
d67 1
a67 1
unsigned long
@


1.1
log
@Initial revision
@
text
@d11 1
a11 1
 * SCCS: @@(#) tkWinImage.c 1.13 97/07/07 11:19:45
@


1.1.4.1
log
@Merged 8.0.3 changes into 8.1
@
text
@d11 1
a11 1
 * RCS: @@(#) $Id: tkWinImage.c,v 1.2 1998/09/14 18:24:00 stanton Exp $
@


