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 ***
22
#include <Xmt/Pixmap.h>
25
#include <Xmt/Color.h>
26
#include <Xmt/AppResP.h>
27
#include <X11/IntrinsicP.h>
29
static XmtHashTable image_cache = NULL;
30
static XmtHashTable pixmap_to_image_table = NULL;
33
PixmapImage, PixmapMask
36
typedef struct _PixmapRec {
45
Pixel *allocated_pixels; /* free these pixels when done w/ pixmap */
46
short num_allocated_pixels;
47
struct _PixmapRec *next;
48
struct _ImageCacheEntry *listhead;
49
} PixmapRec, *PixmapList;
52
ImageTypeXbm, ImageTypeXpm
58
unsigned short width, height;
62
typedef struct _ImageCacheEntry {
72
#if NeedFunctionPrototypes
73
static void FreeImageCacheEntry(ImageCacheEntry *ie)
75
static void FreeImageCacheEntry(ie)
79
if (ie->type == ImageTypeXbm) {
80
XtFree((char *)ie->data.xbm);
85
#if NeedFunctionPrototypes
86
static void RegisterImage(StringConst name, ImageType type, XtPointer data)
88
static void RegisterImage(name, type, data)
94
XrmQuark q = XrmStringToQuark(name);
97
if (image_cache == NULL) {
98
image_cache = XmtHashTableCreate(3);
99
pixmap_to_image_table = XmtHashTableCreate(3);
103
* if there is already an image by that name, free the old image
104
* if possible, or make it an orphan so it gets cleaned up when
105
* all of its outstanding pixmaps have been released.
107
if (XmtHashTableLookup(image_cache, (XtPointer)q, (XtPointer *)&ie)) {
108
if (ie->list == NULL) FreeImageCacheEntry(ie);
109
else ie->orphan = True;
112
ie = XtNew(ImageCacheEntry);
114
if (type == ImageTypeXbm) ie->data.xbm = (XbmImage *) data;
115
else ie->data.xpm = (XmtImage *)data;
118
XmtHashTableStore(image_cache, (XtPointer)q, (XtPointer)ie);
122
#if NeedFunctionPrototypes
123
void XmtRegisterXbmData(StringConst name, char *imagedata, char *maskdata,
124
int width, int height, int hotspot_x, int hotspot_y)
126
void XmtRegisterXbmData(name, imagedata, maskdata, width, height,
127
hotspot_x, hotspot_y)
139
data = XtNew(XbmImage);
140
data->imagedata = imagedata;
141
data->maskdata = maskdata;
143
data->height = height;
144
data->hotspot.x = hotspot_x;
145
data->hotspot.y = hotspot_y;
147
RegisterImage(name, ImageTypeXbm, (XtPointer)data);
150
#if NeedFunctionPrototypes
151
void XmtRegisterImage(StringConst name, XmtImage *data)
153
void XmtRegisterImage(name, data)
158
RegisterImage(name, ImageTypeXpm, (XtPointer)data);
162
#if NeedFunctionPrototypes
163
Pixmap XmtLookupBitmap(Widget widget, StringConst name)
165
Pixmap XmtLookupBitmap(widget, name)
170
Screen *screen = XtScreenOfObject(widget);
174
if (image_cache == NULL) return None;
176
/* if nothing by that name, return None */
177
if (!XmtHashTableLookup(image_cache, (XtPointer)XrmStringToQuark(name),
181
/* if it is not bitmap data, return None*/
182
if (ie->type != ImageTypeXbm) return None;
184
/* if there is no image data, return None */
185
if (ie->data.xbm->imagedata == NULL) return None;
187
/* go see if a 1-bit image pixmap has been created for this screen */
188
for (p=ie->list; p; p = p->next) {
189
if ((p->type == PixmapImage) &&
190
(p->screen == screen) &&
197
/* otherwise create it and add to the list */
198
p = XtNew(PixmapRec);
199
p->type = PixmapImage;
200
p->pixmap = XCreateBitmapFromData(DisplayOfScreen(screen),
201
RootWindowOfScreen(screen),
202
ie->data.xbm->imagedata,
204
ie->data.xbm->height);
211
p->allocated_pixels = NULL;
212
p->num_allocated_pixels = 0;
218
* map the bitmap back to its list entry, so that we
219
* can decrement its reference count when done with it.
221
XmtHashTableStore(pixmap_to_image_table,
222
(XtPointer) p->pixmap, (XtPointer)p);
228
#if NeedFunctionPrototypes
229
Pixmap XmtLookupPixmap(Widget widget, Visual *visual, Colormap colormap,
230
unsigned int depth, XmtColorTable table,
233
Pixmap XmtLookupPixmap(widget, visual, colormap, depth, table, name)
242
Screen *screen = XtScreenOfObject(widget);
251
if (image_cache == NULL) return None;
253
/* if nothing by that name, return None */
254
if (!XmtHashTableLookup(image_cache, (XtPointer)XrmStringToQuark(name),
258
/* if xbm format with no image data, return None */
259
if (ie->type == ImageTypeXbm && ie->data.xbm->imagedata == NULL)
262
/* go see if an appropriate Pixmap is already created */
263
for (p=ie->list; p; p = p->next) {
264
if ((p->type == PixmapImage) &&
265
(p->screen == screen) &&
266
(p->visual == visual) &&
267
(p->colormap == colormap) &&
268
(p->depth == depth) &&
269
(p->table == table)) {
275
/* otherwise go create it */
276
if (ie->type == ImageTypeXpm) {
277
status = XmtCreatePixmapFromXmtImage(widget,
278
RootWindowOfScreen(screen),
279
visual, colormap, depth, table,
288
if (XmtAllocColor(widget, colormap, visual, table,
289
"+$foreground", &fg) ||
290
XmtAllocColor(widget, colormap, visual, table,
291
"-$background", &bg)) {
292
XmtWarningMsg("XmtLookupPixmap", "color",
293
"bitmap '%s'\n\tforeground and/or background colors are not defined in colortable,\n\tor are invalid colors, or the colormap is full.",
298
pixmap = XCreatePixmapFromBitmapData(DisplayOfScreen(screen),
299
RootWindowOfScreen(screen),
300
ie->data.xbm->imagedata,
302
ie->data.xbm->height,
308
p = XtNew(PixmapRec);
309
p->type = PixmapImage;
313
p->colormap = colormap;
317
p->allocated_pixels = pixels;
318
p->num_allocated_pixels = num_pixels;
324
* map the pixmap back to its list entry, so that we
325
* can decrement its reference count when done with it.
327
XmtHashTableStore(pixmap_to_image_table,
328
(XtPointer) p->pixmap, (XtPointer)p);
334
#if NeedFunctionPrototypes
335
Pixmap XmtLookupBitmask(Widget widget, StringConst name)
337
Pixmap XmtLookupBitmask(widget, name)
342
Screen *screen = XtScreenOfObject(widget);
348
if (image_cache == NULL) return None;
350
/* if nothing by that name, return None */
351
if (!XmtHashTableLookup(image_cache, (XtPointer)XrmStringToQuark(name),
355
/* if xbm format with no mask data, return None */
356
if (ie->type == ImageTypeXbm && ie->data.xbm->maskdata == NULL)
359
/* go see if an appropriate Pixmap is already created */
360
for (p=ie->list; p; p = p->next) {
361
if ((p->type == PixmapMask) &&
362
(p->screen == screen)) {
368
/* otherwise go create one */
369
if (ie->type == ImageTypeXbm) {
370
pixmap = XCreateBitmapFromData(DisplayOfScreen(screen),
371
RootWindowOfScreen(screen),
372
ie->data.xbm->maskdata,
374
ie->data.xbm->height);
377
status = XmtCreatePixmapFromXmtImage(widget,
378
RootWindowOfScreen(screen),
380
ie->data.xpm, NULL, &pixmap,
382
if (!status || pixmap == None) return None;
385
p = XtNew(PixmapRec);
386
p->type = PixmapMask;
394
p->allocated_pixels = NULL;
395
p->num_allocated_pixels = 0;
401
* map the pixmap back to its list entry, so that we
402
* can decrement its reference count when done with it.
404
XmtHashTableStore(pixmap_to_image_table,
405
(XtPointer) p->pixmap, (XtPointer)p);
411
#if NeedFunctionPrototypes
412
Pixmap XmtLookupSimplePixmap(Widget widget, XmtColorTable table,
415
Pixmap XmtLookupSimplePixmap(widget, table, name)
421
while(!XtIsWidget(widget)) widget = XtParent(widget);
422
return XmtLookupPixmap(widget,
423
XmtGetVisual(widget),
424
widget->core.colormap,
430
#if NeedFunctionPrototypes
431
Pixmap XmtLookupWidgetPixmap(Widget w, StringConst name)
433
Pixmap XmtLookupWidgetPixmap(w, name)
438
XmtAppResources *app;
440
while(!XtIsWidget(w)) w = XtParent(w);
441
app = XmtGetApplicationResources(w);
442
return XmtLookupPixmap(w,
446
app->colortable, name);
450
#if NeedFunctionPrototypes
451
void XmtReleasePixmap(Widget widget, Pixmap pixmap)
453
void XmtReleasePixmap(widget, pixmap)
461
if (pixmap_to_image_table == NULL) return;
463
if (!XmtHashTableLookup(pixmap_to_image_table, (XtPointer)pixmap,
467
/* decrement the refcount */
471
* if the refcount is 0, remove the hash table entry,
472
* free the pixmap, unlink the record,
473
* free any allocated pixels, and free the record.
475
if (p->refcount == 0) {
476
XmtHashTableDelete(pixmap_to_image_table, (XtPointer)pixmap);
477
XFreePixmap(DisplayOfScreen(p->screen), p->pixmap);
479
if (p == ie->list) ie->list = p->next;
481
for(q = ie->list; q->next != p; q = q->next);
484
if (p->num_allocated_pixels) {
486
for(i=0; i < p->num_allocated_pixels; i++)
487
XmtFreeColor(widget, p->colormap, p->allocated_pixels[i]);
488
XtFree((char *)p->allocated_pixels);
493
* if that was the last pixmap for this cache entry, and this
494
* cache entry has been orphaned, (ie. not bound to a symbolic
495
* name in the hash table anymore) free the entry.
497
if (ie->orphan && ie->list == NULL)
498
FreeImageCacheEntry(ie);