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

Comparing rxvt-unicode/src/perl/background (file contents):
Revision 1.29 by root, Thu Jun 7 13:12:08 2012 UTC vs.
Revision 1.34 by root, Thu Jun 7 17:04:33 2012 UTC

1#! perl 1#! perl
2 2
3#:META:X_RESOURCE:%.expr:string:background expression 3#:META:X_RESOURCE:%.expr:string:background expression
4#:META:X_RESOURCE:%.enable:boolean:some boolean 4#:META:X_RESOURCE:%.border.:boolean:respect the terminal border
5#:META:X_RESOURCE:%.extra.:value:extra config 5
6=head1 background - manage terminal background
7
8=head2 SYNOPSIS
9
10 rxvt -background-expr 'background expression'
11 -background-border
12
13=head2 DESCRIPTION
14
15=head2 REFERENCE
16
17=cut
6 18
7our $EXPR; 19our $EXPR;
8#$EXPR = 'move W * 0.1, -H * 0.1, resize W * 0.5, H * 0.5, repeat_none load "opensource.png"'; 20#$EXPR = 'move W * 0.1, -H * 0.1, resize W * 0.5, H * 0.5, repeat_none load "opensource.png"';
9$EXPR = 'move -X, -Y, load "argb.png"'; 21$EXPR = 'move -TX, -TY, load "argb.png"';
10#$EXPR = ' 22#$EXPR = '
11# rotate W, H, 50, 50, counter 1/59.95, repeat_mirror, 23# rotate W, H, 50, 50, counter 1/59.95, repeat_mirror,
12# clip X, Y, W, H, repeat_mirror, 24# clip X, Y, W, H, repeat_mirror,
13# load "/root/pix/das_fette_schwein.jpg" 25# load "/root/pix/das_fette_schwein.jpg"
14#'; 26#';
15#$EXPR = 'solid "red"'; 27#$EXPR = 'solid "red"';
16#$EXPR = 'blur root, 10, 10' 28#$EXPR = 'blur root, 10, 10'
17#$EXPR = 'blur move (root, -x, -y), 5, 5' 29#$EXPR = 'blur move (root, -x, -y), 5, 5'
18#resize load "/root/pix/das_fette_schwein.jpg", w, h 30#resize load "/root/pix/das_fette_schwein.jpg", w, h
19 31
20use Safe;
21
22our ($bgdsl_self, $old, $new); 32our ($self, $old, $new);
23our ($x, $y, $w, $h); 33our ($x, $y, $w, $h);
24 34
25# enforce at least this interval between updates 35# enforce at least this interval between updates
26our $MIN_INTERVAL = 1/100; 36our $MIN_INTERVAL = 1/100;
27 37
28{ 38{
29 package urxvt::bgdsl; # background language 39 package urxvt::bgdsl; # background language
30 40
31=head2 PROVIDERS/GENERATORS 41=head2 PROVIDERS/GENERATORS
32 42
43These functions provide an image, by loading it from disk, grabbing it
44from the root screen or by simply generating it. They are used as starting
45points to get an image you can play with.
46
33=over 4 47=over 4
34 48
35=item load $path 49=item load $path
36 50
37Loads the image at the given C<$path>. The image is set to plane tiling 51Loads the image at the given C<$path>. The image is set to plane tiling
38mode. 52mode.
39 53
40 54Loaded images will be cached for one cycle.
41 55
42=cut 56=cut
43 57
44 sub load($) { 58 sub load($) {
45 my ($path) = @_; 59 my ($path) = @_;
46 60
47 $new->{load}{$path} = $old->{load}{$path} || $bgdsl_self->new_img_from_file ($path); 61 $new->{load}{$path} = $old->{load}{$path} || $self->new_img_from_file ($path);
48 } 62 }
63
64=item root
65
66Returns the root window pixmap, that is, hopefully, the background image
67of your screen. The image is set to extend mode.
68
69This function makes your expression root sensitive, that means it will be
70reevaluated when the bg image changes.
71
72=cut
49 73
50 sub root() { 74 sub root() {
51 $new->{rootpmap_sensitive} = 1; 75 $new->{rootpmap_sensitive} = 1;
52 die "root op not supported, exg, we need you"; 76 die "root op not supported, exg, we need you";
53 } 77 }
54 78
79=item solid $colour
80
81=item solid $width, $height, $colour
82
83Creates a new image and completely fills it with the given colour. The
84image is set to tiling mode.
85
86If <$width> and C<$height> are omitted, it creates a 1x1 image, which is
87useful for solid backgrounds or for use in filtering effects.
88
89=cut
90
55 sub solid($;$$) { 91 sub solid($$;$) {
92 my $colour = pop;
93
56 my $img = $bgdsl_self->new_img (urxvt::PictStandardARGB32, $_[1] || 1, $_[2] || 1); 94 my $img = $self->new_img (urxvt::PictStandardARGB32, $_[0] || 1, $_[1] || 1);
57 $img->fill ($_[0]); 95 $img->fill ($colour);
58 $img 96 $img
59 } 97 }
60 98
61=back 99=back
62 100
63=head2 VARIABLES 101=head2 VARIABLES
64 102
103The following functions provide variable data such as the terminal
104window dimensions. Most of them make your expression sensitive to some
105events, for example using C<TW> (terminal width) means your expression is
106evaluated again when the terminal is resized.
107
65=over 4 108=over 4
66 109
67=cut 110=item TX
68 111
112=item TY
113
114Return the X and Y coordinates of the terminal window (the terminal
115window is the full window by default, and the character area only when in
116border-respect mode).
117
118Using these functions make your expression sensitive to window moves.
119
120These functions are mainly useful to align images to the root window.
121
122Example: load an image and align it so it looks as if anchored to the
123background.
124
125 move -TX, -TY, load "mybg.png"
126
127=item TW
128
129Return the width (C<TW>) and height (C<TH>) of the terminal window (the
130terminal window is the full window by default, and the character area only
131when in border-respect mode).
132
133Using these functions make your expression sensitive to window resizes.
134
135These functions are mainly useful to scale images, or to clip images to
136the window size to conserve memory.
137
138Example: take the screen background, clip it to the window size, blur it a
139bit, align it to the window position and use it as background.
140
141 clip move -TX, -TY, blur 5, root
142
143=cut
144
69 sub X() { $new->{position_sensitive} = 1; $x } 145 sub TX() { $new->{position_sensitive} = 1; $x }
70 sub Y() { $new->{position_sensitive} = 1; $y } 146 sub TY() { $new->{position_sensitive} = 1; $y }
71 sub W() { $new->{size_sensitive} = 1; $w } 147 sub TW() { $new->{size_sensitive} = 1; $w }
72 sub H() { $new->{size_sensitive} = 1; $h } 148 sub TH() { $new->{size_sensitive} = 1; $h }
149
150=item now
151
152Returns the current time as (fractional) seconds since the epoch.
153
154Using this expression does I<not> make your expression sensitive to time,
155but the next two functions do.
156
157=item again $seconds
158
159When this function is used the expression will be reevaluated again in
160C<$seconds> seconds.
161
162Example: load some image and rotate it according to the time of day (as if it were
163the hour pointer of a clock). update this image every minute.
164
165 again 60; rotate TW, TH, 50, 50, (now % 86400) * -720 / 86400, scale load "myclock.png"
166
167=item counter $seconds
168
169Like C<again>, but also returns an increasing counter value, starting at
1700, which might be useful for some simple animation effects.
171
172=cut
73 173
74 sub now() { urxvt::NOW } 174 sub now() { urxvt::NOW }
75 175
76 sub again($) { 176 sub again($) {
77 $new->{again} = $_[0]; 177 $new->{again} = $_[0];
78 } 178 }
79 179
80 sub counter($) { 180 sub counter($) {
81 $new->{again} = $_[0]; 181 $new->{again} = $_[0];
82 $bgdsl_self->{counter} + 0 182 $self->{counter} + 0
83 } 183 }
84 184
85=back 185=back
86 186
87=head2 TILING MODES 187=head2 TILING MODES
93 193
94=item tile $img 194=item tile $img
95 195
96Tiles the whole plane with the image and returns this new image - or in 196Tiles the whole plane with the image and returns this new image - or in
97other words, it returns a copy of the image in plane tiling mode. 197other words, it returns a copy of the image in plane tiling mode.
198
199Example: load an image and tile it over the background, without
200resizing. The C<tile> call is superfluous because C<load> already defaults
201to tiling mode.
202
203 tile load "mybg.png"
98 204
99=item mirror $img 205=item mirror $img
100 206
101Similar to tile, but reflects the image each time it uses a new copy, so 207Similar to tile, but reflects the image each time it uses a new copy, so
102that top edges always touch top edges, right edges always touch right 208that top edges always touch top edges, right edges always touch right
103edges and so on (with normal tiling, left edges always touch right edges 209edges and so on (with normal tiling, left edges always touch right edges
104and top always touch bottom edges). 210and top always touch bottom edges).
105 211
212Exmaple: load an image and mirror it over the background, avoiding sharp
213edges at the image borders at the expense of mirroring the image itself
214
215 mirror load "mybg.png"
216
106=item pad $img 217=item pad $img
107 218
108Takes an image and modifies it so that all pixels outside the image area 219Takes an image and modifies it so that all pixels outside the image area
109become transparent. This mode is most useful when you want to place an 220become transparent. This mode is most useful when you want to place an
110image over another image or the background colour while leaving all 221image over another image or the background colour while leaving all
111background pixels outside the image unchanged. 222background pixels outside the image unchanged.
112 223
224Example: load an image and display it in the upper left corner. The rets
225of the space is left "empty" (transparent or wahtever your compisotr does
226in alpha mode, else background colour).
227
228 pad load "mybg.png"
229
113=item extend $img 230=item extend $img
114 231
115Extends the image over the whole plane, using the closest pixel in the 232Extends the image over the whole plane, using the closest pixel in the
116area outside the image. This mode is mostly useful when you more complex 233area outside the image. This mode is mostly useful when you more complex
117filtering operations and want the pixels outside the image to have the 234filtering operations and want the pixels outside the image to have the
118same values as the pixels near the edge. 235same values as the pixels near the edge.
119 236
237Example: just for curiosity, how does this pixel extension stuff work?
238
239 extend move 50, 50, load "mybg.png"
240
120=cut 241=cut
121 242
122 sub pad($) { 243 sub pad($) {
123 my $img = $_[0]->clone; 244 my $img = $_[0]->clone;
124 $img->repeat_mode (urxvt::RepeatNone); 245 $img->repeat_mode (urxvt::RepeatNone);
184 305
185=cut 306=cut
186 307
187 sub clip($;$$;$$) { 308 sub clip($;$$;$$) {
188 my $img = pop; 309 my $img = pop;
189 my $h = pop || H; 310 my $h = pop || TH;
190 my $w = pop || W; 311 my $w = pop || TW;
191 $img->sub_rect ($_[0], $_[1], $w, $h) 312 $img->sub_rect ($_[0], $_[1], $w, $h)
192 } 313 }
193 314
194=item scale $img 315=item scale $img
195 316
211 332
212=cut 333=cut
213 334
214#TODO: maximise, maximise_fill? 335#TODO: maximise, maximise_fill?
215 336
216 sub scale($$$) { 337 sub scale($;$;$) {
217 my $img = pop; 338 my $img = pop;
218 339
219 @_ == 2 ? $img->scale ($_[0] * $img->w * 0.01, $_[1] * $img->h * 0.01) 340 @_ == 2 ? $img->scale ($_[0] * $img->w * 0.01, $_[1] * $img->h * 0.01)
220 : @_ ? $img->scale ($_[0] * $img->w * 0.01, $_[0] * $img->h * 0.01) 341 : @_ ? $img->scale ($_[0] * $img->w * 0.01, $_[0] * $img->h * 0.01)
221 : $img->scale (W, H) 342 : $img->scale (TW, TH)
222 } 343 }
223 344
224 sub resize($$$) { 345 sub resize($$$) {
225 my $img = pop; 346 my $img = pop;
226 $img->scale ($_[0], $_[1]) 347 $img->scale ($_[0], $_[1])
227 } 348 }
228 349
229 # TODO: ugly
230 sub move($$;$) { 350 sub move($$;$) {
231 my $img = pop->clone; 351 my $img = pop->clone;
232 $img->move ($_[0], $_[1]); 352 $img->move ($_[0], $_[1]);
233 $img 353 $img
234# my $img = pop;
235# $img->sub_rect (
236# $_[0], $_[1],
237# $img->w, $img->h,
238# $_[2],
239# )
240 } 354 }
241 355
242 sub rotate($$$$$$) { 356 sub rotate($$$$$$) {
243 my $img = pop; 357 my $img = pop;
244 $img->rotate ( 358 $img->rotate (
250 ) 364 )
251 } 365 }
252 366
253 sub blur($$;$) { 367 sub blur($$;$) {
254 my $img = pop; 368 my $img = pop;
255
256 $img->blur ($_[0], @_ >= 2 ? $_[1] : $_[0]); 369 $img->blur ($_[0], @_ >= 2 ? $_[1] : $_[0])
257 } 370 }
258 371
259 sub contrast($$;$$;$) { 372 sub contrast($$;$$;$) {
260 my $img = pop; 373 my $img = pop;
261 my ($r, $g, $b, $a) = @_; 374 my ($r, $g, $b, $a) = @_;
300 $self->recalculate; 413 $self->recalculate;
301} 414}
302 415
303# evaluate the current bg expression 416# evaluate the current bg expression
304sub recalculate { 417sub recalculate {
305 my ($self) = @_; 418 my ($arg_self) = @_;
306 419
307 # rate limit evaluation 420 # rate limit evaluation
308 421
309 if ($self->{next_refresh} > urxvt::NOW) { 422 if ($arg_self->{next_refresh} > urxvt::NOW) {
310 $self->{next_refresh_timer} = urxvt::timer->new->after ($self->{next_refresh} - urxvt::NOW)->cb (sub { 423 $arg_self->{next_refresh_timer} = urxvt::timer->new->after ($arg_self->{next_refresh} - urxvt::NOW)->cb (sub {
311 $self->recalculate; 424 $arg_self->recalculate;
312 }); 425 });
313 return; 426 return;
314 } 427 }
315 428
316 $self->{next_refresh} = urxvt::NOW + $MIN_INTERVAL; 429 $arg_self->{next_refresh} = urxvt::NOW + $MIN_INTERVAL;
317 430
318 # set environment to evaluate user expression 431 # set environment to evaluate user expression
319 432
320 local $bgdsl_self = $self; 433 local $self = $arg_self;
321 434
322 local $old = $self->{state}; 435 local $old = $self->{state};
323 local $new = my $state = $self->{state} = {}; 436 local $new = my $state = $self->{state} = {};
324 437
325 my $border = 0; #d#
326
327 ($x, $y, $w, $h) = 438 ($x, $y, $w, $h) =
328 $self->background_geometry ($border); 439 $self->background_geometry ($self->{border});
329 440
330 # evaluate user expression 441 # evaluate user expression
331 442
332 my $img = eval { $self->{expr}->() }; 443 my $img = eval { $self->{expr}->() };
333 warn $@ if $@;#d# 444 warn $@ if $@;#d#
334 die if !UNIVERSAL::isa $img, "urxvt::img"; 445 die if !UNIVERSAL::isa $img, "urxvt::img";
446
447 $state->{size_sensitive} = 1
448 if $img->repeat_mode != urxvt::RepeatNormal;
335 449
336 # if the expression is sensitive to external events, prepare reevaluation then 450 # if the expression is sensitive to external events, prepare reevaluation then
337 451
338 my $repeat; 452 my $repeat;
339 453
375 unless ($repeat) { 489 unless ($repeat) {
376 delete $self->{state}; 490 delete $self->{state};
377 delete $self->{expr}; 491 delete $self->{expr};
378 } 492 }
379 493
380 # prepare and set background pixmap 494 # set background pixmap
381 495
382 $img = $img->sub_rect (0, 0, $w, $h)
383 if $img->w != $w || $img->h != $h;
384
385 $self->set_background ($img, $border); 496 $self->set_background ($img, $self->{border});
386 $self->scr_recolour (0); 497 $self->scr_recolour (0);
387 $self->want_refresh; 498 $self->want_refresh;
388} 499}
389 500
390sub on_start { 501sub on_start {
391 my ($self) = @_; 502 my ($self) = @_;
392 503
504 my $expr = $self->x_resource ("background.expr")
505 or return;
506
393 $self->set_expr (parse_expr $EXPR); 507 $self->set_expr (parse_expr $expr);
508 $self->{border} = $self->x_resource_boolean ("background.border");
394 509
395 () 510 ()
396} 511}
397 512

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines