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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines