CTWM
Toggle main menu visibility
Loading...
Searching...
No Matches
/usr/src/RPM/BUILD/ctwm-4.1.0/image.c
Go to the documentation of this file.
1
/*
2
* Image handling functions
3
*
4
* This provides some general and hub stuff. Details of different image
5
* type functions, and generation of builtins, go in their own files.
6
*/
7
8
#include "
ctwm.h
"
9
10
#include <stdio.h>
11
#include <string.h>
12
#include <unistd.h>
13
14
#include "
list.h
"
15
#include "
screen.h
"
16
17
#include "
image.h
"
18
#include "
image_bitmap.h
"
19
#include "
image_bitmap_builtin.h
"
20
#include "
image_xwd.h
"
21
#ifdef JPEG
22
#include "
image_jpeg.h
"
23
#endif
24
#if defined (XPM)
25
#include "
image_xpm.h
"
26
#endif
27
28
/* Flag (maybe should be retired */
29
bool
reportfilenotfound
=
false
;
30
Colormap
AlternateCmap
= None;
31
32
33
/*
34
* Find (load/generate) an image by name
35
*/
36
Image
*
37
GetImage
(
const
char
*name,
ColorPair
cp)
38
{
39
name_list
**list;
40
#define GIFNLEN 256
41
char
fullname[
GIFNLEN
];
42
Image
*image;
43
44
if
(name == NULL) {
45
return
NULL;
46
}
47
if
(
dpy
== NULL) {
48
// May happen in special cases like --cfgchk with no $DISPLAY
49
return
NULL;
50
}
51
image = NULL;
52
53
list = &
Scr
->ImageCache;
54
if
(0) {
55
/* dummy */
;
56
}
57
else
if
((name [0] ==
'@'
) || (strncmp(name,
"xpm:"
, 4) == 0)) {
58
#ifdef XPM
59
snprintf(fullname,
GIFNLEN
,
"%s%dx%d"
, name, (
int
) cp.
fore
, (
int
) cp.
back
);
60
61
if
((image =
LookInNameList
(*list, fullname)) == NULL) {
62
int
startn = (name [0] ==
'@'
) ? 1 : 4;
63
if
((image =
GetXpmImage
(name + startn, cp)) != NULL) {
64
AddToList
(list, fullname, image);
65
}
66
}
67
#else
68
fprintf(stderr,
"XPM support disabled, ignoring image %s\n"
, name);
69
return
NULL;
70
#endif
71
}
72
else
if
(strncmp(name,
"jpeg:"
, 5) == 0) {
73
#ifdef JPEG
74
if
((image =
LookInNameList
(*list, name)) == NULL) {
75
if
((image =
GetJpegImage
(&name [5])) != NULL) {
76
AddToList
(list, name, image);
77
}
78
}
79
#else
80
fprintf(stderr,
"JPEG support disabled, ignoring image %s\n"
, name);
81
return
NULL;
82
#endif
83
}
84
else
if
((strncmp(name,
"xwd:"
, 4) == 0) || (name [0] ==
'|'
)) {
85
int
startn = (name [0] ==
'|'
) ? 0 : 4;
86
if
((image =
LookInNameList
(*list, name)) == NULL) {
87
if
((image =
GetXwdImage
(&name [startn], cp)) != NULL) {
88
AddToList
(list, name, image);
89
}
90
}
91
}
92
else
if
(strncmp(name,
":xpm:"
, 5) == 0) {
93
snprintf(fullname,
GIFNLEN
,
"%s%dx%d"
, name, (
int
) cp.
fore
, (
int
) cp.
back
);
94
if
((image =
LookInNameList
(*list, fullname)) == NULL) {
95
image =
get_builtin_scalable_pixmap
(name, cp);
96
if
(image == NULL) {
97
/* g_b_s_p() already warned */
98
return
NULL;
99
}
100
AddToList
(list, fullname, image);
101
}
102
}
103
else
if
(strncmp(name,
"%xpm:"
, 5) == 0) {
104
snprintf(fullname,
GIFNLEN
,
"%s%dx%d"
, name, (
int
) cp.
fore
, (
int
) cp.
back
);
105
if
((image =
LookInNameList
(*list, fullname)) == NULL) {
106
image =
get_builtin_animated_pixmap
(name, cp);
107
if
(image == NULL) {
108
/* g_b_a_p() already warned */
109
return
NULL;
110
}
111
AddToList
(list, fullname, image);
112
}
113
}
114
else
if
(name [0] ==
':'
) {
115
unsigned
int
width, height;
116
Pixmap pm = 0;
117
XGCValues gcvalues;
118
119
snprintf(fullname,
GIFNLEN
,
"%s%dx%d"
, name, (
int
) cp.
fore
, (
int
) cp.
back
);
120
if
((image =
LookInNameList
(*list, fullname)) == NULL) {
121
pm =
get_builtin_plain_pixmap
(name, &width, &height);
122
if
(pm == None) {
123
/* g_b_p_p() already warned */
124
return
NULL;
125
}
126
image =
AllocImage
();
127
image->
pixmap
= XCreatePixmap(
dpy
,
Scr
->Root, width, height,
Scr
->d_depth);
128
if
(
Scr
->rootGC == (GC) 0) {
129
Scr
->rootGC = XCreateGC(
dpy
,
Scr
->Root, 0, &gcvalues);
130
}
131
gcvalues.background = cp.
back
;
132
gcvalues.foreground = cp.
fore
;
133
XChangeGC(
dpy
,
Scr
->rootGC, GCForeground | GCBackground, &gcvalues);
134
XCopyPlane(
dpy
, pm, image->
pixmap
,
Scr
->rootGC, 0, 0, width, height, 0, 0,
135
(
unsigned
long
) 1);
136
image->
width
= width;
137
image->
height
= height;
138
AddToList
(list, fullname, image);
139
}
140
}
141
else
{
142
snprintf(fullname,
GIFNLEN
,
"%s%dx%d"
, name, (
int
) cp.
fore
, (
int
) cp.
back
);
143
if
((image =
LookInNameList
(*list, fullname)) == NULL) {
144
if
((image =
GetBitmapImage
(name, cp)) != NULL) {
145
AddToList
(list, fullname, image);
146
}
147
}
148
}
149
return
image;
150
#undef GIFNLEN
151
}
152
153
154
/*
155
* Creation/cleanup of Image structs
156
*/
157
Image
*
158
AllocImage
(
void
)
159
{
160
return
calloc(1,
sizeof
(
Image
));
161
}
162
163
void
164
FreeImage
(
Image
*image)
165
{
166
Image
*im, *im2;
167
168
im = image;
169
while
(im != NULL) {
170
/* Cleanup sub-bits */
171
if
(im->
pixmap
) {
172
XFreePixmap(
dpy
, im->
pixmap
);
173
}
174
if
(im->
mask
) {
175
XFreePixmap(
dpy
, im->
mask
);
176
}
177
178
/* Cleanup self */
179
im2 = im->
next
;
180
im->
next
= NULL;
181
free(im);
182
183
/*
184
* Loop back around, unless we hit the original. e.g.,
185
* "foo%.xpm" animations load the images into a closed loop, so
186
* FreeImage() would do Very Bad Things running around the track
187
* until it segfaults or the like.
188
*/
189
if
(im2 == image) {
190
break
;
191
}
192
im = im2;
193
}
194
}
195
196
197
198
/*
199
* Utils for image*
200
*/
201
202
/*
203
* Expand out the real pathname for an image. Turn ~ into $HOME if
204
* it's there, and look under the entries in PixmapDirectory if the
205
* result isn't a full path.
206
*/
207
char
*
208
ExpandPixmapPath
(
const
char
*name)
209
{
210
char
*ret;
211
212
ret = NULL;
213
214
/* If it starts with '~/', replace it with our homedir */
215
if
(name[0] ==
'~'
&& name[1] ==
'/'
) {
216
asprintf(&ret,
"%s/%s"
,
Home
, name + 2);
217
return
ret;
218
}
219
220
/*
221
* If it starts with /, it's an absolute path, so just pass it
222
* through.
223
*/
224
if
(name[0] ==
'/'
) {
225
return
strdup(name);
226
}
227
228
/*
229
* If we got here, it's some sort of relative path (or a bare
230
* filename), so search for it under PixmapDirectory if we have it.
231
*/
232
if
(
Scr
->PixmapDirectory) {
233
char
*colon;
234
char
*p =
Scr
->PixmapDirectory;
235
236
/* PixmapDirectory is a colon-separated list */
237
while
((colon = strchr(p,
':'
))) {
238
*colon =
'\0'
;
239
asprintf(&ret,
"%s/%s"
, p, name);
240
*colon =
':'
;
241
if
(!access(ret, R_OK)) {
242
return
(ret);
243
}
244
free(ret);
245
p = colon + 1;
246
}
247
248
asprintf(&ret,
"%s/%s"
, p, name);
249
if
(!access(ret, R_OK)) {
250
return
(ret);
251
}
252
free(ret);
253
}
254
255
256
/*
257
* If we get here, we have no idea. For simplicity and consistency
258
* for our callers, just return what we were given.
259
*/
260
return
strdup(name);
261
}
262
263
264
/*
265
* Generalized loader for animations.
266
*
267
* These are specified with a '%' in the filename, which is replaced by a
268
* series of numbers. So e.g.
269
*
270
* "foo%.xpm" -> [ "foo1.xpm", "foo2.xpm", ...]
271
*
272
* These then turn into a looped-linked-list of Image's. We support
273
* these for all types of images, so write it up into a central handler
274
* once to centralize the logic.
275
*/
276
Image
*
277
get_image_anim_cp
(
const
char
*name,
278
ColorPair
cp,
Image
* (*imgloader)(
const
char
*,
ColorPair
))
279
{
280
Image
*head, *tail;
281
char
*pref, *suff, *stmp;
282
int
i;
283
284
/* This shouldn't get called for non-animations */
285
if
((stmp = strchr(name,
'%'
)) == NULL) {
286
fprintf(stderr,
"%s() called for non-animation '%s'\n"
, __func__, name);
287
return
NULL;
288
}
289
if
(stmp[1] ==
'\0'
) {
290
fprintf(stderr,
"%s(): nothing after %% in '%s'\n"
, __func__, name);
291
return
NULL;
292
}
293
stmp = NULL;
294
295
/*
296
* For animated requests, we load a series of files, replacing the %
297
* with numbers in series.
298
*/
299
tail = head = NULL;
300
301
/* Working copy of the filename split to before/after the % */
302
pref = strdup(name);
303
suff = strchr(pref,
'%'
);
304
*suff++ =
'\0'
;
305
306
/* "foo%.xpm" -> [ "foo1.xpm", "foo2.xpm", ...] */
307
for
(i = 1 ; ; i++) {
308
#define ANIM_PATHLEN 256
309
char
path[
ANIM_PATHLEN
];
310
Image
*tmp;
311
312
if
(snprintf(path,
ANIM_PATHLEN
,
"%s%d%s"
, pref, i,
313
suff) >= (
ANIM_PATHLEN
- 1)) {
314
fprintf(stderr,
"%s(): generated filename for '%s' #%d longer than %d.\n"
,
315
__func__, name, i,
ANIM_PATHLEN
);
316
FreeImage
(head);
317
free(pref);
318
return
NULL;
319
}
320
#undef ANIM_PATHLEN
321
322
/*
323
* Load this image, and set ->next so it's explicitly the
324
* [current] tail of the list.
325
*/
326
tmp = imgloader(path, cp);
327
if
(tmp == NULL) {
328
break
;
329
}
330
tmp->
next
= NULL;
331
332
/*
333
* If it's the first, it's the head (image) we return, as well as
334
* our current tail marker (s). Else, append to that tail.
335
*/
336
if
(head == NULL) {
337
tail = head = tmp;
338
}
339
else
{
340
tail->
next
= tmp;
341
tail = tmp;
342
}
343
}
344
free(pref);
345
346
/* Set the tail to loop back to the head */
347
if
(tail != NULL) {
348
tail->
next
= head;
349
}
350
351
/* Warn if we got nothing */
352
if
(head == NULL) {
353
fprintf(stderr,
"Cannot find any image frames for '%s'\n"
, name);
354
}
355
356
return
head;
357
}
ctwm.h
Home
char * Home
Definition
ctwm_main.c:128
dpy
Display * dpy
Definition
ctwm_main.c:84
Scr
#define Scr
AlternateCmap
Colormap AlternateCmap
Definition
image.c:30
ANIM_PATHLEN
#define ANIM_PATHLEN
reportfilenotfound
bool reportfilenotfound
Definition
image.c:29
GetImage
Image * GetImage(const char *name, ColorPair cp)
Definition
image.c:37
get_image_anim_cp
Image * get_image_anim_cp(const char *name, ColorPair cp, Image *(*imgloader)(const char *, ColorPair))
Definition
image.c:277
GIFNLEN
#define GIFNLEN
AllocImage
Image * AllocImage(void)
Definition
image.c:158
ExpandPixmapPath
char * ExpandPixmapPath(const char *name)
Definition
image.c:208
FreeImage
void FreeImage(Image *image)
Definition
image.c:164
image.h
GetBitmapImage
Image * GetBitmapImage(const char *name, ColorPair cp)
Definition
image_bitmap.c:49
image_bitmap.h
get_builtin_plain_pixmap
Pixmap get_builtin_plain_pixmap(const char *name, unsigned int *widthp, unsigned int *heightp)
Definition
image_bitmap_builtin.c:43
get_builtin_scalable_pixmap
Image * get_builtin_scalable_pixmap(const char *name, ColorPair cp)
Definition
image_bitmap_builtin.c:279
get_builtin_animated_pixmap
Image * get_builtin_animated_pixmap(const char *name, ColorPair cp)
Definition
image_bitmap_builtin.c:766
image_bitmap_builtin.h
GetJpegImage
Image * GetJpegImage(const char *name)
Definition
image_jpeg.c:46
image_jpeg.h
GetXpmImage
Image * GetXpmImage(const char *name, ColorPair cp)
Definition
image_xpm.c:28
image_xpm.h
GetXwdImage
Image * GetXwdImage(const char *name, ColorPair cp)
Definition
image_xwd.c:30
image_xwd.h
LookInNameList
void * LookInNameList(name_list *list_head, const char *name)
Definition
list.c:130
AddToList
void AddToList(name_list **list_head, const char *name, void *ptr)
Definition
list.c:63
list.h
screen.h
ColorPair
Definition
ctwm.h:140
ColorPair::back
Pixel back
Definition
ctwm.h:141
ColorPair::fore
Pixel fore
Definition
ctwm.h:141
Image
Definition
image.h:9
Image::mask
Pixmap mask
Definition
image.h:11
Image::height
int height
Definition
image.h:13
Image::pixmap
Pixmap pixmap
Definition
image.h:10
Image::next
Image * next
Definition
image.h:14
Image::width
int width
Definition
image.h:12
name_list
Definition
list.h:20
image.c
Generated by
1.18.0