Tk
view release on metacpan or search on metacpan
pTk/mTk/additions/imgWindow.c view on Meta::CPAN
if (interp && name && (name[0] == '.') && ((name[1] == 0) || islower(UCHAR(name[1])))) {
tkwin = Tk_MainWindow(interp);
if (tkwin == NULL) {
return 0;
}
tkwin = Tk_NameToWindow(interp, name, tkwin);
if (tkwin == NULL) {
*widthPtr = *heightPtr = 0;
return 1;
}
*widthPtr = Tk_Width(tkwin);
*heightPtr = Tk_Height(tkwin);
return 1;
}
return 0;
}
/*
*----------------------------------------------------------------------
*
* ObjReadWin --
*
* This procedure is called by the photo image type to read
* the contents of a window and give it to the photo image.
*
* Results:
* A standard TCL completion code. If TCL_ERROR is returned
* then an error message is left in interp->result.
*
* Side effects:
* new data is added to the image given by imageHandle.
*
*----------------------------------------------------------------------
*/
typedef struct myblock {
Tk_PhotoImageBlock ck;
int dummy; /* extra space for offset[3], in case it is not
included already in Tk_PhotoImageBlock */
} myblock;
#define block bl.ck
static int ObjReadWin(interp, data, format, imageHandle,
destX, destY, width, height, srcX, srcY)
Tcl_Interp *interp;
Tcl_Obj *data;
Tcl_Obj *format;
Tk_PhotoHandle imageHandle;
int destX, destY;
int width, height;
int srcX, srcY;
{
myblock bl;
Tk_Window tkwin;
int fileWidth, fileHeight, i, depth, ncolors, nBytes, x, y;
char *name;
#ifndef __WIN32__
XImage *ximage;
ColormapData cdata;
#else
# undef XGetPixel
# define XGetPixel(P,X,Y) GetPixel(P, X, Y)
TkWinDCState DCi;
HDC ximage;
#endif
Colormap cmap;
Visual *visual;
unsigned char *p;
#ifdef X_GetImage
Tk_ErrorHandler handle;
#endif
int green, blue;
name = ImgGetStringFromObj(data, NULL);
tkwin = Tk_NameToWindow(interp, name, Tk_MainWindow(interp));
if (!tkwin) {
Tcl_AppendResult(interp, "Window \"", name,"\" doesn't exist", (char *) NULL);
return TCL_ERROR;
}
if (!Tk_WindowId(tkwin)) {
Tcl_AppendResult(interp, "Window \"", name,"\" is not mapped", (char *) NULL);
return TCL_ERROR;
}
fileWidth = Tk_Width(tkwin);
fileHeight = Tk_Height(tkwin);
if ((srcX + width) > fileWidth) {
width = fileWidth - srcX;
}
if ((srcY + height) > fileHeight) {
height = fileHeight - srcY;
}
if ((width <= 0) || (height <= 0)) {
return TCL_OK;
}
/*
* If the window is off the screen it will generate an BadMatch/XError
* We catch any BadMatch errors here
*/
#ifdef X_GetImage
handle = Tk_CreateErrorHandler(Tk_Display(tkwin), BadMatch,
X_GetImage, -1, xerrorhandler, (ClientData) tkwin);
#endif
#ifndef __WIN32__
/*
* Generate an XImage from the window. We can then read pixel
* values out of the XImage.
*/
ximage = XGetImage(Tk_Display(tkwin), Tk_WindowId(tkwin), srcX, srcY,
width, height, AllPlanes, ZPixmap);
#ifdef X_GetImage
Tk_DeleteErrorHandler(handle);
#endif
if (ximage == (XImage*) NULL) {
Tcl_AppendResult(interp, "Window \"", name,
"\" cannot be transformed into a pixmap (possibly obscured?)",
(char *) NULL);
return TCL_ERROR;
}
#else
ximage = TkWinGetDrawableDC(Tk_Display(tkwin), Tk_WindowId(tkwin), &DCi);
#endif
depth = Tk_Depth(tkwin);
visual = Tk_Visual(tkwin);
#ifndef __WIN32__
cmap = Tk_Colormap(tkwin);
/*
* Obtain information about the colormap, ie the mapping between
* pixel values and RGB values. The code below should work
* for all Visual types.
*/
ncolors = visual->map_entries;
cdata.colors = (XColor *) ckalloc(sizeof(XColor) * ncolors);
cdata.ncolors = ncolors;
if (visual->class == DirectColor || visual->class == TrueColor) {
cdata.separated = 1;
cdata.red_mask = visual->red_mask;
cdata.green_mask = visual->green_mask;
cdata.blue_mask = visual->blue_mask;
cdata.red_shift = 0;
cdata.green_shift = 0;
cdata.blue_shift = 0;
while ((0x0001 & (cdata.red_mask >> cdata.red_shift)) == 0)
cdata.red_shift ++;
while ((0x0001 & (cdata.green_mask >> cdata.green_shift)) == 0)
cdata.green_shift ++;
while ((0x0001 & (cdata.blue_mask >> cdata.blue_shift)) == 0)
cdata.blue_shift ++;
for (i = 0; i < ncolors; i ++)
cdata.colors[i].pixel =
((i << cdata.red_shift) & cdata.red_mask) |
((i << cdata.green_shift) & cdata.green_mask) |
((i << cdata.blue_shift) & cdata.blue_mask);
} else {
cdata.separated=0;
for (i = 0; i < ncolors; i ++) cdata.colors[i].pixel = i;
}
cdata.color = !(visual->class == StaticGray || visual->class == GrayScale);
XQueryColors(Tk_Display(tkwin), cmap, cdata.colors, ncolors);
#endif
Tk_PhotoExpand(imageHandle, destX + width, destY + height);
block.offset[0] = 0;
block.offset[3] = 0;
#ifndef __WIN32__
if (cdata.color) {
#endif
block.pixelSize = 3;
block.offset[1] = green = 1;
block.offset[2] = blue = 2;
#ifndef __WIN32__
} else {
block.pixelSize = 1;
block.offset[1] = green = 0;
block.offset[2] = blue = 0;
}
#endif
block.width = width;
block.height = height;
block.pitch = block.pixelSize * width;
nBytes = block.pitch * height;
block.pixelPtr = (unsigned char *) ckalloc((unsigned) nBytes);
p = block.pixelPtr;
for (y = 0; y<height; y++) {
for (x = 0; x<width; x++) {
unsigned long pixel = XGetPixel(ximage, x, y);
#ifndef __WIN32__
if (cdata.separated) {
int r = (pixel & cdata.red_mask) >> cdata.red_shift;
p[0] = cdata.colors[r].red >> 8;
if (cdata.color) {
int g = (pixel & cdata.green_mask) >> cdata.green_shift;
int b = (pixel & cdata.blue_mask) >> cdata.blue_shift;
p[1] = cdata.colors[g].green >> 8;
p[2] = cdata.colors[b].blue >> 8;
}
} else {
p[0] = cdata.colors[pixel].red >> 8;
if (cdata.color) {
p[1] = cdata.colors[pixel].green >> 8;
p[2] = cdata.colors[pixel].blue >> 8;
}
}
#else
p[0] = GetRValue(pixel);
p[1] = GetGValue(pixel);
p[2] = GetBValue(pixel);
#endif
p += block.pixelSize;
}
}
Tk_PhotoPutBlock(imageHandle, &block, destX, destY, width, height, TK_PHOTO_COMPOSITE_SET);
#ifndef __WIN32__
XDestroyImage(ximage);
ckfree((char *) cdata.colors);
#else
# undef XGetPixel
TkWinReleaseDrawableDC(Tk_WindowId(tkwin), ximage, &DCi);
#endif
ckfree((char *) block.pixelPtr);
return TCL_OK;
}
( run in 1.309 second using v1.01-cache-2.11-cpan-995e09ba956 )