1a966c04fSmrg/*
2a966c04fSmrg * Copyright (C) 1989-95 GROUPE BULL
3a966c04fSmrg *
4a966c04fSmrg * Permission is hereby granted, free of charge, to any person obtaining a copy
5a966c04fSmrg * of this software and associated documentation files (the "Software"), to
6a966c04fSmrg * deal in the Software without restriction, including without limitation the
7a966c04fSmrg * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8a966c04fSmrg * sell copies of the Software, and to permit persons to whom the Software is
9a966c04fSmrg * furnished to do so, subject to the following conditions:
10a966c04fSmrg *
11a966c04fSmrg * The above copyright notice and this permission notice shall be included in
12a966c04fSmrg * all copies or substantial portions of the Software.
13a966c04fSmrg *
14a966c04fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15a966c04fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16a966c04fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17a966c04fSmrg * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18a966c04fSmrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19a966c04fSmrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20a966c04fSmrg *
21a966c04fSmrg * Except as contained in this notice, the name of GROUPE BULL shall not be
22a966c04fSmrg * used in advertising or otherwise to promote the sale, use or other dealings
23a966c04fSmrg * in this Software without prior written authorization from GROUPE BULL.
24a966c04fSmrg */
25a966c04fSmrg
26a966c04fSmrg/*****************************************************************************\
27a966c04fSmrg* Attrib.c:                                                                   *
28a966c04fSmrg*                                                                             *
29a966c04fSmrg*  XPM library                                                                *
30a966c04fSmrg*  Functions related to the XpmAttributes structure                           *
31a966c04fSmrg*                                                                             *
32a966c04fSmrg*  Developed by Arnaud Le Hors                                                *
33a966c04fSmrg\*****************************************************************************/
34a966c04fSmrg
35a966c04fSmrg/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
36a966c04fSmrg
37a966c04fSmrg#ifdef HAVE_CONFIG_H
38a966c04fSmrg#include <config.h>
39a966c04fSmrg#endif
40a966c04fSmrg#include "XpmI.h"
41a966c04fSmrg
42a966c04fSmrg/* 3.2 backward compatibility code */
43a966c04fSmrgLFUNC(CreateOldColorTable, int, (XpmColor *ct, unsigned int ncolors,
44a966c04fSmrg				 XpmColor ***oldct));
45a966c04fSmrg
46a966c04fSmrgLFUNC(FreeOldColorTable, void, (XpmColor **colorTable, unsigned int ncolors));
47a966c04fSmrg
48a966c04fSmrg/*
49a966c04fSmrg * Create a colortable compatible with the old style colortable
50a966c04fSmrg */
51a966c04fSmrgstatic int
522e2dd055SmrgCreateOldColorTable(
532e2dd055Smrg    XpmColor	  *ct,
542e2dd055Smrg    unsigned int   ncolors,
552e2dd055Smrg    XpmColor	***oldct)
56a966c04fSmrg{
57a966c04fSmrg    XpmColor **colorTable, **color;
58a966c04fSmrg    unsigned int a;
59a966c04fSmrg
6097cf2ee2Smrg    if (ncolors >= UINT_MAX / sizeof(XpmColor *))
61a966c04fSmrg	return XpmNoMemory;
62a966c04fSmrg
63a966c04fSmrg    colorTable = (XpmColor **) XpmMalloc(ncolors * sizeof(XpmColor *));
64a966c04fSmrg    if (!colorTable) {
65a966c04fSmrg	*oldct = NULL;
66a966c04fSmrg	return (XpmNoMemory);
67a966c04fSmrg    }
68a966c04fSmrg    for (a = 0, color = colorTable; a < ncolors; a++, color++, ct++)
69a966c04fSmrg	*color = ct;
70a966c04fSmrg    *oldct = colorTable;
71a966c04fSmrg    return (XpmSuccess);
72a966c04fSmrg}
73a966c04fSmrg
74a966c04fSmrgstatic void
752e2dd055SmrgFreeOldColorTable(
762e2dd055Smrg    XpmColor	**colorTable,
772e2dd055Smrg    unsigned int  ncolors)
78a966c04fSmrg{
79a966c04fSmrg    unsigned int a, b;
80a966c04fSmrg    XpmColor **color;
81a966c04fSmrg    char **sptr;
82a966c04fSmrg
83a966c04fSmrg    if (colorTable) {
84a966c04fSmrg	for (a = 0, color = colorTable; a < ncolors; a++, color++) {
85a966c04fSmrg	    for (b = 0, sptr = (char **) *color; b <= NKEYS; b++, sptr++)
86a966c04fSmrg		if (*sptr)
87a966c04fSmrg		    XpmFree(*sptr);
88a966c04fSmrg	}
89a966c04fSmrg	XpmFree(*colorTable);
90a966c04fSmrg	XpmFree(colorTable);
91a966c04fSmrg    }
92a966c04fSmrg}
93a966c04fSmrg
94a966c04fSmrg/* end 3.2 bc */
95a966c04fSmrg
96a966c04fSmrg/*
97a966c04fSmrg * Free the computed color table
98a966c04fSmrg */
99a966c04fSmrgvoid
1002e2dd055SmrgxpmFreeColorTable(
1012e2dd055Smrg    XpmColor	*colorTable,
1022e2dd055Smrg    int		 ncolors)
103a966c04fSmrg{
104a966c04fSmrg    int a, b;
105a966c04fSmrg    XpmColor *color;
106a966c04fSmrg    char **sptr;
107a966c04fSmrg
108a966c04fSmrg    if (colorTable) {
109a966c04fSmrg	for (a = 0, color = colorTable; a < ncolors; a++, color++) {
110a966c04fSmrg	    for (b = 0, sptr = (char **) color; b <= NKEYS; b++, sptr++)
111a966c04fSmrg		if (*sptr)
112a966c04fSmrg		    XpmFree(*sptr);
113a966c04fSmrg	}
114a966c04fSmrg	XpmFree(colorTable);
115a966c04fSmrg    }
116a966c04fSmrg}
117a966c04fSmrg
118a966c04fSmrg/*
119a966c04fSmrg * Free array of extensions
120a966c04fSmrg */
121a966c04fSmrgvoid
1222e2dd055SmrgXpmFreeExtensions(
1232e2dd055Smrg    XpmExtension	*extensions,
1242e2dd055Smrg    int			 nextensions)
125a966c04fSmrg{
126a966c04fSmrg    unsigned int i, j, nlines;
127a966c04fSmrg    XpmExtension *ext;
128a966c04fSmrg    char **sptr;
129a966c04fSmrg
130a966c04fSmrg    if (extensions  && nextensions > 0) {
131a966c04fSmrg	for (i = 0, ext = extensions; i < nextensions; i++, ext++) {
132a966c04fSmrg	    if (ext->name)
133a966c04fSmrg		XpmFree(ext->name);
134a966c04fSmrg	    nlines = ext->nlines;
135a966c04fSmrg	    for (j = 0, sptr = ext->lines; j < nlines; j++, sptr++)
136a966c04fSmrg		if (sptr && *sptr)
137a966c04fSmrg		    XpmFree(*sptr);
138a966c04fSmrg	    if (ext->lines)
139a966c04fSmrg		XpmFree(ext->lines);
140a966c04fSmrg	}
141a966c04fSmrg	XpmFree(extensions);
142a966c04fSmrg    }
143a966c04fSmrg}
144a966c04fSmrg
145a966c04fSmrg/*
146a966c04fSmrg * Return the XpmAttributes structure size
147a966c04fSmrg */
148a966c04fSmrg
149a966c04fSmrgint
1502e2dd055SmrgXpmAttributesSize(void)
151a966c04fSmrg{
152a966c04fSmrg    return sizeof(XpmAttributes);
153a966c04fSmrg}
154a966c04fSmrg
155a966c04fSmrg/*
156a966c04fSmrg * Init returned data to free safely later on
157a966c04fSmrg */
158a966c04fSmrgvoid
1592e2dd055SmrgxpmInitAttributes(XpmAttributes *attributes)
160a966c04fSmrg{
161a966c04fSmrg    if (attributes) {
162a966c04fSmrg	attributes->pixels = NULL;
163a966c04fSmrg	attributes->npixels = 0;
164a966c04fSmrg	attributes->colorTable = NULL;
165a966c04fSmrg	attributes->ncolors = 0;
166a966c04fSmrg/* 3.2 backward compatibility code */
167a966c04fSmrg	attributes->hints_cmt = NULL;
168a966c04fSmrg	attributes->colors_cmt = NULL;
169a966c04fSmrg	attributes->pixels_cmt = NULL;
170a966c04fSmrg/* end 3.2 bc */
171a966c04fSmrg	if (attributes->valuemask & XpmReturnExtensions) {
172a966c04fSmrg	    attributes->extensions = NULL;
173a966c04fSmrg	    attributes->nextensions = 0;
174a966c04fSmrg	}
175a966c04fSmrg	if (attributes->valuemask & XpmReturnAllocPixels) {
176a966c04fSmrg	    attributes->alloc_pixels = NULL;
177a966c04fSmrg	    attributes->nalloc_pixels = 0;
178a966c04fSmrg	}
179a966c04fSmrg    }
180a966c04fSmrg}
181a966c04fSmrg
182a966c04fSmrg/*
183a966c04fSmrg * Fill in the XpmAttributes with the XpmImage and the XpmInfo
184a966c04fSmrg */
185a966c04fSmrgvoid
1862e2dd055SmrgxpmSetAttributes(
1872e2dd055Smrg    XpmAttributes	*attributes,
1882e2dd055Smrg    XpmImage		*image,
1892e2dd055Smrg    XpmInfo		*info)
190a966c04fSmrg{
191a966c04fSmrg    if (attributes->valuemask & XpmReturnColorTable) {
192a966c04fSmrg	attributes->colorTable = image->colorTable;
193a966c04fSmrg	attributes->ncolors = image->ncolors;
194a966c04fSmrg
195a966c04fSmrg	/* avoid deletion of copied data */
196a966c04fSmrg	image->ncolors = 0;
197a966c04fSmrg	image->colorTable = NULL;
198a966c04fSmrg    }
199a966c04fSmrg/* 3.2 backward compatibility code */
200a966c04fSmrg    else if (attributes->valuemask & XpmReturnInfos) {
201a966c04fSmrg	int ErrorStatus;
202a966c04fSmrg
203a966c04fSmrg	ErrorStatus = CreateOldColorTable(image->colorTable, image->ncolors,
204a966c04fSmrg					  (XpmColor ***)
205a966c04fSmrg					  &attributes->colorTable);
206a966c04fSmrg
207a966c04fSmrg	/* if error just say we can't return requested data */
208a966c04fSmrg	if (ErrorStatus != XpmSuccess) {
209a966c04fSmrg	    attributes->valuemask &= ~XpmReturnInfos;
210a966c04fSmrg	    if (!(attributes->valuemask & XpmReturnPixels)) {
211a966c04fSmrg		XpmFree(attributes->pixels);
212a966c04fSmrg		attributes->pixels = NULL;
213a966c04fSmrg		attributes->npixels = 0;
214a966c04fSmrg	    }
215a966c04fSmrg	    attributes->ncolors = 0;
216a966c04fSmrg	} else {
217a966c04fSmrg	    attributes->ncolors = image->ncolors;
218a966c04fSmrg	    attributes->hints_cmt = info->hints_cmt;
219a966c04fSmrg	    attributes->colors_cmt = info->colors_cmt;
220a966c04fSmrg	    attributes->pixels_cmt = info->pixels_cmt;
221a966c04fSmrg
222a966c04fSmrg	    /* avoid deletion of copied data */
223a966c04fSmrg	    image->ncolors = 0;
224a966c04fSmrg	    image->colorTable = NULL;
225a966c04fSmrg	    info->hints_cmt = NULL;
226a966c04fSmrg	    info->colors_cmt = NULL;
227a966c04fSmrg	    info->pixels_cmt = NULL;
228a966c04fSmrg	}
229a966c04fSmrg    }
230a966c04fSmrg/* end 3.2 bc */
231a966c04fSmrg    if (attributes->valuemask & XpmReturnExtensions) {
232a966c04fSmrg	attributes->extensions = info->extensions;
233a966c04fSmrg	attributes->nextensions = info->nextensions;
234a966c04fSmrg
235a966c04fSmrg	/* avoid deletion of copied data */
236a966c04fSmrg	info->extensions = NULL;
237a966c04fSmrg	info->nextensions = 0;
238a966c04fSmrg    }
239a966c04fSmrg    if (info->valuemask & XpmHotspot) {
240a966c04fSmrg	attributes->valuemask |= XpmHotspot;
241a966c04fSmrg	attributes->x_hotspot = info->x_hotspot;
242a966c04fSmrg	attributes->y_hotspot = info->y_hotspot;
243a966c04fSmrg    }
244a966c04fSmrg    attributes->valuemask |= XpmCharsPerPixel;
245a966c04fSmrg    attributes->cpp = image->cpp;
246a966c04fSmrg    attributes->valuemask |= XpmSize;
247a966c04fSmrg    attributes->width = image->width;
248a966c04fSmrg    attributes->height = image->height;
249a966c04fSmrg}
250a966c04fSmrg
251a966c04fSmrg/*
252a966c04fSmrg * Free the XpmAttributes structure members
253a966c04fSmrg * but the structure itself
254a966c04fSmrg */
255a966c04fSmrgvoid
2562e2dd055SmrgXpmFreeAttributes(XpmAttributes *attributes)
257a966c04fSmrg{
258a966c04fSmrg    if (attributes->valuemask & XpmReturnPixels && attributes->npixels) {
259a966c04fSmrg	XpmFree(attributes->pixels);
260a966c04fSmrg	attributes->pixels = NULL;
261a966c04fSmrg	attributes->npixels = 0;
262a966c04fSmrg    }
263a966c04fSmrg    if (attributes->valuemask & XpmReturnColorTable) {
264a966c04fSmrg	xpmFreeColorTable(attributes->colorTable, attributes->ncolors);
265a966c04fSmrg	attributes->colorTable = NULL;
266a966c04fSmrg	attributes->ncolors = 0;
267a966c04fSmrg    }
268a966c04fSmrg/* 3.2 backward compatibility code */
269a966c04fSmrg    else if (attributes->valuemask & XpmInfos) {
270a966c04fSmrg	if (attributes->colorTable) {
271a966c04fSmrg	    FreeOldColorTable((XpmColor **) attributes->colorTable,
272a966c04fSmrg			      attributes->ncolors);
273a966c04fSmrg	    attributes->colorTable = NULL;
274a966c04fSmrg	    attributes->ncolors = 0;
275a966c04fSmrg	}
276a966c04fSmrg	if (attributes->hints_cmt) {
277a966c04fSmrg	    XpmFree(attributes->hints_cmt);
278a966c04fSmrg	    attributes->hints_cmt = NULL;
279a966c04fSmrg	}
280a966c04fSmrg	if (attributes->colors_cmt) {
281a966c04fSmrg	    XpmFree(attributes->colors_cmt);
282a966c04fSmrg	    attributes->colors_cmt = NULL;
283a966c04fSmrg	}
284a966c04fSmrg	if (attributes->pixels_cmt) {
285a966c04fSmrg	    XpmFree(attributes->pixels_cmt);
286a966c04fSmrg	    attributes->pixels_cmt = NULL;
287a966c04fSmrg	}
288a966c04fSmrg	if (attributes->pixels) {
289a966c04fSmrg	    XpmFree(attributes->pixels);
290a966c04fSmrg	    attributes->pixels = NULL;
291a966c04fSmrg	    attributes->npixels = 0;
292a966c04fSmrg	}
293a966c04fSmrg    }
294a966c04fSmrg/* end 3.2 bc */
295a966c04fSmrg    if (attributes->valuemask & XpmReturnExtensions
296a966c04fSmrg	&& attributes->nextensions) {
297a966c04fSmrg	XpmFreeExtensions(attributes->extensions, attributes->nextensions);
298a966c04fSmrg	attributes->extensions = NULL;
299a966c04fSmrg	attributes->nextensions = 0;
300a966c04fSmrg    }
301a966c04fSmrg    if (attributes->valuemask & XpmReturnAllocPixels
302a966c04fSmrg	&& attributes->nalloc_pixels) {
303a966c04fSmrg	XpmFree(attributes->alloc_pixels);
304a966c04fSmrg	attributes->alloc_pixels = NULL;
305a966c04fSmrg	attributes->nalloc_pixels = 0;
306a966c04fSmrg    }
307a966c04fSmrg    attributes->valuemask = 0;
308a966c04fSmrg}
309