1
2 /* $Id: tixUnixXpm.c,v 1.1.1.1 2000/05/17 11:08:54 idiscovery Exp $ */
3
4 /*
5 * tixUnixImgXpm.c --
6 *
7 * Implement the Windows specific function calls for the pixmap
8 * image type.
9 *
10 * Copyright (c) 1996, Expert Interface Technologies
11 *
12 * See the file "license.terms" for information on usage and redistribution
13 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14 *
15 */
16
17 #include "tkInt.h"
18 #include "tixPort.h"
19 #include "tixUnixInt.h"
20 #include "tixImgXpm.h"
21
22 typedef struct PixmapData {
23 Pixmap mask; /* Mask: only display pixmap pixels where
24 * there are 1's here. */
25 GC gc; /* Graphics context for displaying pixmap.
26 * None means there was an error while
27 * setting up the instance, so it cannot
28 * be displayed. */
29 } PixmapData;
30
31
32 /*----------------------------------------------------------------------
33 * TixpInitPixmapInstance --
34 *
35 * Initializes the platform-specific data of a pixmap instance
36 *
37 *----------------------------------------------------------------------
38 */
39
40 void
TixpInitPixmapInstance(masterPtr,instancePtr)41 TixpInitPixmapInstance(masterPtr, instancePtr)
42 PixmapMaster *masterPtr; /* Pointer to master for image. */
43 PixmapInstance *instancePtr;/* The pixmap instance. */
44 {
45 PixmapData * dataPtr;
46
47 dataPtr = (PixmapData *)ckalloc(sizeof(PixmapData));
48 dataPtr->mask = None;
49 dataPtr->gc = None;
50
51 instancePtr->clientData = (ClientData)dataPtr;
52 }
53
54 /*----------------------------------------------------------------------
55 * TixpXpmAllocTmpBuffer --
56 *
57 * Allocate a temporary space to draw the image.
58 *
59 *----------------------------------------------------------------------
60 */
61
62 void
TixpXpmAllocTmpBuffer(masterPtr,instancePtr,imagePtr,maskPtr)63 TixpXpmAllocTmpBuffer(masterPtr, instancePtr, imagePtr, maskPtr)
64 PixmapMaster * masterPtr;
65 PixmapInstance * instancePtr;
66 XImage ** imagePtr;
67 XImage ** maskPtr;
68 {
69 int pad;
70 XImage * image = NULL, * mask = NULL;
71 Display *display = Tk_Display(instancePtr->tkwin);
72 int depth;
73
74 depth = Tk_Depth(instancePtr->tkwin);
75
76 if (depth > 16) {
77 pad = 32;
78 } else if (depth > 8) {
79 pad = 16;
80 } else {
81 pad = 8;
82 }
83
84 /*
85 * Create the XImage structures to store the temporary image
86 */
87 image = XCreateImage(display,
88 Tk_Visual(instancePtr->tkwin),
89 depth, ZPixmap, 0, 0,
90 masterPtr->size[0], masterPtr->size[1], pad, 0);
91 image->data =
92 (char *)ckalloc(image->bytes_per_line * masterPtr->size[1]);
93
94 mask = XCreateImage(display,
95 Tk_Visual(instancePtr->tkwin),
96 1, XYPixmap, 0, 0,
97 masterPtr->size[0], masterPtr->size[1], pad, 0);
98
99 mask->data =
100 (char *)ckalloc(mask->bytes_per_line * masterPtr->size[1]);
101
102 *imagePtr = image;
103 *maskPtr = mask;
104 }
105
106 void
TixpXpmFreeTmpBuffer(masterPtr,instancePtr,image,mask)107 TixpXpmFreeTmpBuffer(masterPtr, instancePtr, image, mask)
108 PixmapMaster * masterPtr;
109 PixmapInstance * instancePtr;
110 XImage * image;
111 XImage * mask;
112 {
113 if (image) {
114 ckfree((char*)image->data);
115 image->data = NULL;
116 XDestroyImage(image);
117 }
118 if (mask) {
119 ckfree((char*)mask->data);
120 mask->data = NULL;
121 XDestroyImage(mask);
122 }
123 }
124
125 /*----------------------------------------------------------------------
126 * TixpXpmSetPixel --
127 *
128 * Sets the pixel at the given (x,y) coordinate to be the given
129 * color.
130 *----------------------------------------------------------------------
131 */
132 void
TixpXpmSetPixel(instancePtr,image,mask,x,y,colorPtr,isTranspPtr)133 TixpXpmSetPixel(instancePtr, image, mask, x, y, colorPtr, isTranspPtr)
134 PixmapInstance * instancePtr;
135 XImage * image;
136 XImage * mask;
137 int x;
138 int y;
139 XColor * colorPtr;
140 int * isTranspPtr;
141 {
142 if (colorPtr != NULL) {
143 XPutPixel(image, x, y, colorPtr->pixel);
144 XPutPixel(mask, x, y, 1);
145 } else {
146 XPutPixel(mask, x, y, 0);
147 *isTranspPtr = 1;
148 }
149 }
150
151 /*----------------------------------------------------------------------
152 * TixpXpmRealizePixmap --
153 *
154 * On Unix: Create the pixmap from the buffer.
155 * On Windows: Free the mask if there are no transparent pixels.
156 *----------------------------------------------------------------------
157 */
158
159 void
TixpXpmRealizePixmap(masterPtr,instancePtr,image,mask,isTransp)160 TixpXpmRealizePixmap(masterPtr, instancePtr, image, mask, isTransp)
161 PixmapMaster * masterPtr;
162 PixmapInstance * instancePtr;
163 XImage * image;
164 XImage * mask;
165 int isTransp;
166 {
167 Display *display = Tk_Display(instancePtr->tkwin);
168 int depth = Tk_Depth(instancePtr->tkwin);
169 PixmapData *dataPtr = (PixmapData*)instancePtr->clientData;
170 unsigned int gcMask;
171 XGCValues gcValues;
172 GC gc;
173
174 instancePtr->pixmap = Tk_GetPixmap(display,
175 Tk_WindowId(instancePtr->tkwin),
176 masterPtr->size[0], masterPtr->size[1], depth);
177
178 gc = Tk_GetGC(instancePtr->tkwin, 0, NULL);
179
180 XPutImage(display, instancePtr->pixmap,
181 gc, image, 0, 0, 0, 0, masterPtr->size[0], masterPtr->size[1]);
182
183 Tk_FreeGC(display, gc);
184
185 if (isTransp) {
186 /*
187 * There are transparent pixels. We need a mask.
188 */
189 dataPtr->mask = Tk_GetPixmap(display,
190 Tk_WindowId(instancePtr->tkwin),
191 masterPtr->size[0], masterPtr->size[1], 1);
192 gc = XCreateGC(display, dataPtr->mask, 0, NULL);
193 XPutImage(display, dataPtr->mask,
194 gc, mask, 0, 0, 0, 0, masterPtr->size[0], masterPtr->size[1]);
195 XFreeGC(display, gc);
196 } else {
197 dataPtr->mask = None;
198 }
199
200 /*
201 * Allocate a GC for drawing this instance (mask is not used if there
202 * is no transparent pixels inside the image).
203 */
204 if (dataPtr->mask != None) {
205 gcMask = GCGraphicsExposures|GCClipMask;
206 } else {
207 gcMask = GCGraphicsExposures;
208 }
209 gcValues.graphics_exposures = False;
210 gcValues.clip_mask = dataPtr->mask;
211
212 gc = Tk_GetGC(instancePtr->tkwin, gcMask, &gcValues);
213 dataPtr->gc = gc;
214 }
215
216 void
TixpXpmFreeInstanceData(instancePtr,delete,display)217 TixpXpmFreeInstanceData(instancePtr, delete, display)
218 PixmapInstance *instancePtr;/* Pixmap instance. */
219 int delete; /* Should the instance data structure
220 * be deleted as well? */
221 Display *display; /* Display containing window that used image.*/
222 {
223 PixmapData *dataPtr = (PixmapData*)instancePtr->clientData;
224
225 if (dataPtr->mask != None) {
226 Tk_FreePixmap(display, dataPtr->mask);
227 dataPtr->mask = None;
228 }
229 if (dataPtr->gc != None) {
230 Tk_FreeGC(display, dataPtr->gc);
231 dataPtr->gc = None;
232 }
233 if (delete) {
234 ckfree((char*)dataPtr);
235 instancePtr->clientData = NULL;
236 }
237 }
238
239 void
TixpXpmDisplay(clientData,display,drawable,imageX,imageY,width,height,drawableX,drawableY)240 TixpXpmDisplay(clientData, display, drawable, imageX, imageY, width,
241 height, drawableX, drawableY)
242 ClientData clientData; /* Pointer to PixmapInstance structure for
243 * for instance to be displayed. */
244 Display *display; /* Display on which to draw image. */
245 Drawable drawable; /* Pixmap or window in which to draw image. */
246 int imageX, imageY; /* Upper-left corner of region within image
247 * to draw. */
248 int width, height; /* Dimensions of region within image to draw.*/
249 int drawableX, drawableY; /* Coordinates within drawable that
250 * correspond to imageX and imageY. */
251 {
252 PixmapInstance *instancePtr = (PixmapInstance *) clientData;
253 PixmapData *dataPtr = (PixmapData*)instancePtr->clientData;
254
255 /*
256 * If there's no graphics context, it means that an error occurred
257 * while creating the image instance so it can't be displayed.
258 */
259 if (dataPtr->gc == None) {
260 return;
261 }
262
263 /*
264 * We always use clipping: modify the clip origin within
265 * the graphics context to line up with the image's origin.
266 * Then draw the image and reset the clip origin.
267 */
268 XSetClipOrigin(display, dataPtr->gc, drawableX - imageX,
269 drawableY - imageY);
270 XCopyArea(display, instancePtr->pixmap, drawable, dataPtr->gc,
271 imageX, imageY, (unsigned) width, (unsigned) height,
272 drawableX, drawableY);
273 XSetClipOrigin(display, dataPtr->gc, 0, 0);
274 }
275