]> git.saurik.com Git - wxWidgets.git/blob - src/xpm/misc.c
This is the way to go (well, close enough).
[wxWidgets.git] / src / xpm / misc.c
1 /*
2 * Copyright (C) 1989-94 GROUPE BULL
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to
6 * deal in the Software without restriction, including without limitation the
7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 * sell copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 *
21 * Except as contained in this notice, the name of GROUPE BULL shall not be
22 * used in advertising or otherwise to promote the sale, use or other dealings
23 * in this Software without prior written authorization from GROUPE BULL.
24 */
25
26 /*****************************************************************************\
27 * misc.c: *
28 * *
29 * XPM library *
30 * Miscellaneous utilities *
31 * *
32 * Developed by Arnaud Le Hors *
33 \*****************************************************************************/
34
35 /*
36 * The code related to FOR_MSW has been added by
37 * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
38 */
39
40 #include "xpm34p.h"
41 #ifdef VMS
42 #include "sys$library:stat.h"
43 #include "sys$library:fcntl.h"
44 #else
45 #include <sys/types.h>
46 #include <sys/stat.h>
47 #include <fcntl.h>
48 #include <stdio.h>
49 #ifdef FOR_MSW
50 #include <io.h>
51 #else
52 #include <unistd.h>
53 #endif
54 #endif
55
56 /* 3.2 backward compatibility code */
57 LFUNC(CreateOldColorTable, int, (XpmColor *ct, int ncolors,
58 XpmColor ***oldct));
59
60 LFUNC(FreeOldColorTable, void, (XpmColor **colorTable, int ncolors));
61
62 /*
63 * Create a colortable compatible with the old style colortable
64 */
65 static int
66 CreateOldColorTable(XpmColor *ct, int ncolors, XpmColor ***oldct)
67 {
68 XpmColor **colorTable, **color;
69 int a;
70
71 colorTable = (XpmColor **) XpmMalloc(ncolors * sizeof(XpmColor *));
72 if (!colorTable) {
73 *oldct = NULL;
74 return (XpmNoMemory);
75 }
76 for (a = 0, color = colorTable; a < ncolors; a++, color++, ct++)
77 *color = ct;
78 *oldct = colorTable;
79 return (XpmSuccess);
80 }
81
82 static void
83 FreeOldColorTable(XpmColor **colorTable, int ncolors)
84 {
85 int a, b;
86 XpmColor **color;
87 char **sptr;
88
89 if (colorTable) {
90 for (a = 0, color = colorTable; a < ncolors; a++, color++) {
91 for (b = 0, sptr = (char **) *color; b <= NKEYS; b++, sptr++)
92 if (*sptr)
93 XpmFree(*sptr);
94 }
95 XpmFree(*colorTable);
96 XpmFree(colorTable);
97 }
98 }
99
100 /* end 3.2 bc */
101
102
103 /*
104 * Free the computed color table
105 */
106 void
107 xpmFreeColorTable(XpmColor *colorTable, int ncolors)
108 {
109 int a, b;
110 XpmColor *color;
111 char **sptr;
112
113 if (colorTable) {
114 for (a = 0, color = colorTable; a < ncolors; a++, color++) {
115 for (b = 0, sptr = (char **) color; b <= NKEYS; b++, sptr++)
116 if (*sptr)
117 XpmFree(*sptr);
118 }
119 XpmFree(colorTable);
120 }
121 }
122
123 /*
124 * Free array of extensions
125 */
126 void
127 XpmFreeExtensions(XpmExtension *extensions, int nextensions)
128 {
129 unsigned int i, j, nlines;
130 XpmExtension *ext;
131 char **sptr;
132
133 if (extensions) {
134 for (i = 0, ext = extensions; i < nextensions; i++, ext++) {
135 if (ext->name)
136 XpmFree(ext->name);
137 nlines = ext->nlines;
138 for (j = 0, sptr = ext->lines; j < nlines; j++, sptr++)
139 if (*sptr)
140 XpmFree(*sptr);
141 if (ext->lines)
142 XpmFree(ext->lines);
143 }
144 XpmFree(extensions);
145 }
146 }
147
148
149 /*
150 * Return the XpmAttributes structure size
151 */
152
153 int
154 XpmAttributesSize()
155 {
156 return sizeof(XpmAttributes);
157 }
158
159 /*
160 * Init returned data to free safely later on
161 */
162 void
163 xpmInitAttributes(XpmAttributes *attributes)
164 {
165 if (attributes) {
166 attributes->pixels = NULL;
167 attributes->npixels = 0;
168 attributes->colorTable = NULL;
169 attributes->ncolors = 0;
170 /* 3.2 backward compatibility code */
171 attributes->hints_cmt = NULL;
172 attributes->colors_cmt = NULL;
173 attributes->pixels_cmt = NULL;
174 /* end 3.2 bc */
175 attributes->extensions = NULL;
176 attributes->nextensions = 0;
177 }
178 }
179
180 /*
181 * Fill in the XpmAttributes with the XpmImage and the XpmInfo
182 */
183 void
184 xpmSetAttributes(XpmAttributes *attributes, XpmImage *image, XpmInfo *info)
185 {
186 if (attributes->valuemask & XpmReturnColorTable) {
187 attributes->colorTable = image->colorTable;
188 attributes->ncolors = image->ncolors;
189
190 /* avoid deletion of copied data */
191 image->ncolors = 0;
192 image->colorTable = NULL;
193 }
194 /* 3.2 backward compatibility code */
195 else if (attributes->valuemask & XpmReturnInfos) {
196 int ErrorStatus;
197
198 ErrorStatus = CreateOldColorTable(image->colorTable, image->ncolors,
199 (XpmColor ***)
200 &attributes->colorTable);
201
202 /* if error just say we can't return requested data */
203 if (ErrorStatus != XpmSuccess) {
204 attributes->valuemask &= ~XpmReturnInfos;
205 if (!(attributes->valuemask & XpmReturnPixels)) {
206 XpmFree(attributes->pixels);
207 attributes->pixels = NULL;
208 attributes->npixels = 0;
209 }
210 attributes->ncolors = 0;
211 } else {
212 attributes->ncolors = image->ncolors;
213 attributes->hints_cmt = info->hints_cmt;
214 attributes->colors_cmt = info->colors_cmt;
215 attributes->pixels_cmt = info->pixels_cmt;
216
217 /* avoid deletion of copied data */
218 image->ncolors = 0;
219 image->colorTable = NULL;
220 info->hints_cmt = NULL;
221 info->colors_cmt = NULL;
222 info->pixels_cmt = NULL;
223 }
224 }
225 /* end 3.2 bc */
226 if (attributes->valuemask & XpmReturnExtensions) {
227 attributes->extensions = info->extensions;
228 attributes->nextensions = info->nextensions;
229
230 /* avoid deletion of copied data */
231 info->extensions = NULL;
232 info->nextensions = 0;
233 }
234 if (info->valuemask & XpmHotspot) {
235 attributes->valuemask |= XpmHotspot;
236 attributes->x_hotspot = info->x_hotspot;
237 attributes->y_hotspot = info->y_hotspot;
238 }
239 attributes->valuemask |= XpmCharsPerPixel;
240 attributes->cpp = image->cpp;
241 attributes->valuemask |= XpmSize;
242 attributes->width = image->width;
243 attributes->height = image->height;
244 }
245
246 /*
247 * Free the XpmAttributes structure members
248 * but the structure itself
249 */
250 void
251 XpmFreeAttributes(XpmAttributes *attributes)
252 {
253 if (attributes->valuemask & XpmReturnPixels && attributes->npixels) {
254 XpmFree(attributes->pixels);
255 attributes->pixels = NULL;
256 attributes->npixels = 0;
257 }
258 if (attributes->valuemask & XpmReturnColorTable) {
259 xpmFreeColorTable(attributes->colorTable, attributes->ncolors);
260 attributes->colorTable = NULL;
261 attributes->ncolors = 0;
262 }
263 /* 3.2 backward compatibility code */
264 else if (attributes->valuemask & XpmInfos) {
265 if (attributes->colorTable) {
266 FreeOldColorTable((XpmColor **) attributes->colorTable,
267 attributes->ncolors);
268 attributes->colorTable = NULL;
269 attributes->ncolors = 0;
270 }
271 if (attributes->hints_cmt) {
272 XpmFree(attributes->hints_cmt);
273 attributes->hints_cmt = NULL;
274 }
275 if (attributes->colors_cmt) {
276 XpmFree(attributes->colors_cmt);
277 attributes->colors_cmt = NULL;
278 }
279 if (attributes->pixels_cmt) {
280 XpmFree(attributes->pixels_cmt);
281 attributes->pixels_cmt = NULL;
282 }
283 if (attributes->pixels) {
284 XpmFree(attributes->pixels);
285 attributes->pixels = NULL;
286 attributes->npixels = 0;
287 }
288 }
289 /* end 3.2 bc */
290 if (attributes->valuemask & XpmReturnExtensions
291 && attributes->nextensions) {
292 XpmFreeExtensions(attributes->extensions, attributes->nextensions);
293 attributes->extensions = NULL;
294 attributes->nextensions = 0;
295 }
296 attributes->valuemask = 0;
297 }
298
299 /*
300 * Init returned data to free safely later on
301 */
302 void
303 xpmInitXpmImage(XpmImage *image)
304 {
305 image->ncolors = 0;
306 image->colorTable = NULL;
307 image->data = NULL;
308 }
309
310 /*
311 * Free the XpmImage data which have been allocated
312 */
313 void
314 XpmFreeXpmImage(XpmImage *image)
315 {
316 if (image->colorTable)
317 xpmFreeColorTable(image->colorTable, image->ncolors);
318 XpmFree(image->data);
319 image->data = NULL;
320 }
321
322 /*
323 * Init returned data to free safely later on
324 */
325 void
326 xpmInitXpmInfo(XpmInfo *info)
327 {
328 if (info) {
329 info->hints_cmt = NULL;
330 info->colors_cmt = NULL;
331 info->pixels_cmt = NULL;
332 info->extensions = NULL;
333 info->nextensions = 0;
334 }
335 }
336
337 /*
338 * Free the XpmInfo data which have been allocated
339 */
340 void
341 XpmFreeXpmInfo(XpmInfo *info)
342 {
343 if (info) {
344 if (info->valuemask & XpmComments) {
345 if (info->hints_cmt) {
346 XpmFree(info->hints_cmt);
347 info->hints_cmt = NULL;
348 }
349 if (info->colors_cmt) {
350 XpmFree(info->colors_cmt);
351 info->colors_cmt = NULL;
352 }
353 if (info->pixels_cmt) {
354 XpmFree(info->pixels_cmt);
355 info->pixels_cmt = NULL;
356 }
357 }
358 if (info->valuemask & XpmReturnExtensions && info->nextensions) {
359 XpmFreeExtensions(info->extensions, info->nextensions);
360 info->extensions = NULL;
361 info->nextensions = 0;
362 }
363 info->valuemask = 0;
364 }
365 }
366
367 /*
368 * Set the XpmInfo valuemask to retrieve required info
369 */
370 void
371 xpmSetInfoMask(XpmInfo *info, XpmAttributes *attributes)
372 {
373 info->valuemask = 0;
374 if (attributes->valuemask & XpmReturnInfos)
375 info->valuemask |= XpmReturnComments;
376 if (attributes->valuemask & XpmReturnExtensions)
377 info->valuemask |= XpmReturnExtensions;
378 }
379
380 /*
381 * Fill in the XpmInfo with the XpmAttributes
382 */
383 void
384 xpmSetInfo(XpmInfo *info, XpmAttributes *attributes)
385 {
386 info->valuemask = 0;
387 if (attributes->valuemask & XpmInfos) {
388 info->valuemask |= XpmComments | XpmColorTable;
389 info->hints_cmt = attributes->hints_cmt;
390 info->colors_cmt = attributes->colors_cmt;
391 info->pixels_cmt = attributes->pixels_cmt;
392 }
393 if (attributes->valuemask & XpmExtensions) {
394 info->valuemask |= XpmExtensions;
395 info->extensions = attributes->extensions;
396 info->nextensions = attributes->nextensions;
397 }
398 if (attributes->valuemask & XpmHotspot) {
399 info->valuemask |= XpmHotspot;
400 info->x_hotspot = attributes->x_hotspot;
401 info->y_hotspot = attributes->y_hotspot;
402 }
403 }
404
405
406 #ifdef NEED_STRDUP
407 /*
408 * in case strdup is not provided by the system here is one
409 * which does the trick
410 */
411 char *
412 strdup(char *s1)
413 {
414 char *s2;
415 int l = strlen(s1) + 1;
416
417 if (s2 = (char *) XpmMalloc(l))
418 strncpy(s2, s1, l);
419 return s2;
420 }
421
422 #endif
423
424 unsigned int
425 atoui(register char *p, unsigned int l, unsigned int *ui_return)
426 {
427 register unsigned int n, i;
428
429 n = 0;
430 for (i = 0; i < l; i++)
431 if (*p >= '0' && *p <= '9')
432 n = n * 10 + *p++ - '0';
433 else
434 break;
435
436 if (i != 0 && i == l) {
437 *ui_return = n;
438 return 1;
439 } else
440 return 0;
441 }
442
443
444 /*
445 * File / Buffer utilities
446 */
447 int
448 XpmReadFileToBuffer(char *filename, char **buffer_return)
449 {
450 int fd, fcheck, len;
451 char *ptr;
452 struct stat stats;
453 FILE *fp;
454
455 *buffer_return = NULL;
456
457 fd = open(filename, O_RDONLY);
458 if (fd < 0)
459 return XpmOpenFailed;
460
461 if (fstat(fd, &stats)) {
462 close(fd);
463 return XpmOpenFailed;
464 }
465 fp = fdopen(fd, "r");
466 if (!fp) {
467 close(fd);
468 return XpmOpenFailed;
469 }
470 len = (int) stats.st_size;
471 ptr = (char *) XpmMalloc(len + 1);
472 if (!ptr) {
473 fclose(fp);
474 return XpmNoMemory;
475 }
476 fcheck = fread(ptr, len, 1, fp);
477 fclose(fp);
478 if (fcheck != 1) {
479 XpmFree(ptr);
480 return XpmOpenFailed;
481 }
482 ptr[len] = '\0';
483 *buffer_return = ptr;
484 return XpmSuccess;
485 }
486
487 int
488 XpmWriteFileFromBuffer(char *filename, char *buffer)
489 {
490 int fcheck, len;
491 FILE *fp = fopen(filename, "w");
492
493 if (!fp)
494 return XpmOpenFailed;
495
496 len = strlen(buffer);
497 fcheck = fwrite(buffer, len, 1, fp);
498 fclose(fp);
499 if (fcheck != 1)
500 return XpmOpenFailed;
501
502 return XpmSuccess;
503 }
504
505
506 /*
507 * Small utility function
508 */
509 char *
510 XpmGetErrorString(int errcode)
511 {
512 switch (errcode) {
513 case XpmColorError:
514 return ("XpmColorError");
515 case XpmSuccess:
516 return ("XpmSuccess");
517 case XpmOpenFailed:
518 return ("XpmOpenFailed");
519 case XpmFileInvalid:
520 return ("XpmFileInvalid");
521 case XpmNoMemory:
522 return ("XpmNoMemory");
523 case XpmColorFailed:
524 return ("XpmColorFailed");
525 default:
526 return ("Invalid XpmError");
527 }
528 }
529
530 /*
531 * The following function provides a way to figure out if the linked library is
532 * newer or older than the one with which a program has been first compiled.
533 */
534 int
535 XpmLibraryVersion()
536 {
537 return XpmIncludeVersion;
538 }
539
540
541 #ifndef FOR_MSW
542 void
543 xpmCreatePixmapFromImage(Display *display, Drawable d, XImage *ximage, Pixmap *pixmap_return)
544 {
545 GC gc;
546
547 *pixmap_return = XCreatePixmap(display, d, ximage->width,
548 ximage->height, ximage->depth);
549 gc = XCreateGC(display, *pixmap_return, 0, NULL);
550
551 XPutImage(display, *pixmap_return, gc, ximage, 0, 0, 0, 0,
552 ximage->width, ximage->height);
553
554 XFreeGC(display, gc);
555 }
556
557 void
558 xpmCreateImageFromPixmap(Display *display, Pixmap pixmap, XImage **ximage_return, unsigned int *width, unsigned int *height)
559 {
560 unsigned int dum;
561 int dummy;
562 Window win;
563
564 if (*width == 0 && *height == 0)
565 XGetGeometry(display, pixmap, &win, &dummy, &dummy,
566 width, height, &dum, &dum);
567
568 *ximage_return = XGetImage(display, pixmap, 0, 0, *width, *height,
569 AllPlanes, ZPixmap);
570 }
571
572 #endif /* FOR_MSW */