Import Tk 8.5.15 (as of svn r89086)
This commit is contained in:
698
win/tkWinImage.c
Normal file
698
win/tkWinImage.c
Normal file
@@ -0,0 +1,698 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#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(
|
||||
"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, (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 {
|
||||
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:
|
||||
*/
|
||||
Reference in New Issue
Block a user