ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/background.C
(Generate patch)

Comparing rxvt-unicode/src/background.C (file contents):
Revision 1.196 by sf-exg, Tue Jan 10 18:50:14 2012 UTC vs.
Revision 1.201 by sf-exg, Sat Feb 4 21:47:06 2012 UTC

20 * You should have received a copy of the GNU General Public License 20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software 21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *---------------------------------------------------------------------*/ 23 *---------------------------------------------------------------------*/
24 24
25#include <cmath> 25#include <math.h>
26#include "../config.h" /* NECESSARY */ 26#include "../config.h" /* NECESSARY */
27#include "rxvt.h" /* NECESSARY */ 27#include "rxvt.h" /* NECESSARY */
28 28
29#if XRENDER 29#if XRENDER
30# include <X11/extensions/Xrender.h> 30# include <X11/extensions/Xrender.h>
58# endif 58# endif
59 59
60void 60void
61rxvt_term::bg_destroy () 61rxvt_term::bg_destroy ()
62{ 62{
63#ifdef HAVE_AFTERIMAGE
64 if (original_asim)
65 safe_asimage_destroy (original_asim);
66 if (asv)
67 destroy_asvisual (asv, 0);
68 if (asimman)
69 destroy_image_manager (asimman, 0);
70#endif
71
72#ifdef HAVE_PIXBUF 63#ifdef HAVE_PIXBUF
73 if (pixbuf) 64 if (pixbuf)
74 g_object_unref (pixbuf); 65 g_object_unref (pixbuf);
75#endif 66#endif
76 67
129 120
130 return false; 121 return false;
131} 122}
132 123
133# ifdef BG_IMAGE_FROM_FILE 124# ifdef BG_IMAGE_FROM_FILE
134static inline bool
135check_set_scale_value (int geom_flags, int flag, unsigned int &scale, unsigned int new_value)
136{
137 if (geom_flags & flag)
138 {
139 if (new_value > 1000)
140 new_value = 1000;
141 if (new_value != scale)
142 {
143 scale = new_value;
144 return true;
145 }
146 }
147 return false;
148}
149
150static inline bool
151check_set_align_value (int geom_flags, int flag, int &align, int new_value)
152{
153 if (geom_flags & flag)
154 {
155 if (new_value < -100)
156 new_value = -100;
157 else if (new_value > 200)
158 new_value = 200;
159 if (new_value != align)
160 {
161 align = new_value;
162 return true;
163 }
164 }
165 return false;
166}
167
168static inline int 125static inline int
169make_align_position (int align, int window_size, int image_size) 126make_align_position (int align, int window_size, int image_size)
170{ 127{
171 int diff = window_size - image_size; 128 int diff = window_size - image_size;
172 int smaller = min (image_size, window_size); 129 int smaller = min (image_size, window_size);
191 src_pos = -pos; 148 src_pos = -pos;
192 dst_pos = 0; 149 dst_pos = 0;
193 dst_size += pos; 150 dst_size += pos;
194 } 151 }
195 152
196 if (dst_pos + dst_size > target_size)
197 dst_size = target_size - dst_pos; 153 min_it (dst_size, target_size - dst_pos);
198 return src_pos; 154 return src_pos;
199} 155}
200 156
201bool 157bool
202rxvt_term::bg_set_geometry (const char *geom, bool update) 158rxvt_term::bg_set_geometry (const char *geom, bool update)
203{ 159{
204 bool changed = false; 160 bool changed = false;
205 int geom_flags = 0; 161 int geom_flags = 0;
206 int x = 0, y = 0; 162 int x = h_align;
163 int y = v_align;
207 unsigned int w = 0, h = 0; 164 unsigned int w = h_scale;
165 unsigned int h = v_scale;
208 unsigned long new_flags = 0; 166 unsigned long new_flags = 0;
209 167
210 if (geom == NULL) 168 if (geom == NULL)
211 return false; 169 return false;
212 170
321 w = h = defaultScale; 279 w = h = defaultScale;
322 else if (!(geom_flags & HeightValue)) 280 else if (!(geom_flags & HeightValue))
323 h = w; 281 h = w;
324 else if (!(geom_flags & WidthValue)) 282 else if (!(geom_flags & WidthValue))
325 w = h; 283 w = h;
326
327 geom_flags |= WidthValue|HeightValue|XValue|YValue;
328 } 284 }
329 285
330 if (check_set_scale_value (geom_flags, WidthValue, h_scale, w)) changed = true; 286 min_it (w, 1000);
331 if (check_set_scale_value (geom_flags, HeightValue, v_scale, h)) changed = true; 287 min_it (h, 1000);
332 if (check_set_align_value (geom_flags, XValue, h_align, x)) changed = true; 288 clamp_it (x, -100, 200);
333 if (check_set_align_value (geom_flags, YValue, v_align, y)) changed = true; 289 clamp_it (y, -100, 200);
334 290
335 if (new_flags != bg_flags) 291 if (bg_flags != new_flags
292 || h_scale != w
293 || v_scale != h
294 || h_align != x
295 || v_align != y)
336 { 296 {
337 bg_flags = new_flags; 297 bg_flags = new_flags;
298 h_scale = w;
299 v_scale = h;
300 h_align = x;
301 v_align = y;
338 changed = true; 302 changed = true;
339 } 303 }
340 304
341 return changed; 305 return changed;
342} 306}
377 || h_scale || v_scale 341 || h_scale || v_scale
378 || (!(bg_flags & BG_ROOT_ALIGN) && (h_align || v_align)) 342 || (!(bg_flags & BG_ROOT_ALIGN) && (h_align || v_align))
379 || w > target_width || h > target_height) 343 || w > target_width || h > target_height)
380 bg_flags |= BG_IS_SIZE_SENSITIVE; 344 bg_flags |= BG_IS_SIZE_SENSITIVE;
381} 345}
382
383# ifdef HAVE_AFTERIMAGE
384bool
385rxvt_term::render_image (unsigned long tr_flags)
386{
387 init_asv ();
388
389 ASImage *background = NULL;
390 ARGB32 background_tint = TINT_LEAVE_SAME;
391
392# ifdef ENABLE_TRANSPARENCY
393 if (tr_flags)
394 background = pixmap2ximage (asv, bg_pixmap, 0, 0, bg_pmap_width, bg_pmap_height, AllPlanes, 100);
395
396 if (tr_flags & BG_NEEDS_TINT)
397 {
398 ShadingInfo as_shade;
399 as_shade.shading = shade;
400
401 rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC);
402 if (bg_flags & BG_TINT_SET)
403 tint.get (c);
404 as_shade.tintColor.red = c.r;
405 as_shade.tintColor.green = c.g;
406 as_shade.tintColor.blue = c.b;
407
408 background_tint = shading2tint32 (&as_shade);
409 }
410
411 if ((tr_flags & BG_NEEDS_BLUR) && background != NULL)
412 {
413 ASImage *tmp = blur_asimage_gauss (asv, background, h_blurRadius, v_blurRadius, 0xFFFFFFFF,
414 ASA_XImage,
415 100, ASIMAGE_QUALITY_DEFAULT);
416 if (tmp)
417 {
418 destroy_asimage (&background);
419 background = tmp;
420 }
421 }
422# endif
423
424 ASImage *result = 0;
425
426 int target_width = szHint.width;
427 int target_height = szHint.height;
428 int new_pmap_width = target_width;
429 int new_pmap_height = target_height;
430
431 int x = 0;
432 int y = 0;
433 int w = 0;
434 int h = 0;
435
436 if (original_asim)
437 get_image_geometry (original_asim->width, original_asim->height, w, h, x, y);
438
439 if (!original_asim
440 || (!(bg_flags & BG_ROOT_ALIGN)
441 && (x >= target_width
442 || y >= target_height
443 || x + w <= 0
444 || y + h <= 0)))
445 {
446 if (background)
447 {
448 new_pmap_width = background->width;
449 new_pmap_height = background->height;
450 result = background;
451
452 if (background_tint != TINT_LEAVE_SAME)
453 {
454 ASImage *tmp = tile_asimage (asv, background, 0, 0,
455 target_width, target_height, background_tint,
456 ASA_XImage, 100, ASIMAGE_QUALITY_DEFAULT);
457 if (tmp)
458 result = tmp;
459 }
460 }
461 else
462 new_pmap_width = new_pmap_height = 0;
463 }
464 else
465 {
466 result = original_asim;
467
468 if (w != original_asim->width
469 || h != original_asim->height)
470 {
471 result = scale_asimage (asv, original_asim,
472 w, h,
473 ASA_XImage,
474 100, ASIMAGE_QUALITY_DEFAULT);
475 }
476
477 if (background == NULL)
478 {
479 if (bg_flags & BG_TILE)
480 {
481 /* if tiling - pixmap has to be sized exactly as the image,
482 but there is no need to make it bigger than the window! */
483 new_pmap_width = min (result->width, target_width);
484 new_pmap_height = min (result->height, target_height);
485
486 /* we also need to tile our image in both directions */
487 ASImage *tmp = tile_asimage (asv, result,
488 (int)result->width - x,
489 (int)result->height - y,
490 new_pmap_width,
491 new_pmap_height,
492 TINT_LEAVE_SAME, ASA_XImage,
493 100, ASIMAGE_QUALITY_DEFAULT);
494 if (tmp)
495 {
496 if (result != original_asim)
497 destroy_asimage (&result);
498
499 result = tmp;
500 }
501 }
502 }
503 else
504 {
505 /* if blending background and image - pixmap has to be sized same as target window */
506 ASImageLayer *layers = create_image_layers (2);
507
508 layers[0].im = background;
509 layers[0].clip_width = target_width;
510 layers[0].clip_height = target_height;
511 layers[0].tint = background_tint;
512 layers[1].im = result;
513
514 if (bg_flags & BG_TILE)
515 {
516 /* tile horizontally */
517 while (x > 0) x -= (int)result->width;
518 layers[1].dst_x = x;
519 layers[1].clip_width = result->width+target_width;
520 }
521 else
522 {
523 /* clip horizontally */
524 layers[1].dst_x = x;
525 layers[1].clip_width = result->width;
526 }
527
528 if (bg_flags & BG_TILE)
529 {
530 while (y > 0) y -= (int)result->height;
531 layers[1].dst_y = y;
532 layers[1].clip_height = result->height + target_height;
533 }
534 else
535 {
536 layers[1].dst_y = y;
537 layers[1].clip_height = result->height;
538 }
539
540 if (rs[Rs_blendtype])
541 {
542 layers[1].merge_scanlines = blend_scanlines_name2func (rs[Rs_blendtype]);
543 if (layers[1].merge_scanlines == NULL)
544 layers[1].merge_scanlines = alphablend_scanlines;
545 }
546
547 ASImage *tmp = merge_layers (asv, layers, 2, target_width, target_height,
548 ASA_XImage, 0, ASIMAGE_QUALITY_DEFAULT);
549
550 if (tmp)
551 {
552 if (result != original_asim)
553 destroy_asimage (&result);
554
555 result = tmp;
556 }
557
558 free (layers);
559 }
560 }
561
562 bool ret = false;
563
564 if (result)
565 {
566 XGCValues gcv;
567 GC gc;
568
569 /* create Pixmap */
570 if (bg_pixmap == None
571 || bg_pmap_width != new_pmap_width
572 || bg_pmap_height != new_pmap_height)
573 {
574 if (bg_pixmap)
575 XFreePixmap (dpy, bg_pixmap);
576 bg_pixmap = XCreatePixmap (dpy, vt, new_pmap_width, new_pmap_height, depth);
577 bg_pmap_width = new_pmap_width;
578 bg_pmap_height = new_pmap_height;
579 }
580 /* fill with background color (if result's not completely overlapping it) */
581 gcv.foreground = pix_colors[Color_bg];
582 gc = XCreateGC (dpy, vt, GCForeground, &gcv);
583
584 int src_x = 0, src_y = 0, dst_x = 0, dst_y = 0;
585 int dst_width = result->width, dst_height = result->height;
586 if (background == NULL)
587 {
588 if (!(bg_flags & BG_TILE))
589 {
590 src_x = make_clip_rectangle (x, result->width , new_pmap_width , dst_x, dst_width );
591 src_y = make_clip_rectangle (y, result->height, new_pmap_height, dst_y, dst_height);
592 }
593
594 if (dst_x > 0 || dst_y > 0
595 || dst_x + dst_width < new_pmap_width
596 || dst_y + dst_height < new_pmap_height)
597 XFillRectangle (dpy, bg_pixmap, gc, 0, 0, new_pmap_width, new_pmap_height);
598 }
599
600 /* put result on pixmap */
601 if (dst_x < new_pmap_width && dst_y < new_pmap_height)
602 asimage2drawable (asv, bg_pixmap, result, gc, src_x, src_y, dst_x, dst_y, dst_width, dst_height, True);
603
604 if (result != background && result != original_asim)
605 destroy_asimage (&result);
606
607 XFreeGC (dpy, gc);
608
609 ret = true;
610 }
611
612 if (background)
613 destroy_asimage (&background);
614
615 return ret;
616}
617# endif /* HAVE_AFTERIMAGE */
618 346
619# ifdef HAVE_PIXBUF 347# ifdef HAVE_PIXBUF
620bool 348bool
621rxvt_term::pixbuf_to_pixmap (GdkPixbuf *pixbuf, Pixmap pixmap, GC gc, 349rxvt_term::pixbuf_to_pixmap (GdkPixbuf *pixbuf, Pixmap pixmap, GC gc,
622 int src_x, int src_y, int dst_x, int dst_y, 350 int src_x, int src_y, int dst_x, int dst_y,
880 char *f = rxvt_temp_buf<char> (len + 1); 608 char *f = rxvt_temp_buf<char> (len + 1);
881 memcpy (f, file, len); 609 memcpy (f, file, len);
882 f[len] = '\0'; 610 f[len] = '\0';
883 file = f; 611 file = f;
884 } 612 }
885
886# ifdef HAVE_AFTERIMAGE
887 if (!asimman)
888 asimman = create_generic_imageman (rs[Rs_path]);
889 ASImage *image = get_asimage (asimman, file, 0xFFFFFFFF, 100);
890 if (image)
891 {
892 if (original_asim)
893 safe_asimage_destroy (original_asim);
894 original_asim = image;
895 bg_flags |= BG_IS_FROM_FILE | BG_CLIENT_RENDER;
896 ret = true;
897 }
898# endif
899 613
900# ifdef HAVE_PIXBUF 614# ifdef HAVE_PIXBUF
901 GdkPixbuf *image = gdk_pixbuf_new_from_file (file, NULL); 615 GdkPixbuf *image = gdk_pixbuf_new_from_file (file, NULL);
902 if (image) 616 if (image)
903 { 617 {
1316 if (bg_flags & BG_NEEDS_TINT) 1030 if (bg_flags & BG_NEEDS_TINT)
1317 { 1031 {
1318 if (tint_pixmap (bg_pixmap, visual, window_width, window_height)) 1032 if (tint_pixmap (bg_pixmap, visual, window_width, window_height))
1319 result &= ~BG_NEEDS_TINT; 1033 result &= ~BG_NEEDS_TINT;
1320 } 1034 }
1321# ifndef HAVE_AFTERIMAGE
1322 if (result & BG_NEEDS_TINT) 1035 if (result & BG_NEEDS_TINT)
1323 { 1036 {
1324 XImage *ximage = XGetImage (dpy, bg_pixmap, 0, 0, bg_pmap_width, bg_pmap_height, AllPlanes, ZPixmap); 1037 XImage *ximage = XGetImage (dpy, bg_pixmap, 0, 0, bg_pmap_width, bg_pmap_height, AllPlanes, ZPixmap);
1325 if (ximage) 1038 if (ximage)
1326 { 1039 {
1329 1042
1330 XPutImage (dpy, bg_pixmap, gc, ximage, 0, 0, 0, 0, ximage->width, ximage->height); 1043 XPutImage (dpy, bg_pixmap, gc, ximage, 0, 0, 0, 0, ximage->width, ximage->height);
1331 XDestroyImage (ximage); 1044 XDestroyImage (ximage);
1332 } 1045 }
1333 } 1046 }
1334# endif
1335 } /* server side rendering completed */ 1047 } /* server side rendering completed */
1336 1048
1337 XFreeGC (dpy, gc); 1049 XFreeGC (dpy, gc);
1338 } 1050 }
1339 1051
1363# ifdef ENABLE_TRANSPARENCY 1075# ifdef ENABLE_TRANSPARENCY
1364 if (bg_flags & BG_IS_TRANSPARENT) 1076 if (bg_flags & BG_IS_TRANSPARENT)
1365 { 1077 {
1366 /* we need to re-generate transparency pixmap in that case ! */ 1078 /* we need to re-generate transparency pixmap in that case ! */
1367 tr_flags = make_transparency_pixmap (); 1079 tr_flags = make_transparency_pixmap ();
1368 if (tr_flags == 0) 1080 if (tr_flags)
1369 return false;
1370 bg_flags |= BG_IS_VALID; 1081 bg_flags |= BG_IS_VALID;
1371 } 1082 }
1372# endif 1083# endif
1373 1084
1374# ifdef BG_IMAGE_FROM_FILE 1085# ifdef BG_IMAGE_FROM_FILE
1375 if ((bg_flags & BG_IS_FROM_FILE) 1086 if ((bg_flags & BG_IS_FROM_FILE)
1421#endif 1132#endif
1422} 1133}
1423 1134
1424#endif /* HAVE_BG_PIXMAP */ 1135#endif /* HAVE_BG_PIXMAP */
1425 1136
1426#if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE) 1137#ifdef ENABLE_TRANSPARENCY
1427/* based on code from aterm-0.4.2 */ 1138/* based on code from aterm-0.4.2 */
1428 1139
1429static inline void 1140static inline void
1430fill_lut (uint32_t *lookup, uint32_t mask, int sh, unsigned short low, unsigned short high) 1141fill_lut (uint32_t *lookup, uint32_t mask, int sh, unsigned short low, unsigned short high)
1431{ 1142{
1577 } 1288 }
1578 } 1289 }
1579 1290
1580 free (lookup); 1291 free (lookup);
1581} 1292}
1582#endif /* defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE) */ 1293#endif /* ENABLE_TRANSPARENCY */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines