2
* Motif Tools Library, Version 3.1
5
* Written by David Flanagan.
6
* Copyright (c) 1992-2001 by David Flanagan.
7
* All Rights Reserved. See the file COPYRIGHT for details.
8
* This is open source software. See the file LICENSE for details.
9
* There is no warranty for this software. See NO_WARRANTY for details.
12
* Revision 1.1.1.1 2001/07/18 11:06:02 root
15
* Revision 1.2 2001/06/12 16:25:28 andre
16
* *** empty log message ***
27
#include <Xmt/Pixmap.h>
30
#include <Xmt/Color.h>
31
#include <Xmt/AppResP.h>
32
#include <Xmt/ConvertersP.h>
33
#include <Xmt/LookupP.h>
34
#include <X11/IntrinsicP.h>
36
#if NeedFunctionPrototypes
37
static Pixmap GetPixmap(Widget object, StringConst str, XmtColorTable table,
40
static Pixmap GetPixmap(object, str, table, get_bitmap)
54
XmtImage *xmtimage = NULL;
57
int width, height, hot_x, hot_y;
62
String filename = NULL;
64
Boolean pixmap_file = False;
65
Boolean bitmap_file = False;
66
XtCacheRef color_table_cache_ref;
68
Boolean free_color_table = False;
69
static int unique_image_number;
71
for(w=object; !XtIsWidget(w); w = XtParent(w));
72
shell = XmtGetShell(w);
74
app = XmtGetApplicationResources(shell);
76
display = DisplayOfScreen(screen);
77
visual = XmtGetVisual(shell);
78
colormap = w->core.colormap;
79
depth = w->core.depth;
80
if (!table) table = app->colortable;
83
* see if it is a literal XPM file
85
if (!get_bitmap && strncmp(str, "/* XPM */", 9) == 0) {
86
xmtimage = XmtParseXpmString(str);
89
sprintf(name, "_%d_", unique_image_number++);
96
* see if it is a literal XBM file
99
if (strncmp(str, "#define", 7) == 0) {
100
if (XmtParseXbmString(str, &xbmdata.bits,
101
&xbmdata.width, &xbmdata.height,
102
&xbmdata.hot_x, &xbmdata.hot_y)) {
104
sprintf(name, "_Xmt%d", unique_image_number++);
112
* Otherwise it is a single name, optionally followed by a color table.
113
* If there is a colon, parse the color table, and get a null-terminated
114
* copy of the single name.
115
* In either case, name is set to the image name.
116
* if (name != str) then name must be freed later.
118
table_string = strchr(str, ':');
122
table_string++; /* points to first char after colon */
124
if (_XmtColorTableConverter != NULL) {
126
XrmValue color_table_args[2];
127
XmtColorTable parent_table;
130
parent_table = table;
131
from.addr = table_string;
132
from.size = strlen(table_string);
133
to.addr = (XPointer)&table;
134
to.size = sizeof(XmtColorTable);
135
color_table_args[0].addr = (XPointer)&parent_table;
136
color_table_args[0].size = sizeof(XmtColorTable);
137
color_table_args[1].addr = (XPointer)&screen;
138
color_table_args[1].size = sizeof(Screen *);
139
status = XtCallConverter(display, _XmtColorTableConverter,
141
&from, &to, &color_table_cache_ref);
143
XmtWarningMsg("XmtGetPixmap", "badColor",
144
"continuing with default color table.");
146
free_color_table = True;
149
XmtWarningMsg("XmtGetPixmap", "noColor",
150
"No XmtColorTable converter registered.\n\tSee XmtRegisterColorTableConverter();");
154
XmtWarningMsg("XmtGetBitmap", "table",
155
"color table specification unused in bitmap conversion.");
158
table_string -= 2; /* points to char before colon */
159
for(; isspace(*table_string); table_string--); /* skip over blanks*/
160
i = (table_string - str) + 1;
161
name = strncpy(XtMalloc(i+1), str, i);
168
* see if name is defined in the image cache
171
pixmap = XmtLookupBitmap(w, name);
173
pixmap = XmtLookupPixmap(w, visual, colormap, depth, table, name);
175
if (pixmap) goto end;
178
* If it is not in the image cache, check if it is the name of a
179
* resource under _Pixmaps_ or _Bitmaps_. We lookup the image
181
* _Pixmaps_.visual.depth.resolution.language.territory.codeset.name
182
* For backward compatibility with Xmt 1.2, we also do just:
184
* because in 1.2 '.name' was more common than '*name'
186
* For bitmaps, we use _Bitmaps_, and omit the visual and depth.
191
value = _XmtLookupResource(screen, "PVDZltc", name);
193
if ((xmtimage = XmtParseXpmString(value))) goto found;
198
value = _XmtLookupResource(screen, "BZltc", name);
200
if (XmtParseXbmString(value, &xbmdata.bits,
201
&xbmdata.width, &xbmdata.height,
202
&xbmdata.hot_x, &xbmdata.hot_y))
207
/* if still not found, look up the old way, for compatibility */
209
value = _XmtLookupResource(screen, "P", name);
211
if ((xmtimage = XmtParseXpmString(value))) goto found;
216
value = _XmtLookupResource(screen, "B", name);
218
if (XmtParseXbmString(value, &xbmdata.bits,
219
&xbmdata.width, &xbmdata.height,
220
&xbmdata.hot_x, &xbmdata.hot_y))
227
* if we still haven't found a pixmap, name must be a filename
229
if (pixmap == None) {
231
* handle absolute and relative filenames
233
if ((name[0] == '/') ||
234
((name[0] == '.') && (name[1] == '/')) ||
235
((name[0] == '.') && (name[1] == '.') && (name[2] == '/')))
239
* check relative to an environment variable, if defined
240
* Note that since we don't know the path, we don't know for
241
* sure that it uses the supplied type and suffix, so we don't
242
* know what type of file is being found
244
if (!get_bitmap && !filename && (path = getenv("XPMLANGPATH"))) {
245
filename = XmtFindFile(shell, "pixmaps", name, ".xpm",
246
NULL, path, XmtSearchPathOnly);
247
if (filename) pixmap_file = True;
250
if (!filename && (path = getenv("XBMLANGPATH"))) {
251
filename = XmtFindFile(shell, "bitmaps", name, ".xbm",
252
NULL, path, XmtSearchPathOnly);
253
if (filename) bitmap_file = True;
256
/* next check the user, app, and system pixmap and bitmap paths */
259
filename = XmtFindFile(shell, "pixmaps", name, ".xpm",
260
NULL, app->pixmap_file_path,
261
XmtSearchEverywhere);
266
filename = XmtFindFile(shell, "bitmaps", name, ".xbm",
267
NULL, app->bitmap_file_path,
268
XmtSearchEverywhere);
275
* if we found a file, read the first few bytes to determine the
276
* type. Read it as appropriate. Register the resulting
277
* pixmap in the cache using the filename as the key.
283
if (!pixmap_file && !bitmap_file) {
284
if (get_bitmap) bitmap_file = True;
285
else if ((f = fopen(filename, "r")) != NULL) {
286
(void)fgets(buf, 10, f);
287
if (strncmp(buf, "/* XPM */", 9) == 0)
289
else if (strncmp(buf, "#define", 7) == 0)
295
if (pixmap_file || (!pixmap_file && !bitmap_file)) {
296
xmtimage = XmtParseXpmFile(filename);
297
if (xmtimage) goto found;
300
if (bitmap_file || (!pixmap_file && !bitmap_file)) {
301
if (XmtParseXbmFile(filename, &xbmdata.bits,
302
&xbmdata.width, &xbmdata.height,
303
&xbmdata.hot_x, &xbmdata.hot_y))
311
* register the xpm or xbm data, and then get a pixmap for it.
312
* we jump here when we successfully parse a xpm or xbm file or string.
315
XmtRegisterImage(name, xmtimage);
316
else if (xbmdata.bits)
317
XmtRegisterXbmData(name, xbmdata.bits, NULL,
318
xbmdata.width, xbmdata.height,
319
xbmdata.hot_x, xbmdata.hot_y);
321
if (xmtimage || xbmdata.bits) {
323
pixmap = XmtLookupBitmap(w, name);
325
pixmap = XmtLookupPixmap(w, visual, colormap,
331
* free what we need to and return.
332
* we jump here if the pixmap is already cached, or on error.
334
if (filename && filename != name) XtFree(filename);
335
if (name && name != str) XtFree(name);
336
if (free_color_table) {
337
refs[0] = color_table_cache_ref;
339
XtAppReleaseCacheRefs(XtWidgetToApplicationContext(w), refs);
344
#if NeedFunctionPrototypes
345
Pixmap XmtGetBitmap(Widget object, StringConst str)
347
Pixmap XmtGetBitmap(object, str)
352
return GetPixmap(object, str, NULL, True);
355
#if NeedFunctionPrototypes
356
Pixmap XmtGetPixmap(Widget object, XmtColorTable table, StringConst str)
358
Pixmap XmtGetPixmap(object, table, str)
364
return GetPixmap(object, str, table, False);