diff options
author | William Joye <wjoye@cfa.harvard.edu> | 2016-10-27 20:28:26 (GMT) |
---|---|---|
committer | William Joye <wjoye@cfa.harvard.edu> | 2016-10-27 20:28:26 (GMT) |
commit | b184baa1234c2143e488d1796ae98afab118b891 (patch) | |
tree | 686b0a47b272296205c7fa2bc789f62a03d20df6 /tkimg/pixmap/pixmapUnix.c | |
parent | f7560d0a451a793441216d76eb4d9475aab61740 (diff) | |
parent | 5aad878400425d3af44433a47c13824385689e1d (diff) | |
download | blt-b184baa1234c2143e488d1796ae98afab118b891.zip blt-b184baa1234c2143e488d1796ae98afab118b891.tar.gz blt-b184baa1234c2143e488d1796ae98afab118b891.tar.bz2 |
Merge commit '5aad878400425d3af44433a47c13824385689e1d' as 'tkimg'
Diffstat (limited to 'tkimg/pixmap/pixmapUnix.c')
-rw-r--r-- | tkimg/pixmap/pixmapUnix.c | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/tkimg/pixmap/pixmapUnix.c b/tkimg/pixmap/pixmapUnix.c new file mode 100644 index 0000000..3be0b87 --- /dev/null +++ b/tkimg/pixmap/pixmapUnix.c @@ -0,0 +1,275 @@ +/* + * tkUnixPmap.c -- + * + * Implement the Unix specific function calls for the pixmap + * image type. + * + * Copyright (c) 1996, Expert Interface Technologies + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + */ + +#include "pixmapInt.h" +#include <stdlib.h> +#include "X11/Xlib.h" +#include "X11/Xutil.h" + +#ifdef MAC_OSX_TK +#define XPutImage +#endif + +typedef struct PixmapData { + Pixmap mask; /* Mask: only display pixmap pixels where + * there are 1's here. */ + GC gc; /* Graphics context for displaying pixmap. + * None means there was an error while + * setting up the instance, so it cannot + * be displayed. */ +} PixmapData; + + +/*---------------------------------------------------------------------- + * TkimgInitPixmapInstance -- + * + * Initializes the platform-specific data of a pixmap instance + * + *---------------------------------------------------------------------- + */ + +void +TkimgInitPixmapInstance(masterPtr, instancePtr) + PixmapMaster *masterPtr; /* Pointer to master for image. */ + PixmapInstance *instancePtr;/* The pixmap instance. */ +{ + PixmapData * dataPtr; + + dataPtr = (PixmapData *)ckalloc(sizeof(PixmapData)); + dataPtr->mask = None; + dataPtr->gc = None; + + instancePtr->clientData = (ClientData)dataPtr; +} + +/*---------------------------------------------------------------------- + * TkimgXpmAllocTmpBuffer -- + * + * Allocate a temporary space to draw the image. + * + *---------------------------------------------------------------------- + */ + +void +TkimgXpmAllocTmpBuffer(masterPtr, instancePtr, imagePtr, maskPtr) + PixmapMaster * masterPtr; + PixmapInstance * instancePtr; + XImage ** imagePtr; + XImage ** maskPtr; +{ + int pad; + XImage * image = NULL, * mask = NULL; + Display *display = Tk_Display(instancePtr->tkwin); + int depth; + + depth = Tk_Depth(instancePtr->tkwin); + + if (depth > 16) { + pad = 32; + } else if (depth > 8) { + pad = 16; + } else { + pad = 8; + } + + /* + * Create the XImage structures to store the temporary image + */ + image = XCreateImage(display, + Tk_Visual(instancePtr->tkwin), + depth, ZPixmap, 0, 0, + masterPtr->size[0], masterPtr->size[1], pad, 0); + image->data = + (char *)ckalloc(image->bytes_per_line * masterPtr->size[1]); + + mask = XCreateImage(display, + Tk_Visual(instancePtr->tkwin), + 1, XYPixmap, 0, 0, + masterPtr->size[0], masterPtr->size[1], pad, 0); + + mask->data = + (char *)ckalloc(mask->bytes_per_line * masterPtr->size[1]); + + *imagePtr = image; + *maskPtr = mask; +} + +void +TkimgXpmFreeTmpBuffer(masterPtr, instancePtr, image, mask) + PixmapMaster * masterPtr; + PixmapInstance * instancePtr; + XImage * image; + XImage * mask; +{ + if (image) { + ckfree((char*)image->data); + image->data = NULL; + XDestroyImage(image); + } + if (mask) { + ckfree((char*)mask->data); + mask->data = NULL; + XDestroyImage(mask); + } +} + +/*---------------------------------------------------------------------- + * TkimgXpmSetPixel -- + * + * Sets the pixel at the given (x,y) coordinate to be the given + * color. + *---------------------------------------------------------------------- + */ +void +TkimgXpmSetPixel(instancePtr, image, mask, x, y, colorPtr, isTranspPtr) + PixmapInstance * instancePtr; + XImage * image; + XImage * mask; + int x; + int y; + XColor * colorPtr; + int * isTranspPtr; +{ + if (colorPtr != NULL) { + XPutPixel(image, x, y, colorPtr->pixel); + XPutPixel(mask, x, y, 1); + } else { + XPutPixel(mask, x, y, 0); + *isTranspPtr = 1; + } +} + +/*---------------------------------------------------------------------- + * TkimgXpmRealizePixmap -- + * + * On Unix: Create the pixmap from the buffer. + * On Windows: Free the mask if there are no transparent pixels. + *---------------------------------------------------------------------- + */ + +void +TkimgXpmRealizePixmap(masterPtr, instancePtr, image, mask, isTransp) + PixmapMaster * masterPtr; + PixmapInstance * instancePtr; + XImage * image; + XImage * mask; + int isTransp; +{ + Display *display = Tk_Display(instancePtr->tkwin); + int depth = Tk_Depth(instancePtr->tkwin); + PixmapData *dataPtr = (PixmapData*)instancePtr->clientData; + unsigned int gcMask; + XGCValues gcValues; + GC gc; + + instancePtr->pixmap = Tk_GetPixmap(display, + Tk_WindowId(instancePtr->tkwin), + masterPtr->size[0], masterPtr->size[1], depth); + + gc = Tk_GetGC(instancePtr->tkwin, 0, NULL); + + XPutImage(display, instancePtr->pixmap, + gc, image, 0, 0, 0, 0, masterPtr->size[0], masterPtr->size[1]); + + Tk_FreeGC(display, gc); + + if (isTransp) { + /* + * There are transparent pixels. We need a mask. + */ + dataPtr->mask = Tk_GetPixmap(display, + Tk_WindowId(instancePtr->tkwin), + masterPtr->size[0], masterPtr->size[1], 1); + gc = XCreateGC(display, dataPtr->mask, 0, NULL); + XPutImage(display, dataPtr->mask, + gc, mask, 0, 0, 0, 0, masterPtr->size[0], masterPtr->size[1]); + XFreeGC(display, gc); + } else { + dataPtr->mask = None; + } + + /* + * Allocate a GC for drawing this instance (mask is not used if there + * is no transparent pixels inside the image). + */ + if (dataPtr->mask != None) { + gcMask = GCGraphicsExposures|GCClipMask; + } else { + gcMask = GCGraphicsExposures; + } + gcValues.graphics_exposures = False; + gcValues.clip_mask = dataPtr->mask; + + gc = Tk_GetGC(instancePtr->tkwin, gcMask, &gcValues); + dataPtr->gc = gc; +} + +void +TkimgXpmFreeInstanceData(instancePtr, delete) + PixmapInstance *instancePtr; /* Pixmap instance. */ + int delete; /* Should the instance data structure + * be deleted as well? */ +{ + PixmapData *dataPtr = (PixmapData*)instancePtr->clientData; + + if (dataPtr->mask != None) { + Tk_FreePixmap(Tk_Display(instancePtr->tkwin), dataPtr->mask); + dataPtr->mask = None; + } + if (dataPtr->gc != None) { + Tk_FreeGC(Tk_Display(instancePtr->tkwin), dataPtr->gc); + dataPtr->gc = None; + } + if (delete) { + ckfree((char*)dataPtr); + instancePtr->clientData = NULL; + } +} + +void +TkimgpXpmDisplay(clientData, display, drawable, imageX, imageY, width, + height, drawableX, drawableY) + ClientData clientData; /* Pointer to PixmapInstance structure for + * for instance to be displayed. */ + Display *display; /* Display on which to draw image. */ + Drawable drawable; /* Pixmap or window in which to draw image. */ + int imageX, imageY; /* Upper-left corner of region within image + * to draw. */ + int width, height; /* Dimensions of region within image to draw.*/ + int drawableX, drawableY; /* Coordinates within drawable that + * correspond to imageX and imageY. */ +{ + PixmapInstance *instancePtr = (PixmapInstance *) clientData; + PixmapData *dataPtr = (PixmapData*)instancePtr->clientData; + + /* + * If there's no graphics context, it means that an error occurred + * while creating the image instance so it can't be displayed. + */ + if (dataPtr->gc == None) { + return; + } + + /* + * We always use clipping: modify the clip origin within + * the graphics context to line up with the image's origin. + * Then draw the image and reset the clip origin. + */ + XSetClipOrigin(display, dataPtr->gc, drawableX - imageX, + drawableY - imageY); + XCopyArea(display, instancePtr->pixmap, drawable, dataPtr->gc, + imageX, imageY, (unsigned) width, (unsigned) height, + drawableX, drawableY); + XSetClipOrigin(display, dataPtr->gc, 0, 0); +} + |