ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/perl/background
Revision: 1.39
Committed: Fri Jun 8 22:19:03 2012 UTC (11 years, 11 months ago) by root
Branch: MAIN
Changes since 1.38: +58 -19 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 #! perl
2    
3 root 1.16 #:META:X_RESOURCE:%.expr:string:background expression
4 root 1.33 #:META:X_RESOURCE:%.border.:boolean:respect the terminal border
5    
6 root 1.35 #TODO: once, rootalign
7    
8 root 1.33 =head1 background - manage terminal background
9    
10     =head2 SYNOPSIS
11    
12 root 1.36 urxvt --background-expr 'background expression'
13     --background-border
14 root 1.33
15     =head2 DESCRIPTION
16    
17 root 1.36 This extension manages the terminal background by creating a picture that
18     is behind the text, replacing the normal background colour.
19    
20     It does so by evaluating a Perl expression that I<calculates> the image on
21     the fly, for example, by grabbing the root background or loading a file.
22    
23     While the full power of Perl is available, the operators have been design
24     to be as simple as possible.
25    
26     For example, to load an image and scale it to the window size, you would
27     use:
28    
29     urxvt --background-expr 'scale load "/path/to/mybg.png"'
30    
31     Or specified as a X resource:
32    
33     URxvt.background-expr: scale load "/path/to/mybg.png"
34    
35     =head2 THEORY OF OPERATION
36    
37     At startup, just before the window is mapped for the first time, the
38     expression is evaluated and must yield an image. The image is then
39     extended as necessary to cover the whole terminal window, and is set as a
40     background pixmap.
41    
42     If the image contains an alpha channel, then it will be used as-is in
43     visuals that support alpha channels (for example, for a compositing
44     manager). In other visuals, the terminal background colour will be used to
45     replace any transparency.
46    
47     When the expression relies, directly or indirectly, on the window size,
48     position, the root pixmap, or a timer, then it will be remembered. If not,
49     then it will be removed.
50    
51     If any of the parameters that the expression relies on changes (when the
52     window is moved or resized, its position or size changes; when the root
53     pixmap is replaced by another one the root background changes; or when the
54     timer elapses), then the expression will be evaluated again.
55    
56     For example, an expression such as C<scale load "$HOME/mybg.png"> scales the
57     image to the window size, so it relies on the window size and will
58     be reevaluated each time it is changed, but not when it moves for
59     example. That ensures that the picture always fills the terminal, even
60     after it's size changes.
61    
62     =head3 EXPRESSIONS
63    
64     Expressions are normal Perl expressions, in fact, they are Perl blocks -
65     which means you could use multiple lines and statements:
66    
67     again 3600;
68     if (localtime now)[6]) {
69     return scale load "$HOME/weekday.png";
70     } else {
71     return scale load "$HOME/sunday.png";
72     }
73    
74     This expression gets evaluated once per hour. It will set F<sunday.png> as
75 root 1.39 background on Sundays, and F<weekday.png> on all other days.
76 root 1.36
77     Fortunately, we expect that most expressions will be much simpler, with
78     little Perl knowledge needed.
79    
80     Basically, you always start with a function that "generates" an image
81     object, such as C<load>, which loads an image from disk, or C<root>, which
82     returns the root window background image:
83    
84     load "$HOME/mypic.png"
85    
86     The path is usually specified as a quoted string (the exact rules can be
87     found in the L<perlop> manpage). The F<$HOME> at the beginning of the
88     string is expanded to the home directory.
89    
90     Then you prepend one or more modifiers or filtering expressions, such as
91     C<scale>:
92    
93     scale load "$HOME/mypic.png"
94    
95     Just like a mathematical expression with functions, you should read these
96     expressions from right to left, as the C<load> is evaluated first, and
97     its result becomes the argument to the C<scale> function.
98    
99     Many operators also allow some parameters preceding the input image
100     that modify its behaviour. For example, C<scale> without any additional
101     arguments scales the image to size of the terminal window. If you specify
102     an additional argument, it uses it as a percentage:
103    
104     scale 200, load "$HOME/mypic.png"
105    
106     This enlarges the image by a factor of 2 (200%). As you can see, C<scale>
107     has now two arguments, the C<200> and the C<load> expression, while
108     C<load> only has one argument. Arguments are separated from each other by
109     commas.
110    
111     Scale also accepts two arguments, which are then separate factors for both
112     horizontal and vertical dimensions. For example, this halves the image
113     width and doubles the image height:
114    
115     scale 50, 200, load "$HOME/mypic.png"
116    
117 root 1.39 Other effects than scalign are also readily available, for exmaple, you can
118     tile the image to fill the whole window, instead of resizing it:
119    
120     tile load "$HOME/mypic.png"
121    
122     In fact, images returned by C<load> are in C<tile> mode by default, so the C<tile> operator
123     is kind of superfluous.
124    
125     Another common effect is to mirror the image, so that the same edges touch:
126    
127     mirror load "$HOME/mypic.png"
128    
129     This is also a typical background expression:
130    
131     rootalign root
132    
133     It first takes a snapshot of the screen background image, and then
134     moves it to the upper left corner of the screen - the result is
135     pseudo-transparency, as the image seems to be static while the window is
136     moved around.
137 root 1.36
138     =head3 CYCLES AND CACHING
139    
140 root 1.39 As has been mentioned before, the expression might be evaluated multiple
141     times. Each time the expression is reevaluated, a new cycle is said to
142     have begun. Many operators cache their results till the next cycle.
143    
144     For example, the C<load> operator keeps a copy of the image. If it is
145     asked to load the same image on the next cycle it will not load it again,
146     but return the cached copy.
147    
148     This only works for one cycle though, so as long as you load the same
149     image every time, it will always be cached, but when you load a different
150     image, it will forget about the first one.
151    
152     This allows you to either speed things up by keeping multiple images in
153     memory, or comserve memory by loading images more often.
154    
155     For example, you can keep two images in memory and use a random one like
156     this:
157    
158     my $img1 = load "img1.png";
159     my $img2 = load "img2.png";
160     (0.5 > rand) ? $img1 : $img2
161    
162     Since both images are "loaded" every time the expression is evaluated,
163     they are always kept in memory. Contrast this version:
164    
165     my $path1 = "img1.png";
166     my $path2 = "img2.png";
167     load ((0.5 > rand) ? $path1 : $path2)
168    
169     Here, a path is selected randomly, and load is only called for one image,
170     so keeps only one image in memory. If, on the next evaluation, luck
171     decides to use the other path, then it will have to load that image again.
172 root 1.36
173 root 1.33 =head2 REFERENCE
174    
175 root 1.36 =head3 COMMAND LINE SWITCHES
176    
177     =over 4
178    
179     =item --background-expr perl-expression
180    
181     Specifies the Perl expression to evaluate.
182    
183     =item --background-border
184    
185     By default, the expression creates an image that fills the full window,
186     overwriting borders and any other areas, such as the scrollbar.
187    
188     Specifying this flag changes the behaviour, so that the image only
189     replaces the background of the character area.
190    
191     =back
192    
193 root 1.33 =cut
194 root 1.12
195 root 1.36 our $HOME;
196 root 1.33 our ($self, $old, $new);
197 root 1.29 our ($x, $y, $w, $h);
198 root 1.3
199 root 1.16 # enforce at least this interval between updates
200 root 1.10 our $MIN_INTERVAL = 1/100;
201 root 1.9
202 root 1.1 {
203     package urxvt::bgdsl; # background language
204    
205 root 1.15 =head2 PROVIDERS/GENERATORS
206    
207 root 1.31 These functions provide an image, by loading it from disk, grabbing it
208 sf-exg 1.32 from the root screen or by simply generating it. They are used as starting
209 root 1.31 points to get an image you can play with.
210    
211 root 1.15 =over 4
212    
213     =item load $path
214    
215 root 1.29 Loads the image at the given C<$path>. The image is set to plane tiling
216     mode.
217    
218 root 1.31 Loaded images will be cached for one cycle.
219 root 1.29
220 root 1.15 =cut
221    
222 root 1.2 sub load($) {
223 root 1.1 my ($path) = @_;
224    
225 root 1.33 $new->{load}{$path} = $old->{load}{$path} || $self->new_img_from_file ($path);
226 root 1.1 }
227    
228 root 1.31 =item root
229    
230     Returns the root window pixmap, that is, hopefully, the background image
231     of your screen. The image is set to extend mode.
232    
233     This function makes your expression root sensitive, that means it will be
234     reevaluated when the bg image changes.
235    
236     =cut
237    
238 root 1.2 sub root() {
239 root 1.9 $new->{rootpmap_sensitive} = 1;
240 root 1.1 die "root op not supported, exg, we need you";
241     }
242    
243 root 1.31 =item solid $colour
244    
245     =item solid $width, $height, $colour
246    
247     Creates a new image and completely fills it with the given colour. The
248     image is set to tiling mode.
249    
250     If <$width> and C<$height> are omitted, it creates a 1x1 image, which is
251     useful for solid backgrounds or for use in filtering effects.
252    
253     =cut
254    
255     sub solid($$;$) {
256     my $colour = pop;
257    
258 root 1.33 my $img = $self->new_img (urxvt::PictStandardARGB32, $_[0] || 1, $_[1] || 1);
259 root 1.31 $img->fill ($colour);
260 root 1.15 $img
261     }
262    
263     =back
264    
265 root 1.20 =head2 VARIABLES
266    
267 root 1.31 The following functions provide variable data such as the terminal
268 sf-exg 1.32 window dimensions. Most of them make your expression sensitive to some
269 root 1.31 events, for example using C<TW> (terminal width) means your expression is
270     evaluated again when the terminal is resized.
271    
272 root 1.20 =over 4
273    
274 root 1.31 =item TX
275    
276     =item TY
277    
278     Return the X and Y coordinates of the terminal window (the terminal
279     window is the full window by default, and the character area only when in
280     border-respect mode).
281    
282     Using these functions make your expression sensitive to window moves.
283    
284     These functions are mainly useful to align images to the root window.
285    
286     Example: load an image and align it so it looks as if anchored to the
287     background.
288    
289     move -TX, -TY, load "mybg.png"
290    
291     =item TW
292    
293     Return the width (C<TW>) and height (C<TH>) of the terminal window (the
294     terminal window is the full window by default, and the character area only
295     when in border-respect mode).
296    
297     Using these functions make your expression sensitive to window resizes.
298    
299     These functions are mainly useful to scale images, or to clip images to
300     the window size to conserve memory.
301    
302     Example: take the screen background, clip it to the window size, blur it a
303     bit, align it to the window position and use it as background.
304    
305     clip move -TX, -TY, blur 5, root
306    
307 root 1.20 =cut
308    
309 root 1.30 sub TX() { $new->{position_sensitive} = 1; $x }
310     sub TY() { $new->{position_sensitive} = 1; $y }
311     sub TW() { $new->{size_sensitive} = 1; $w }
312     sub TH() { $new->{size_sensitive} = 1; $h }
313 root 1.20
314 root 1.33 =item now
315    
316     Returns the current time as (fractional) seconds since the epoch.
317    
318     Using this expression does I<not> make your expression sensitive to time,
319     but the next two functions do.
320    
321     =item again $seconds
322    
323     When this function is used the expression will be reevaluated again in
324     C<$seconds> seconds.
325    
326     Example: load some image and rotate it according to the time of day (as if it were
327 root 1.36 the hour pointer of a clock). Update this image every minute.
328 root 1.33
329     again 60; rotate TW, TH, 50, 50, (now % 86400) * -720 / 86400, scale load "myclock.png"
330    
331     =item counter $seconds
332    
333     Like C<again>, but also returns an increasing counter value, starting at
334     0, which might be useful for some simple animation effects.
335    
336     =cut
337    
338 root 1.20 sub now() { urxvt::NOW }
339    
340     sub again($) {
341     $new->{again} = $_[0];
342     }
343    
344     sub counter($) {
345     $new->{again} = $_[0];
346 root 1.33 $self->{counter} + 0
347 root 1.20 }
348    
349     =back
350    
351 root 1.28 =head2 TILING MODES
352    
353     The following operators modify the tiling mode of an image, that is, the
354     way that pixels outside the image area are painted when the image is used.
355 root 1.15
356     =over 4
357    
358 root 1.28 =item tile $img
359    
360     Tiles the whole plane with the image and returns this new image - or in
361     other words, it returns a copy of the image in plane tiling mode.
362    
363 root 1.34 Example: load an image and tile it over the background, without
364     resizing. The C<tile> call is superfluous because C<load> already defaults
365     to tiling mode.
366    
367     tile load "mybg.png"
368    
369 root 1.28 =item mirror $img
370    
371     Similar to tile, but reflects the image each time it uses a new copy, so
372     that top edges always touch top edges, right edges always touch right
373     edges and so on (with normal tiling, left edges always touch right edges
374     and top always touch bottom edges).
375    
376 root 1.36 Example: load an image and mirror it over the background, avoiding sharp
377 root 1.34 edges at the image borders at the expense of mirroring the image itself
378    
379     mirror load "mybg.png"
380    
381 root 1.28 =item pad $img
382    
383     Takes an image and modifies it so that all pixels outside the image area
384     become transparent. This mode is most useful when you want to place an
385     image over another image or the background colour while leaving all
386     background pixels outside the image unchanged.
387    
388 root 1.36 Example: load an image and display it in the upper left corner. The rest
389 root 1.34 of the space is left "empty" (transparent or wahtever your compisotr does
390     in alpha mode, else background colour).
391    
392     pad load "mybg.png"
393    
394 root 1.28 =item extend $img
395    
396     Extends the image over the whole plane, using the closest pixel in the
397     area outside the image. This mode is mostly useful when you more complex
398     filtering operations and want the pixels outside the image to have the
399     same values as the pixels near the edge.
400    
401 root 1.34 Example: just for curiosity, how does this pixel extension stuff work?
402    
403     extend move 50, 50, load "mybg.png"
404    
405 root 1.15 =cut
406    
407 root 1.28 sub pad($) {
408     my $img = $_[0]->clone;
409     $img->repeat_mode (urxvt::RepeatNone);
410     $img
411     }
412    
413     sub tile($) {
414     my $img = $_[0]->clone;
415     $img->repeat_mode (urxvt::RepeatNormal);
416     $img
417     }
418    
419     sub mirror($) {
420     my $img = $_[0]->clone;
421     $img->repeat_mode (urxvt::RepeatReflect);
422     $img
423     }
424 root 1.4
425 root 1.28 sub extend($) {
426 root 1.24 my $img = $_[0]->clone;
427 root 1.28 $img->repeat_mode (urxvt::RepeatPad);
428 root 1.24 $img
429     }
430    
431 root 1.28 =back
432    
433     =head2 PIXEL OPERATORS
434    
435     The following operators modify the image pixels in various ways.
436    
437     =over 4
438    
439     =item clone $img
440    
441     Returns an exact copy of the image.
442    
443     =cut
444    
445     sub clone($) {
446     $_[0]->clone
447     }
448    
449     =item clip $img
450    
451     =item clip $width, $height, $img
452    
453     =item clip $x, $y, $width, $height, $img
454    
455     Clips an image to the given rectangle. If the rectangle is outside the
456     image area (e.g. when C<$x> or C<$y> are negative) or the rectangle is
457     larger than the image, then the tiling mode defines how the extra pixels
458     will be filled.
459    
460     If C<$x> an C<$y> are missing, then C<0> is assumed for both.
461    
462     If C<$width> and C<$height> are missing, then the window size will be
463     assumed.
464    
465     Example: load an image, blur it, and clip it to the window size to save
466     memory.
467    
468     clip blur 10, load "mybg.png"
469    
470     =cut
471    
472 root 1.20 sub clip($;$$;$$) {
473 root 1.7 my $img = pop;
474 root 1.30 my $h = pop || TH;
475     my $w = pop || TW;
476 root 1.21 $img->sub_rect ($_[0], $_[1], $w, $h)
477 root 1.4 }
478    
479 root 1.28 =item scale $img
480    
481     =item scale $size_percent, $img
482    
483     =item scale $width_percent, $height_percent, $img
484    
485     Scales the image by the given percentages in horizontal
486     (C<$width_percent>) and vertical (C<$height_percent>) direction.
487    
488     If only one percentage is give, it is used for both directions.
489    
490     If no percentages are given, scales the image to the window size without
491     keeping aspect.
492    
493     =item resize $width, $height, $img
494    
495     Resizes the image to exactly C<$width> times C<$height> pixels.
496    
497     =cut
498    
499     #TODO: maximise, maximise_fill?
500    
501 root 1.33 sub scale($;$;$) {
502 root 1.28 my $img = pop;
503    
504     @_ == 2 ? $img->scale ($_[0] * $img->w * 0.01, $_[1] * $img->h * 0.01)
505     : @_ ? $img->scale ($_[0] * $img->w * 0.01, $_[0] * $img->h * 0.01)
506 root 1.30 : $img->scale (TW, TH)
507 root 1.28 }
508    
509 root 1.2 sub resize($$$) {
510 root 1.7 my $img = pop;
511     $img->scale ($_[0], $_[1])
512 root 1.1 }
513    
514 root 1.36 =item move $dx, $dy, $img
515    
516     Moves the image by C<$dx> pixels in the horizontal, and C<$dy> pixels in
517     the vertical.
518    
519     Example: move the image right by 20 pixels and down by 30.
520    
521     move 20, 30, ...
522    
523     =item rootalign $img
524    
525     Moves the image so that it appears glued to the screen as opposed to the
526     window. This gives the illusion of a larger area behind the window. It is
527     exactly equivalent to C<move -TX, -TY>, that is, it moves the image to the
528     top left of the screen.
529    
530     Example: load a background image, put it in mirror mode and root align it.
531    
532     rootalign mirror load "mybg.png"
533    
534     Example: take the screen background and align it, giving the illusion of
535     transparency as long as the window isn't in front of other windows.
536    
537     rootalign root
538    
539     =cut
540    
541 root 1.7 sub move($$;$) {
542 root 1.20 my $img = pop->clone;
543     $img->move ($_[0], $_[1]);
544     $img
545 root 1.1 }
546    
547 root 1.36 sub rootalign($) {
548     move -TX, -TY, $_[0]
549 root 1.1 }
550    
551 root 1.36 =item contrast $factor, $img
552    
553     =item contrast $r, $g, $b, $img
554    
555     =item contrast $r, $g, $b, $a, $img
556    
557     Adjusts the I<contrast> of an image.
558    
559 root 1.38 #TODO#
560    
561 root 1.36 =item brightness $factor, $img
562    
563     =item brightness $r, $g, $b, $img
564    
565     =item brightness $r, $g, $b, $a, $img
566    
567 root 1.38 Adjusts the brightness of an image.
568    
569 root 1.36 =cut
570 root 1.1
571 root 1.2 sub contrast($$;$$;$) {
572 root 1.7 my $img = pop;
573     my ($r, $g, $b, $a) = @_;
574 root 1.4
575 root 1.1 ($g, $b) = ($r, $r) if @_ < 4;
576     $a = 1 if @_ < 5;
577 root 1.4
578 root 1.1 $img = $img->clone;
579 root 1.37 $img->contrast ($r, $g, $b, $a);
580 root 1.1 $img
581     }
582    
583 root 1.2 sub brightness($$;$$;$) {
584 root 1.7 my $img = pop;
585     my ($r, $g, $b, $a) = @_;
586 root 1.4
587 root 1.1 ($g, $b) = ($r, $r) if @_ < 4;
588     $a = 1 if @_ < 5;
589 root 1.4
590 root 1.1 $img = $img->clone;
591     $img->brightness ($r, $g, $b, $a);
592     $img
593     }
594    
595 root 1.38 =item blur $radius, $img
596    
597     =item blur $radius_horz, $radius_vert, $img
598    
599     Gaussian-blurs the image with (roughly) C<$radius> pixel radius. The radii
600     can also be specified separately.
601    
602 root 1.39 Blurring is often I<very> slow, at least compared or other
603     operators. Larger blur radii are slower than smaller ones, too, so if you
604     don't want to freeze your screen for long times, start experimenting with
605     low values for radius (<5).
606    
607 root 1.38 =cut
608    
609 root 1.36 sub blur($$;$) {
610     my $img = pop;
611     $img->blur ($_[0], @_ >= 2 ? $_[1] : $_[0])
612     }
613    
614 root 1.38 =item rotate $new_width, $new_height, $center_x, $center_y, $degrees
615    
616     Rotates the image by C<$degrees> degrees, counter-clockwise, around the
617     pointer at C<$center_x> and C<$center_y> (specified as percentage of image
618     width/height), generating a new image with width C<$new_width> and height
619     C<$new_height>.
620    
621     #TODO# new width, height, maybe more operators?
622    
623     Example: rotate the image by 90 degrees
624    
625     =cut
626    
627 root 1.36 sub rotate($$$$$$) {
628     my $img = pop;
629     $img->rotate (
630     $_[0],
631     $_[1],
632     $_[2] * $img->w * .01,
633     $_[3] * $img->h * .01,
634     $_[4] * (3.14159265 / 180),
635     )
636     }
637    
638 root 1.15 =back
639    
640     =cut
641    
642 root 1.1 }
643    
644     sub parse_expr {
645     my $expr = eval "sub {\npackage urxvt::bgdsl;\n#line 0 'background expression'\n$_[0]\n}";
646     die if $@;
647     $expr
648     }
649    
650     # compiles a parsed expression
651     sub set_expr {
652     my ($self, $expr) = @_;
653    
654     $self->{expr} = $expr;
655     $self->recalculate;
656     }
657    
658     # evaluate the current bg expression
659     sub recalculate {
660 root 1.33 my ($arg_self) = @_;
661 root 1.1
662 root 1.10 # rate limit evaluation
663    
664 root 1.33 if ($arg_self->{next_refresh} > urxvt::NOW) {
665     $arg_self->{next_refresh_timer} = urxvt::timer->new->after ($arg_self->{next_refresh} - urxvt::NOW)->cb (sub {
666     $arg_self->recalculate;
667 root 1.9 });
668 root 1.12 return;
669 root 1.9 }
670    
671 root 1.33 $arg_self->{next_refresh} = urxvt::NOW + $MIN_INTERVAL;
672 root 1.9
673 root 1.10 # set environment to evaluate user expression
674 root 1.6
675 root 1.33 local $self = $arg_self;
676 root 1.1
677 root 1.36 local $HOME = $ENV{HOME};
678 root 1.3 local $old = $self->{state};
679     local $new = my $state = $self->{state} = {};
680 root 1.1
681 root 1.29 ($x, $y, $w, $h) =
682 root 1.33 $self->background_geometry ($self->{border});
683 root 1.22
684 root 1.10 # evaluate user expression
685    
686 root 1.1 my $img = eval { $self->{expr}->() };
687     warn $@ if $@;#d#
688 root 1.15 die if !UNIVERSAL::isa $img, "urxvt::img";
689 root 1.1
690 root 1.34 $state->{size_sensitive} = 1
691     if $img->repeat_mode != urxvt::RepeatNormal;
692    
693 root 1.10 # if the expression is sensitive to external events, prepare reevaluation then
694    
695 root 1.2 my $repeat;
696    
697 root 1.1 if (my $again = $state->{again}) {
698 root 1.2 $repeat = 1;
699 root 1.35 my $self = $self;
700 root 1.6 $state->{timer} = $again == $old->{again}
701     ? $old->{timer}
702 root 1.7 : urxvt::timer->new->after ($again)->interval ($again)->cb (sub {
703     ++$self->{counter};
704     $self->recalculate
705     });
706 root 1.1 }
707    
708 root 1.2 if (delete $state->{position_sensitive}) {
709     $repeat = 1;
710     $self->enable (position_change => sub { $_[0]->recalculate });
711     } else {
712     $self->disable ("position_change");
713     }
714    
715     if (delete $state->{size_sensitive}) {
716     $repeat = 1;
717     $self->enable (size_change => sub { $_[0]->recalculate });
718     } else {
719     $self->disable ("size_change");
720     }
721    
722 root 1.9 if (delete $state->{rootpmap_sensitive}) {
723     $repeat = 1;
724     $self->enable (rootpmap_change => sub { $_[0]->recalculate });
725     } else {
726     $self->disable ("rootpmap_change");
727     }
728    
729 root 1.10 # clear stuff we no longer need
730    
731 root 1.6 %$old = ();
732    
733 root 1.5 unless ($repeat) {
734     delete $self->{state};
735     delete $self->{expr};
736     }
737    
738 root 1.34 # set background pixmap
739 root 1.1
740 root 1.33 $self->set_background ($img, $self->{border});
741 root 1.1 $self->scr_recolour (0);
742     $self->want_refresh;
743     }
744    
745     sub on_start {
746     my ($self) = @_;
747    
748 root 1.33 my $expr = $self->x_resource ("background.expr")
749     or return;
750    
751     $self->set_expr (parse_expr $expr);
752     $self->{border} = $self->x_resource_boolean ("background.border");
753 root 1.1
754     ()
755     }
756