1 | /*--------------------------------*-C-*---------------------------------* |
1 | /*----------------------------------------------------------------------* |
2 | * File: xpm.C |
2 | * File: xpm.C |
3 | *----------------------------------------------------------------------* |
3 | *----------------------------------------------------------------------* |
4 | * |
4 | * |
5 | * All portions of code are copyright by their respective author/s. |
5 | * All portions of code are copyright by their respective author/s. |
6 | * Copyright (c) 1997 Carsten Haitzler <raster@zip.com.au> |
6 | * Copyright (c) 1997 Carsten Haitzler <raster@zip.com.au> |
7 | * Copyright (c) 1997,1998 Oezguer Kesim <kesim@math.fu-berlin.de> |
7 | * Copyright (c) 1997,1998 Oezguer Kesim <kesim@math.fu-berlin.de> |
8 | * Copyright (c) 1998-2001 Geoff Wing <gcw@pobox.com> |
8 | * Copyright (c) 1998-2001 Geoff Wing <gcw@pobox.com> |
|
|
9 | * Copyright (c) 2005-2006 Marc Lehmann <pcg@goof.com> |
9 | * |
10 | * |
10 | * This program is free software; you can redistribute it and/or modify |
11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by |
12 | * it under the terms of the GNU General Public License as published by |
12 | * the Free Software Foundation; either version 2 of the License, or |
13 | * the Free Software Foundation; either version 2 of the License, or |
13 | * (at your option) any later version. |
14 | * (at your option) any later version. |
… | |
… | |
55 | int flags, changed = 0; |
56 | int flags, changed = 0; |
56 | int x = 0, y = 0; |
57 | int x = 0, y = 0; |
57 | unsigned int w = 0, h = 0; |
58 | unsigned int w = 0, h = 0; |
58 | unsigned int n; |
59 | unsigned int n; |
59 | char *p; |
60 | char *p; |
60 | bgPixmap_t *bgpixmap = & (bgPixmap); |
61 | bgPixmap_t *bgpixmap = &bgPixmap; |
61 | |
62 | |
62 | #define MAXLEN_GEOM sizeof("[10000x10000+10000+10000]") |
63 | #define MAXLEN_GEOM sizeof("[10000x10000+10000+10000]") |
63 | |
64 | |
64 | if (geom == NULL) |
65 | if (geom == NULL) |
65 | return 0; |
66 | return 0; |
… | |
… | |
77 | |
78 | |
78 | if ((p = strchr (geom, ';')) == NULL) |
79 | if ((p = strchr (geom, ';')) == NULL) |
79 | p = strchr (geom, '\0'); |
80 | p = strchr (geom, '\0'); |
80 | |
81 | |
81 | n = (p - geom); |
82 | n = (p - geom); |
82 | if (n <= MAXLEN_GEOM) |
83 | if (n < MAXLEN_GEOM) |
83 | { |
84 | { |
84 | strncpy (str, geom, n); |
85 | strncpy (str, geom, n); |
85 | str[n] = '\0'; |
86 | str[n] = '\0'; |
86 | |
87 | |
|
|
88 | if (strcmp(str, "auto") == 0) |
|
|
89 | { |
|
|
90 | if (!bgpixmap->auto_resize) |
|
|
91 | changed++; |
|
|
92 | bgpixmap->auto_resize = True ; |
|
|
93 | w = szHint.width ; |
|
|
94 | h = szHint.height ; |
|
|
95 | flags = WidthValue|HeightValue ; |
|
|
96 | } |
|
|
97 | else |
|
|
98 | { |
|
|
99 | bgpixmap->auto_resize = False ; |
87 | flags = XParseGeometry (str, &x, &y, &w, &h); |
100 | flags = XParseGeometry (str, &x, &y, &w, &h); |
|
|
101 | } |
88 | |
102 | |
89 | if (!flags) |
103 | if (!flags) |
90 | { |
104 | { |
91 | flags |= WidthValue; |
105 | flags |= WidthValue; |
92 | w = 0; |
106 | w = 0; |
… | |
… | |
168 | { |
182 | { |
169 | XGCValues gcvalue; |
183 | XGCValues gcvalue; |
170 | GC gc; |
184 | GC gc; |
171 | |
185 | |
172 | if (pixmap != None) |
186 | if (pixmap != None) |
|
|
187 | { |
173 | XFreePixmap (xdisp, pixmap); |
188 | XFreePixmap (dpy, pixmap); |
|
|
189 | pixmap = None ; |
|
|
190 | } |
174 | |
191 | |
175 | if (bgPixmap.pixmap == None) |
192 | if (bgPixmap.pixmap == None) |
176 | { /* So be it: I'm not using pixmaps */ |
193 | { /* So be it: I'm not using pixmaps */ |
177 | pixmap = None; |
194 | pixmap = None; |
178 | |
195 | |
|
|
196 | #ifdef TRANSPARENT |
179 | if (!OPTION (Opt_transparent) || !am_transparent) |
197 | if (!option (Opt_transparent) || !am_transparent) |
|
|
198 | #endif |
180 | XSetWindowBackground (xdisp, vt, pix_colors[Color_bg]); |
199 | XSetWindowBackground (dpy, vt, pix_colors[Color_bg]); |
181 | |
200 | |
182 | return; |
201 | return; |
183 | } |
202 | } |
184 | |
203 | |
185 | gcvalue.foreground = pix_colors[Color_bg]; |
204 | gcvalue.foreground = pix_colors[Color_bg]; |
186 | gc = XCreateGC (xdisp, vt, GCForeground, &gcvalue); |
205 | gc = XCreateGC (dpy, vt, GCForeground, &gcvalue); |
187 | |
206 | |
188 | if (bgPixmap.pixmap != None) |
207 | if (bgPixmap.pixmap != None) |
189 | { /* we have a specified pixmap */ |
208 | { /* we have a specified pixmap */ |
190 | unsigned int w = bgPixmap.w, h = bgPixmap.h, |
209 | unsigned int w = bgPixmap.w, h = bgPixmap.h, |
191 | x = bgPixmap.x, y = bgPixmap.y; |
210 | x = bgPixmap.x, y = bgPixmap.y; |
192 | unsigned int xpmh = xpmAttr.height, |
211 | unsigned int xpmh = xpmAttr.height, |
193 | xpmw = xpmAttr.width; |
212 | xpmw = xpmAttr.width; |
194 | |
213 | |
|
|
214 | if (bgPixmap.auto_resize) |
|
|
215 | { |
|
|
216 | w = szHint.width ; |
|
|
217 | h = szHint.height ; |
|
|
218 | } |
195 | /* |
219 | /* |
196 | * don't zoom pixmap too much nor expand really small pixmaps |
220 | * don't zoom pixmap too much nor expand really small pixmaps |
197 | */ |
221 | */ |
198 | if (w > 32767 || h > 32767) |
222 | if (w > 32767 || h > 32767) |
199 | w = 1; |
223 | w = 1; |
… | |
… | |
202 | w = 0; /* tile */ |
226 | w = 0; /* tile */ |
203 | |
227 | |
204 | if (!w) |
228 | if (!w) |
205 | { |
229 | { |
206 | /* basic X tiling - let the X server do it */ |
230 | /* basic X tiling - let the X server do it */ |
207 | pixmap = XCreatePixmap (xdisp, vt, xpmw, xpmh, depth); |
231 | pixmap = XCreatePixmap (dpy, vt, xpmw, xpmh, depth); |
208 | |
232 | |
209 | XCopyArea (xdisp, bgPixmap.pixmap, pixmap, gc, x, y, xpmw - x, xpmh - y, 0, 0); |
233 | XCopyArea (dpy, bgPixmap.pixmap, pixmap, gc, x, y, xpmw - x, xpmh - y, 0, 0); |
210 | XCopyArea (xdisp, bgPixmap.pixmap, pixmap, gc, x, 0, xpmw - x, y, 0, xpmh - y); |
234 | XCopyArea (dpy, bgPixmap.pixmap, pixmap, gc, x, 0, xpmw - x, y, 0, xpmh - y); |
211 | XCopyArea (xdisp, bgPixmap.pixmap, pixmap, gc, 0, y, x, xpmh - y, xpmw - x, 0); |
235 | XCopyArea (dpy, bgPixmap.pixmap, pixmap, gc, 0, y, x, xpmh - y, xpmw - x, 0); |
212 | XCopyArea (xdisp, bgPixmap.pixmap, pixmap, gc, 0, 0, x, y, xpmw - x, xpmh - y); |
236 | XCopyArea (dpy, bgPixmap.pixmap, pixmap, gc, 0, 0, x, y, xpmw - x, xpmh - y); |
213 | } |
237 | } |
214 | else |
238 | else |
|
|
239 | #ifdef HAVE_AFTERIMAGE |
|
|
240 | #ifdef TRANSPARENT |
|
|
241 | if (!option(Opt_transparent) || !am_transparent) |
|
|
242 | /* will do that in check_our_parents otherwise */ |
|
|
243 | #endif |
|
|
244 | { |
|
|
245 | ASImage *scaled_im = scale_asimage( display->asv, original_asim, w, h, ASA_XImage, 0, ASIMAGE_QUALITY_DEFAULT ); |
|
|
246 | if (scaled_im) |
|
|
247 | { |
|
|
248 | pixmap = asimage2pixmap( display->asv, display->root, scaled_im, gc, True ); |
|
|
249 | destroy_asimage( &scaled_im ); |
|
|
250 | } |
|
|
251 | } |
|
|
252 | #else /* HAVE_AFTERIMAGE */ |
215 | { |
253 | { |
216 | float incr, p; |
254 | float incr, p; |
217 | Pixmap tmp; |
255 | Pixmap tmp; |
218 | |
256 | |
219 | pixmap = XCreatePixmap (xdisp, vt, width, height, depth); |
257 | pixmap = XCreatePixmap (dpy, vt, width, height, depth); |
220 | /* |
258 | /* |
221 | * horizontal scaling |
259 | * horizontal scaling |
222 | */ |
260 | */ |
223 | rxvt_pixmap_incr (&w, &x, &incr, &p, width, xpmw); |
261 | rxvt_pixmap_incr (&w, &x, &incr, &p, width, xpmw); |
224 | |
262 | |
225 | tmp = XCreatePixmap (xdisp, vt, width, xpmh, depth); |
263 | tmp = XCreatePixmap (dpy, vt, width, xpmh, depth); |
226 | XFillRectangle (xdisp, tmp, gc, 0, 0, width, xpmh); |
264 | XFillRectangle (dpy, tmp, gc, 0, 0, width, xpmh); |
227 | |
265 | |
228 | for ( /*nil */ ; x < w; x++, p += incr) |
266 | for ( /*nil */ ; x < w; x++, p += incr) |
229 | { |
267 | { |
230 | if (p >= xpmw) |
268 | if (p >= xpmw) |
231 | p = 0; |
269 | p = 0; |
232 | |
270 | |
233 | /* copy one column from the original pixmap to the tmp pixmap */ |
271 | /* copy one column from the original pixmap to the tmp pixmap */ |
234 | XCopyArea (xdisp, bgPixmap.pixmap, tmp, gc, (int)p, 0, 1, xpmh, (int)x, 0); |
272 | XCopyArea (dpy, bgPixmap.pixmap, tmp, gc, (int)p, 0, 1, xpmh, (int)x, 0); |
235 | } |
273 | } |
236 | |
274 | |
237 | /* |
275 | /* |
238 | * vertical scaling |
276 | * vertical scaling |
239 | */ |
277 | */ |
240 | rxvt_pixmap_incr (&h, &y, &incr, &p, height, xpmh); |
278 | rxvt_pixmap_incr (&h, &y, &incr, &p, height, xpmh); |
241 | |
279 | |
242 | if (y > 0) |
280 | if (y > 0) |
243 | XFillRectangle (xdisp, pixmap, gc, 0, 0, width, y); |
281 | XFillRectangle (dpy, pixmap, gc, 0, 0, width, y); |
244 | |
282 | |
245 | if (h < height) |
283 | if (h < height) |
246 | XFillRectangle (xdisp, pixmap, gc, 0, (int)h, width, height - h + 1); |
284 | XFillRectangle (dpy, pixmap, gc, 0, (int)h, width, height - h + 1); |
247 | |
285 | |
248 | for ( /*nil */ ; y < h; y++, p += incr) |
286 | for ( /*nil */ ; y < h; y++, p += incr) |
249 | { |
287 | { |
250 | if (p >= xpmh) |
288 | if (p >= xpmh) |
251 | p = 0; |
289 | p = 0; |
252 | |
290 | |
253 | /* copy one row from the tmp pixmap to the main pixmap */ |
291 | /* copy one row from the tmp pixmap to the main pixmap */ |
254 | XCopyArea (xdisp, tmp, pixmap, gc, 0, (int)p, width, 1, 0, (int)y); |
292 | XCopyArea (dpy, tmp, pixmap, gc, 0, (int)p, width, 1, 0, (int)y); |
255 | } |
293 | } |
256 | |
294 | |
257 | XFreePixmap (xdisp, tmp); |
295 | XFreePixmap (dpy, tmp); |
258 | } |
296 | } |
|
|
297 | #endif /* HAVE_AFTERIMAGE */ |
259 | } |
298 | } |
260 | |
299 | |
261 | XSetWindowBackgroundPixmap (xdisp, vt, pixmap); |
300 | XSetWindowBackgroundPixmap (dpy, vt, pixmap); |
262 | |
301 | |
263 | if (pixmap != None) |
|
|
264 | { |
|
|
265 | XFreePixmap (xdisp, pixmap); |
|
|
266 | pixmap = None; |
|
|
267 | } |
|
|
268 | |
|
|
269 | XFreeGC (xdisp, gc); |
302 | XFreeGC (dpy, gc); |
|
|
303 | #ifdef TRANSPARENT |
270 | am_transparent = 0; |
304 | am_transparent = 0; |
|
|
305 | #endif |
271 | } |
306 | } |
272 | |
307 | |
273 | /* |
308 | /* |
274 | * Calculate tiling sizes and increments |
309 | * Calculate tiling sizes and increments |
275 | * At start, p == 0, incr == xpmwidthheight |
310 | * At start, p == 0, incr == xpmwidthheight |
… | |
… | |
353 | |
388 | |
354 | assert (file != NULL); |
389 | assert (file != NULL); |
355 | |
390 | |
356 | if (bgPixmap.pixmap != None) |
391 | if (bgPixmap.pixmap != None) |
357 | { |
392 | { |
358 | XFreePixmap (display->display, bgPixmap.pixmap); |
393 | XFreePixmap (dpy, bgPixmap.pixmap); |
359 | bgPixmap.pixmap = None; |
394 | bgPixmap.pixmap = None; |
360 | } |
395 | } |
361 | |
396 | |
362 | XSetWindowBackground (display->display, vt, pix_colors[Color_bg]); |
397 | XSetWindowBackground (dpy, vt, pix_colors[Color_bg]); |
363 | |
398 | |
364 | if (*file != '\0') |
399 | if (*file != '\0') |
365 | { |
400 | { |
366 | /* XWindowAttributes attr; */ |
401 | /* XWindowAttributes attr; */ |
367 | |
402 | |
368 | /* |
403 | /* |
369 | * we already have the required attributes |
404 | * we already have the required attributes |
370 | */ |
405 | */ |
371 | /* XGetWindowAttributes (display->display, vt, &attr); */ |
406 | /* XGetWindowAttributes (dpy, vt, &attr); */ |
372 | |
407 | |
|
|
408 | #ifdef HAVE_AFTERIMAGE |
|
|
409 | if (asimman == NULL) |
|
|
410 | asimman = create_generic_imageman(rs[Rs_path]); |
|
|
411 | if ((f = strchr (file, ';')) == NULL) |
|
|
412 | original_asim = get_asimage( asimman, file, 0xFFFFFFFF, 100 ); |
|
|
413 | else |
|
|
414 | { |
|
|
415 | f = strndup( file, f - file ); |
|
|
416 | original_asim = get_asimage( asimman, f, 0xFFFFFFFF, 100 ); |
|
|
417 | free( f ); |
|
|
418 | } |
|
|
419 | if (original_asim) |
|
|
420 | { |
|
|
421 | bgPixmap.pixmap = asimage2pixmap( display->asv, display->root, original_asim, NULL, True ); |
|
|
422 | xpmAttr.width = original_asim->width ; |
|
|
423 | xpmAttr.height = original_asim->height ; |
|
|
424 | } |
|
|
425 | #else /* HAVE_AFTERIMAGE */ |
373 | xpmAttr.closeness = 30000; |
426 | xpmAttr.closeness = 30000; |
374 | xpmAttr.colormap = cmap; |
427 | xpmAttr.colormap = cmap; |
375 | xpmAttr.visual = visual; |
428 | xpmAttr.visual = visual; |
376 | xpmAttr.depth = depth; |
429 | xpmAttr.depth = depth; |
377 | xpmAttr.valuemask = (XpmCloseness | XpmColormap | XpmVisual |
430 | xpmAttr.valuemask = (XpmCloseness | XpmColormap | XpmVisual |
378 | | XpmDepth | XpmSize | XpmReturnPixels); |
431 | | XpmDepth | XpmSize | XpmReturnPixels); |
379 | |
432 | |
380 | /* search environment variables here too */ |
433 | /* search environment variables here too */ |
381 | f = (char *)rxvt_File_find (file, ".xpm", rs[Rs_path]); |
434 | f = (char *)rxvt_File_find (file, ".xpm", rs[Rs_path]); |
382 | if (f == NULL |
435 | if (f == NULL |
383 | || XpmReadFileToPixmap (display->display, display->root, f, |
436 | || XpmReadFileToPixmap (dpy, display->root, f, |
384 | &bgPixmap.pixmap, NULL, |
437 | &bgPixmap.pixmap, NULL, |
385 | &xpmAttr)) |
438 | &xpmAttr)) |
386 | { |
439 | { |
387 | char *p; |
440 | char *p; |
388 | |
441 | |
… | |
… | |
390 | if ((p = strchr (file, ';')) == NULL) |
443 | if ((p = strchr (file, ';')) == NULL) |
391 | p = strchr (file, '\0'); |
444 | p = strchr (file, '\0'); |
392 | |
445 | |
393 | rxvt_warn ("couldn't load XPM file \"%.*s\", ignoring.\n", (p - file), file); |
446 | rxvt_warn ("couldn't load XPM file \"%.*s\", ignoring.\n", (p - file), file); |
394 | } |
447 | } |
395 | |
|
|
396 | free (f); |
448 | free (f); |
|
|
449 | #endif /* HAVE_AFTERIMAGE */ |
397 | } |
450 | } |
398 | |
451 | |
399 | resize_pixmap (); |
452 | resize_pixmap (); |
400 | return bgPixmap.pixmap; |
453 | return bgPixmap.pixmap; |
401 | } |
454 | } |