--- rxvt-unicode/src/perl/background 2012/06/10 13:58:05 1.47 +++ rxvt-unicode/src/perl/background 2012/06/12 18:25:57 1.53 @@ -4,8 +4,6 @@ #:META:X_RESOURCE:%.border:boolean:respect the terminal border #:META:X_RESOURCE:%.interval:seconds:minimum time between updates -#TODO: once, rootalign - =head1 NAME background - manage terminal background @@ -61,7 +59,7 @@ image to the window size, so it relies on the window size and will be reevaluated each time it is changed, but not when it moves for example. That ensures that the picture always fills the terminal, even -after it's size changes. +after its size changes. =head2 EXPRESSIONS @@ -119,7 +117,7 @@ scale 0.5, 2, load "$HOME/mypic.png" -Other effects than scalign are also readily available, for exmaple, you can +Other effects than scaling are also readily available, for example, you can tile the image to fill the whole window, instead of resizing it: tile load "$HOME/mypic.png" @@ -155,7 +153,7 @@ image, it will forget about the first one. This allows you to either speed things up by keeping multiple images in -memory, or comserve memory by loading images more often. +memory, or conserve memory by loading images more often. For example, you can keep two images in memory and use a random one like this: @@ -195,7 +193,7 @@ =item --background-interval seconds -Since some operations in the underlying XRender extension can effetively +Since some operations in the underlying XRender extension can effectively freeze your X-server for prolonged time, this extension enforces a minimum time between updates, which is normally about 0.1 seconds. @@ -206,6 +204,8 @@ =cut +our %_IMG_CACHE; +our %_ONCE_CACHE; our $HOME; our ($self, $old, $new); our ($x, $y, $w, $h); @@ -253,7 +253,7 @@ sub root() { $new->{rootpmap_sensitive} = 1; - die "root op not supported, exg, we need you"; + $self->new_img_from_root } =item solid $colour @@ -287,8 +287,6 @@ $_[0]->clone } -=back - =head2 TILING MODES The following operators modify the tiling mode of an image, that is, the @@ -327,7 +325,7 @@ background pixels outside the image unchanged. Example: load an image and display it in the upper left corner. The rest -of the space is left "empty" (transparent or wahtever your compisotr does +of the space is left "empty" (transparent or whatever your compositor does in alpha mode, else background colour). pad load "mybg.png" @@ -335,7 +333,7 @@ =item extend $img Extends the image over the whole plane, using the closest pixel in the -area outside the image. This mode is mostly useful when you more complex +area outside the image. This mode is mostly useful when you use more complex filtering operations and want the pixels outside the image to have the same values as the pixels near the edge. @@ -436,7 +434,7 @@ Example: load some image and rotate it according to the time of day (as if it were the hour pointer of a clock). Update this image every minute. - again 60; rotate TW, TH, 50, 50, (now % 86400) * -720 / 86400, scale load "myclock.png" + again 60; rotate 50, 50, (now % 86400) * -720 / 86400, scale load "myclock.png" =item counter $seconds @@ -633,6 +631,27 @@ move -TX, -TY, $_[0] } +=item rotate $center_x, $center_y, $degrees + +Rotates the image by C<$degrees> degrees, counter-clockwise, around the +pointer at C<$center_x> and C<$center_y> (specified as factor of image +width/height). + +#TODO# new width, height, maybe more operators? + +Example: rotate the image by 90 degrees + +=cut + + sub rotate($$$$) { + my $img = pop; + $img->rotate ( + $_[0] * $img->w, + $_[1] * $img->h, + $_[2] * (3.14159265 / 180), + ) + } + =back =head2 COLOUR MODIFICATIONS @@ -676,7 +695,7 @@ it. Useful range is from -1 to 1 - the former results in a black, the latter in a white picture. -Due to idiosynchrasies in the underlying XRender extension, biases less +Due to idiosyncrasies in the underlying XRender extension, biases less than zero can be I slow. =cut @@ -685,8 +704,8 @@ my $img = pop; my ($r, $g, $b, $a) = @_; - ($g, $b) = ($r, $r) if @_ < 4; - $a = 1 if @_ < 5; + ($g, $b) = ($r, $r) if @_ < 3; + $a = 1 if @_ < 4; $img = $img->clone; $img->contrast ($r, $g, $b, $a); @@ -697,8 +716,8 @@ my $img = pop; my ($r, $g, $b, $a) = @_; - ($g, $b) = ($r, $r) if @_ < 4; - $a = 1 if @_ < 5; + ($g, $b) = ($r, $r) if @_ < 3; + $a = 1 if @_ < 4; $img = $img->clone; $img->brightness ($r, $g, $b, $a); @@ -724,28 +743,52 @@ $img->blur ($_[0], @_ >= 2 ? $_[1] : $_[0]) } -=item rotate $new_width, $new_height, $center_x, $center_y, $degrees +=back -Rotates the image by C<$degrees> degrees, counter-clockwise, around the -pointer at C<$center_x> and C<$center_y> (specified as factor of image -width/height), generating a new image with width C<$new_width> and height -C<$new_height>. +=head2 OTHER STUFF -#TODO# new width, height, maybe more operators? +Anything that didn't fit any of the other categories, even after appliyng +force and closing our eyes. -Example: rotate the image by 90 degrees +=over 4 + +=item once { ... } + +This function takes a code block as argument, that is, one or more +statements enclosed by braces. + +The trick is that this code block is only evaluated once - future calls +will simply return the original image (yes, it should only be used with +images). + +This can be extremely useful to avoid redoign the same slow operations +again and again- for example, if your background expression takes the root +background, blurs it and then root-aligns it it would have to blur the +root background on every window move or resize. + +Putting the blur into a C block will make sure the blur is only done +once: + + rootlign once { blur 10, root } + +This leaves the question of how to force reevaluation of the block, in +case the root background changes: Right now, all once blocks forget that +they ahve been executed before each time the root background changes (if +the expression is sensitive to that) or when C is called. + +=item once_again + +Resets all C block as if they had never been called, i.e. on the +next call they will be reevaluated again. =cut - sub rotate($$$$$$) { - my $img = pop; - $img->rotate ( - $_[0], - $_[1], - $_[2] * $img->w, - $_[3] * $img->h, - $_[4] * (3.14159265 / 180), - ) + sub once(&) { + $_ONCE_CACHE{$_[0]+0} ||= $_[0]() + } + + sub once_again() { + %_ONCE_CACHE = (); } =back @@ -798,7 +841,7 @@ my $img = eval { $self->{expr}->() }; warn $@ if $@;#d# - die if !UNIVERSAL::isa $img, "urxvt::img"; + die "background-expr did not return an image.\n" if !UNIVERSAL::isa $img, "urxvt::img"; $state->{size_sensitive} = 1 if $img->repeat_mode != urxvt::RepeatNormal; @@ -861,6 +904,9 @@ my $expr = $self->x_resource ("%.expr") or return; + $self->has_render + or die "background extension needs RENDER extension 0.10 or higher, ignoring background-expr.\n"; + $self->set_expr (parse_expr $expr); $self->{border} = $self->x_resource_boolean ("%.border");