~ctwm/ctwm/trunk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/*
 * Bitmap image handling functions
 *
 * These are what's called "XBM", and represented by the Pixmap X data
 * type (which has noting to do with "XPM" X PixMaps, just to confuse
 * you).  This is the format used for various builtin images, buttons,
 * and cursors, and is also the fallback type for any user-specified
 * images.  Assuming any user has made and specified an XBM since the
 * 1980's.
 */

#include "ctwm.h"

#include <X11/Xmu/Drawing.h>

#include "screen.h"
#include "util.h"

#include "image.h"
#include "image_bitmap.h"
#include "image_bitmap_builtin.h"


/* Shared with cursor.c for bitmap cursors */
int  HotX, HotY;


static Image *LoadBitmapImage(const char  *name, ColorPair cp);
static Pixmap FindBitmap(const char *name, unsigned int *widthp,
                         unsigned int *heightp);


/*
 * External API's
 */

/* Simple load-by-name */
Pixmap
GetBitmap(const char *name)
{
	return FindBitmap(name, &JunkWidth, &JunkHeight);
}


/*
 * Load with FG/BG adjusted to given colorpair
 */
Image *
GetBitmapImage(const char *name, ColorPair cp)
{
	/* Non-animated */
	if(! strchr(name, '%')) {
		return (LoadBitmapImage(name, cp));
	}

	/* Animated */
	return get_image_anim_cp(name, cp, LoadBitmapImage);
}


/*
 * Internal bits used by the above
 */

/***********************************************************************
 *
 *  Procedure:
 *      FindBitmap - read in a bitmap file and return size
 *
 *  Returned Value:
 *      the pixmap associated with the bitmap
 *      widthp  - pointer to width of bitmap
 *      heightp - pointer to height of bitmap
 *
 *  Inputs:
 *      name    - the filename to read
 *
 ***********************************************************************
 */
static Pixmap
FindBitmap(const char *name, unsigned int *widthp,
           unsigned int *heightp)
{
	char *bigname;
	Pixmap pm;

	if(!name) {
		return None;
	}

	/*
	 * Names of the form :name refer to hardcoded images that are scaled to
	 * look nice in title buttons.  Eventually, it would be nice to put in a
	 * menu symbol as well....
	 */
	if(name[0] == ':') {
		return get_builtin_plain_pixmap(name, widthp, heightp);
	}

	/*
	 * Generate a full pathname with any special prefix characters (such
	 * as ~) expanded.
	 */
	bigname = ExpandFilename(name);
	if(!bigname) {
		/* Something failed bad */
		return None;
	}

	/*
	 * look along bitmapFilePath resource same as toolkit clients
	 */
	pm = XmuLocateBitmapFile(ScreenOfDisplay(dpy, Scr->screen), bigname, NULL,
	                         0, (int *)widthp, (int *)heightp, &HotX, &HotY);
	if(pm == None && Scr->IconDirectory && bigname[0] != '/') {
		/*
		 * Didn't find it.  Attempt to find icon in old IconDirectory
		 * (now obsolete)
		 */
		free(bigname);
		asprintf(&bigname, "%s/%s", Scr->IconDirectory, name);
		if(XReadBitmapFile(dpy, Scr->Root, bigname, widthp, heightp, &pm,
		                   &HotX, &HotY) != BitmapSuccess) {
			pm = None;
		}
	}
	free(bigname);
	if((pm == None) && reportfilenotfound) {
		fprintf(stderr, "%s:  unable to find bitmap \"%s\"\n", ProgramName, name);
	}

	return pm;
}


static Image *
LoadBitmapImage(const char *name, ColorPair cp)
{
	Image        *image;
	Pixmap       bm;
	unsigned int width, height;
	XGCValues    gcvalues;

	if(Scr->rootGC == (GC) 0) {
		Scr->rootGC = XCreateGC(dpy, Scr->Root, 0, &gcvalues);
	}
	bm = FindBitmap(name, &width, &height);
	if(bm == None) {
		return NULL;
	}

	image = AllocImage();
	image->pixmap = XCreatePixmap(dpy, Scr->Root, width, height, Scr->d_depth);
	gcvalues.background = cp.back;
	gcvalues.foreground = cp.fore;
	XChangeGC(dpy, Scr->rootGC, GCForeground | GCBackground, &gcvalues);
	XCopyPlane(dpy, bm, image->pixmap, Scr->rootGC, 0, 0, width, height,
	           0, 0, (unsigned long) 1);
	XFreePixmap(dpy, bm);
	image->width  = width;
	image->height = height;
	return image;
}