summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhobbs <hobbs>2002-10-10 07:25:23 (GMT)
committerhobbs <hobbs>2002-10-10 07:25:23 (GMT)
commit07bae53a89026d0bc2c8f6635c8586648a52b32e (patch)
tree250461cd6dd036597827c9fd5f9314674f2a8818
parentea99cee25a420695da7bd29c5192575f9d34907d (diff)
downloadtk-07bae53a89026d0bc2c8f6635c8586648a52b32e.zip
tk-07bae53a89026d0bc2c8f6635c8586648a52b32e.tar.gz
tk-07bae53a89026d0bc2c8f6635c8586648a52b32e.tar.bz2
* 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.
-rw-r--r--ChangeLog11
-rw-r--r--generic/tkCanvPs.c50
-rw-r--r--generic/tkCanvWind.c9
-rw-r--r--generic/tkCanvas.h16
-rw-r--r--tests/canvPs.test32
-rw-r--r--win/tkWinImage.c350
6 files changed, 404 insertions, 64 deletions
diff --git a/ChangeLog b/ChangeLog
index 9b8edb7..c371403 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2002-10-10 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * 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.
+
2002-10-09 Jeff Hobbs <jeffh@ActiveState.com>
* unix/README: doc'ed --enable-symbols options.
diff --git a/generic/tkCanvPs.c b/generic/tkCanvPs.c
index 643f2a9..b72ded9 100644
--- a/generic/tkCanvPs.c
+++ b/generic/tkCanvPs.c
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkCanvPs.c,v 1.10 2002/08/05 04:30:38 dgp Exp $
+ * RCS: @(#) $Id: tkCanvPs.c,v 1.11 2002/10/10 07:25:24 hobbs Exp $
*/
#include "tkInt.h"
@@ -23,6 +23,20 @@
*/
/*
+ * The following definition is used in generating postscript for images
+ * and windows.
+ */
+
+typedef struct TkColormapData { /* Hold color information for a window */
+ int separated; /* Whether to use separate color bands */
+ int color; /* Whether window is color or black/white */
+ int ncolors; /* Number of color values stored */
+ XColor *colors; /* Pixel value -> RGB mappings */
+ int red_mask, green_mask, blue_mask; /* Masks and shifts for each */
+ int red_shift, green_shift, blue_shift; /* color band */
+} TkColormapData;
+
+/*
* One of the following structures is created to keep track of Postscript
* output being generated. It consists mostly of information provided on
* the widget command line.
@@ -458,12 +472,13 @@ TkCanvPostscriptCmd(canvasPtr, interp, argc, argv)
/*
* Insert the prolog
*/
- Tcl_AppendResult(interp, Tcl_GetVar(interp,"::tk::ps_preamable",TCL_GLOBAL_ONLY), (char *) NULL);
+ Tcl_AppendResult(interp, Tcl_GetVar(interp,"::tk::ps_preamable",
+ TCL_GLOBAL_ONLY), (char *) NULL);
+
if (psInfo.chan != NULL) {
Tcl_Write(psInfo.chan, Tcl_GetStringResult(interp), -1);
Tcl_ResetResult(canvasPtr->interp);
}
-
/*
*-----------------------------------------------------------
@@ -1118,13 +1133,24 @@ TkImageGetColor(cdata, pixel, red, green, blue)
int r = (pixel & cdata->red_mask) >> cdata->red_shift;
int g = (pixel & cdata->green_mask) >> cdata->green_shift;
int b = (pixel & cdata->blue_mask) >> cdata->blue_shift;
- *red = cdata->colors[r].red / 65535.0;
+#ifdef WIN32
+ /*
+ * Because XQueryColors is an empty stub on Windows, we need
+ * to just make this simple calculation. The TkColormapData
+ * XColor data is otherwise bogus on Windows. -- hobbs
+ */
+ *red = (double)r / 255.0;
+ *green = (double)g / 255.0;
+ *blue = (double)b / 255.0;
+#else
+ *red = cdata->colors[r].red / 65535.0;
*green = cdata->colors[g].green / 65535.0;
- *blue = cdata->colors[b].blue / 65535.0;
+ *blue = cdata->colors[b].blue / 65535.0;
+#endif
} else {
- *red = cdata->colors[pixel].red / 65535.0;
+ *red = cdata->colors[pixel].red / 65535.0;
*green = cdata->colors[pixel].green / 65535.0;
- *blue = cdata->colors[pixel].blue / 65535.0;
+ *blue = cdata->colors[pixel].blue / 65535.0;
}
}
@@ -1218,7 +1244,6 @@ TkPostscriptImage(interp, tkwin, psInfo, ximage, x, y, width, height)
else
cdata.color = 1;
-
XQueryColors(Tk_Display(tkwin), cmap, cdata.colors, ncolors);
/*
@@ -1241,8 +1266,7 @@ TkPostscriptImage(interp, tkwin, psInfo, ximage, x, y, width, height)
* Postscript interpreter).
*/
- switch (level)
- {
+ switch (level) {
case 0: bytesPerLine = (width + 7) / 8; maxWidth = 240000; break;
case 1: bytesPerLine = width; maxWidth = 60000; break;
case 2: bytesPerLine = 3 * width; maxWidth = 20000; break;
@@ -1323,9 +1347,7 @@ TkPostscriptImage(interp, tkwin, psInfo, ximage, x, y, width, height)
TkImageGetColor(&cdata, XGetPixel(ximage, xx, yy),
&red, &green, &blue);
sprintf(buffer, "%02X", (int) floor(0.5 + 255.0 *
- (0.30 * red +
- 0.59 * green +
- 0.11 * blue)));
+ (0.30 * red + 0.59 * green + 0.11 * blue)));
Tcl_AppendResult(interp, buffer, (char *) NULL);
lineLen += 2;
if (lineLen > 60) {
@@ -1340,7 +1362,7 @@ TkPostscriptImage(interp, tkwin, psInfo, ximage, x, y, width, height)
* Finally, color mode. Here, just output the red, green,
* and blue values directly.
*/
- for (xx = x; xx < x+width; xx++) {
+ for (xx = x; xx < x+width; xx++) {
TkImageGetColor(&cdata, XGetPixel(ximage, xx, yy),
&red, &green, &blue);
sprintf(buffer, "%02X%02X%02X",
diff --git a/generic/tkCanvWind.c b/generic/tkCanvWind.c
index c197584..b82efa1 100644
--- a/generic/tkCanvWind.c
+++ b/generic/tkCanvWind.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkCanvWind.c,v 1.7 2002/08/05 04:30:38 dgp Exp $
+ * RCS: @(#) $Id: tkCanvWind.c,v 1.8 2002/10/10 07:25:24 hobbs Exp $
*/
#include <stdio.h>
@@ -845,7 +845,6 @@ CanvasPsWindow(interp, tkwin, canvas, x, y, width, height)
int width, height; /* width/height of window. */
{
char buffer[256];
- TkWindow *winPtr;
XImage *ximage;
int result;
Tcl_DString buffer1, buffer2;
@@ -885,12 +884,6 @@ CanvasPsWindow(interp, tkwin, canvas, x, y, width, height)
(char *) NULL);
Tcl_DStringFree(&buffer1);
- for (winPtr = ((TkWindow *) tkwin)->childList; winPtr != NULL;
- winPtr = winPtr->nextPtr) {
- if (Tk_IsMapped(winPtr)) {
-/* printf("child window: %s\n", winPtr->pathName);*/
- }
- }
return result;
}
Tcl_DStringFree(&buffer1);
diff --git a/generic/tkCanvas.h b/generic/tkCanvas.h
index 70cb03d..cb601a9 100644
--- a/generic/tkCanvas.h
+++ b/generic/tkCanvas.h
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkCanvas.h,v 1.5 2002/08/05 04:30:38 dgp Exp $
+ * RCS: @(#) $Id: tkCanvas.h,v 1.6 2002/10/10 07:25:24 hobbs Exp $
*/
#ifndef _TKCANVAS
@@ -295,18 +295,4 @@ typedef struct TkCanvas {
extern int TkCanvPostscriptCmd _ANSI_ARGS_((TkCanvas *canvasPtr,
Tcl_Interp *interp, int argc, CONST char **argv));
-/*
- * The following definition is shared between tkCanvPs.c and tkCanvImg.c,
- * and is used in generating postscript for images and windows.
- */
-
-typedef struct TkColormapData { /* Hold color information for a window */
- int separated; /* Whether to use separate color bands */
- int color; /* Whether window is color or black/white */
- int ncolors; /* Number of color values stored */
- XColor *colors; /* Pixel value -> RGB mappings */
- int red_mask, green_mask, blue_mask; /* Masks and shifts for each */
- int red_shift, green_shift, blue_shift; /* color band */
-} TkColormapData;
-
#endif /* _TKCANVAS */
diff --git a/tests/canvPs.test b/tests/canvPs.test
index 8faad75..8ab93a0 100644
--- a/tests/canvPs.test
+++ b/tests/canvPs.test
@@ -6,7 +6,7 @@
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.
#
-# RCS: @(#) $Id: canvPs.test,v 1.4 2002/07/14 05:48:46 dgp Exp $
+# RCS: @(#) $Id: canvPs.test,v 1.5 2002/10/10 07:25:24 hobbs Exp $
package require tcltest 2.1
namespace import -force tcltest::configure
@@ -94,6 +94,36 @@ test canvPs-2.4 {test writing to channel and file, same output} {pcOnly} {
set status
} ok
+test canvPs-3.1 {test ps generation with an embedded window} {} {
+ removeFile bar.ps
+ destroy .c
+ pack [canvas .c -width 200 -height 200 -background white]
+ .c create rect 20 20 150 150 -tags rect0 -dash . -width 2
+ .c create arc 0 50 200 200 -tags arc0 \
+ -dash {4 4} -stipple question -outline red -fill green
+
+ image create photo logo \
+ -file [file join $tk_library images pwrdLogo150.gif]
+ .c create image 200 50 -image logo -anchor nw
+
+ entry .c.e -background pink -foreground blue -width 14
+ .c.e insert 0 "we gonna be postscripted"
+ .c create window 50 180 -anchor nw -window .c.e
+ update
+ .c postscript -file bar.ps
+ file exists bar.ps
+} 1
+test canvPs-3.2 {test ps generation with an embedded window not mapped} {} {
+ removeFile bar.ps
+ destroy .c
+ pack [canvas .c -width 200 -height 200 -background white]
+ entry .c.e -background pink -foreground blue -width 14
+ .c.e insert 0 "we gonna be postscripted"
+ .c create window 50 180 -anchor nw -window .c.e
+ .c postscript -file bar.ps
+ file exists bar.ps
+} 1
+
# cleanup
removeFile foo.ps
removeFile bar.ps
diff --git a/win/tkWinImage.c b/win/tkWinImage.c
index e4a153b..32b2ecb 100644
--- a/win/tkWinImage.c
+++ b/win/tkWinImage.c
@@ -8,7 +8,7 @@
* 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.4 2002/03/26 20:13:39 chengyemao Exp $
+ * RCS: @(#) $Id: tkWinImage.c,v 1.5 2002/10/10 07:25:24 hobbs Exp $
*/
#include "tkWinInt.h"
@@ -261,6 +261,242 @@ XCreateImage(display, visual, depth, format, offset, data, width, height,
/*
*----------------------------------------------------------------------
+ * 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;
+}
+
+/*
+ *----------------------------------------------------------------------
*
* XGetImage --
*
@@ -291,39 +527,101 @@ XGetImage(display, d, x, y, width, height, plane_mask, format)
TkWinDrawable *twdPtr = (TkWinDrawable *)d;
XImage *imagePtr;
HDC dc;
- char infoBuf[sizeof(BITMAPINFO) + sizeof(RGBQUAD)];
- BITMAPINFO *infoPtr = (BITMAPINFO*)infoBuf;
- if ((twdPtr->type != TWD_BITMAP) || (twdPtr->bitmap.handle == NULL)
- || (format != XYPixmap) || (plane_mask != 1)) {
- panic("XGetImage: not implemented");
+ display->request++;
+
+ if (twdPtr == NULL) {
+ /*
+ * Avoid unmapped windows or bad drawables
+ */
+ return NULL;
}
+ 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.
+ */
+ Tk_Window tkwin = (Tk_Window) TkWinGetWinPtr(d);
+ TkWinDCState state;
+ unsigned int xx, yy, size;
+ COLORREF pixel;
- imagePtr = XCreateImage(display, NULL, 1, XYBitmap, 0, NULL,
- width, height, 32, 0);
- imagePtr->data = ckalloc(imagePtr->bytes_per_line * imagePtr->height);
+ dc = TkWinGetDrawableDC(display, d, &state);
- dc = GetDC(NULL);
+ imagePtr = XCreateImage(display, NULL, Tk_Depth(tkwin),
+ format, 0, NULL, width, height, 32, 0);
+ size = imagePtr->bytes_per_line * imagePtr->height;
+ imagePtr->data = ckalloc(size);
+ ZeroMemory(imagePtr->data, size);
- GetDIBits(dc, twdPtr->bitmap.handle, 0, height, NULL,
- infoPtr, DIB_RGB_COLORS);
+ 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);
+ }
+ }
- 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;
+ TkWinReleaseDrawableDC(d, dc, &state);
+ } else {
+ char *errMsg = NULL;
+ char infoBuf[sizeof(BITMAPINFO) + sizeof(RGBQUAD)];
+ BITMAPINFO *infoPtr = (BITMAPINFO*)infoBuf;
- GetDIBits(dc, twdPtr->bitmap.handle, 0, height, imagePtr->data,
- infoPtr, DIB_RGB_COLORS);
- ReleaseDC(NULL, dc);
+ 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);
+ }
return imagePtr;
}