File Coverage

blib/lib/ZConf/BGSet.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             package ZConf::BGSet;
2              
3 1     1   29871 use warnings;
  1         3  
  1         35  
4 1     1   6 use strict;
  1         2  
  1         34  
5 1     1   1183 use Image::Size::FillFullSelect;
  1         7749  
  1         34  
6 1     1   1511 use ZConf;
  1         241069  
  1         49  
7 1     1   15 use File::Spec;
  1         3  
  1         25  
8 1     1   515 use X11::Resolution;
  0            
  0            
9              
10             =head1 NAME
11              
12             ZConf::BGSet - A perl module for background management.
13              
14             =head1 VERSION
15              
16             Version 1.0.0
17              
18             =cut
19              
20             our $VERSION = '1.0.0';
21              
22              
23             =head1 SYNOPSIS
24              
25             use ZConf::BGSet;
26              
27             my $zbg = ZConf::BGSet->new();
28             ...
29              
30             =head1 METHODES
31              
32             =head2 new
33              
34             This initializes it.
35              
36             One arguement is taken and that is a hash value.
37              
38             If this it fails, $zbg->{perror} is set and the other methods
39             will always error as a permanent error has been set.
40              
41             =head3 hash values
42              
43             =head4 zconf
44              
45             If this key is defined, this hash will be passed to ZConf->new().
46              
47             my $zbg=ZConf::Runner->new();
48             if($zbg->{error}){
49             print "Error!\n";
50             }
51              
52             =cut
53              
54             sub new {
55             my %args;
56             if(defined($_[1])){
57             %args= %{$_[1]};
58             }
59             my $function='new';
60              
61             my $self={
62             error=>undef,
63             errorString=>undef,
64             perror=>undef,
65             module=>'ZConf-BGSet',
66             zconfconfig=>'zbgset',
67             };
68             bless $self;
69              
70             #get the ZConf object
71             if (!defined($args{zconf})) {
72             #creates the ZConf object
73             $self->{zconf}=ZConf->new();
74             if(defined($self->{zconf}->{error})){
75             $self->{error}=1;
76             $self->{perror}=1;
77             $self->{errorString}="Could not initiate ZConf. It failed with '"
78             .$self->{zconf}->{error}."', '".
79             $self->{zconf}->{errorString}."'";
80             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
81             return $self;
82             }
83             }else {
84             $self->{zconf}=$args{zconf};
85             }
86              
87             #create the config if it does not exist
88             #if it does exist, make sure the set we are using exists
89             my $returned = $self->{zconf}->configExists($self->{zconfconfig});
90             if($self->{zconf}->{error}){
91             $self->{error}=2;
92             $self->{perror}=1;
93             $self->{errorString}="Checking if '".$self->{zconfconfig}."' exists failed. error='".
94             $self->{zconf}->{error}."', errorString='".
95             $self->{zconf}->{errorString}."'";
96             warn($self->{module}.' '.$function.':'.$self->{error}.':'.$self->{errorString});
97             return $self;
98             }
99            
100             #initiate the config if it does not exist
101             if (!$returned) {
102             #init it
103             $self->init;
104             if ($self->{zconf}->{error}) {
105             $self->{perror}=1;
106             $self->{errorString}='Init failed.';
107             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
108             return $self;
109             }
110             }else {
111             #if we have a set, make sure we also have a set that will be loaded
112             $returned=$self->{zconf}->defaultSetExists($self->{zconfconfig});
113             if ($self->{zconf}->{error}) {
114             $self->{error}=2;
115             $self->{perror}=1;
116             $self->{errorString}="Checking if '".$self->{zconfconfig}."' exists failed. error='".
117             $self->{zconf}->{error}."', errorString='".
118             $self->{zconf}->{errorString}."'";
119             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
120             return $self;
121             }
122            
123             #if we don't have a default set, initialize it
124             if (!$returned) {
125             #init it
126             $self->init;
127             if ($self->{zconf}->{error}) {
128             $self->{perror}=1;
129             $self->{errorString}='Init failed.';
130             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
131             return $self;
132             }
133             }
134             }
135              
136             #read the config
137             $self->{zconf}->read({config=>$self->{zconfconfig}});
138             if ($self->{zconf}->{error}) {
139             $self->{error}=1;
140             $self->{perror}=1;
141             $self->{errorString}="Reading the ZConf config '".$self->{zconfconfig}."' failed. error='".
142             $self->{zconf}->{error}."', errorString='".
143             $self->{zconf}->{errorString}."'";
144             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
145             return $self;
146             }
147            
148             return $self;
149             }
150              
151             =head2 addToLast
152              
153             This adds an item to the history.
154              
155             =head3 args hash
156              
157             =head4 hostname
158              
159             This specifies the hostname to use. If this is not defined,
160             the hostname of the machine it is currently running on
161             will be used.
162              
163             =head4 display
164              
165             This is the X display the BG was set on. If it is not set,
166             the enviromental variable 'DISPLAY' is used.
167              
168             =head4 filltype
169              
170             This is the fill type that was used.
171              
172             =head4 image
173              
174             This is the image the background was set to.
175              
176             $zbg->addToLast({image=>'/tmp/something.jpg', filltype=>'full'});
177             if($zbg->{error}){
178             print "Error!\n";
179             }
180              
181             =cut
182              
183             sub addToLast{
184             my $self=$_[0];
185             my %args;
186             if(defined($_[1])){
187             %args= %{$_[1]};
188             }
189             my $function='addToLast';
190              
191             $self->errorblank;
192             if ($self->{error}) {
193             warn($self->{module}.' '.$function.': A permanent error is set');
194             return undef;
195             }
196              
197              
198             #gets the hostname if it is not specified
199             if (!defined($args{hostname})) {
200             #gets the hostname
201             $args{hostname}=`hostname`;
202             if(!defined($args{hostname})){
203             $args{hostname}="localhost";
204             }else{
205             chomp($args{hostname});
206             };
207             }
208              
209             #make sure display is defined can be found
210             if (!defined($args{display})) {
211             if (!defined($ENV{DISPLAY})) {
212             $self->{error}=8;
213             $self->{errorString}='$args{display} or $ENV{DISPLAY} not defined';
214             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
215             return undef;
216             }
217             $args{display}=$ENV{DISPLAY};
218             }
219              
220             #error if the filltype is not specified
221             if (!defined($args{filltype})) {
222             $self->{error}=5;
223             $self->{errorString}='$args{filltype} is not defined';
224             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
225             return undef;
226             }
227              
228             #error if the image is specified
229             if (!defined($args{image})) {
230             $self->{error}=5;
231             $self->{errorString}='$args{image} is not defined';
232             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
233             return undef;
234             }
235              
236             #make sure a legit filltype is specified
237             if (!$self->validSetterName($args{filltype})) {
238             $self->{error}=6;
239             $self->{errorString}='"'.$args{filltype}.'" is not a valid setter name.';
240             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
241             return undef;
242             }
243              
244             #errors if : is found in the hostname
245             if ($args{hostname} =~ /:/) {
246             $self->{error}=9;
247             $self->{errorString}='Hostname contains ":".';
248             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
249             return undef;
250             }
251              
252             #make sure it is a legit display name
253             if (!$args{display} =~ /^:[[:digit:]]*\.[[:digit:]]*$/) {
254             $self->{error}=10;
255             $self->{errorString}='Invalid display name.';
256             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
257             return undef;
258             }
259              
260             #this builds the last line that will be added
261             my $lastline=$args{hostname}.$args{display}.':'.$args{filltype}.':'.$args{image};
262             my $last=$lastline."\n".$self->getLastRaw;
263              
264             #breaks it apart and rebuilds it
265             my @lastSplit=split(/\n/, $last);
266             my $newlast='';
267             my $int=0;
268             while (defined($lastSplit[$int])) {
269             if ($int <= $self->{zconf}->{conf}->{zbgset}->{numberoflast}) {
270             $newlast=$newlast.$lastSplit[$int]."\n";
271             }
272              
273             $int++;
274             }
275              
276             chomp($newlast);
277              
278             $self->{zconf}->{conf}{zbgset}{last}=$newlast;
279              
280             $self->{zconf}->writeSetFromLoadedConfig({config=>'zbgset'});
281              
282             return 1;
283             }
284              
285             =head2 createPath
286              
287             This creates a path. If a path already exists, it will error.
288              
289             Two arguements are required. The first is the name of the path
290             and the second is a array containing the various paths.
291              
292             $zbg->setPath('somepath', @paths);
293             if($zbg->{error}){
294             print "Error!\n";
295             }
296              
297             =cut
298              
299             sub createPath{
300             my $self=$_[0];
301             my $path=$_[1];
302             my @paths=$_[2];
303             my $function='createPath';
304              
305             #blanks any previous errors
306             $self->errorblank;
307             if ($self->{error}) {
308             warn($self->{module}.' '.$function.': A permanent error is set');
309             return undef;
310             }
311              
312             if (!defined($path)) {
313             $self->{error}=5;
314             $self->{errorString}='No path specified.';
315             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
316             return undef;
317             }
318              
319             #check if it exists and error if there is an error
320             my $pathExists=$self->pathExists($path);
321             if ($self->{error}) {
322             warn('ZConf-BGSet createPath: pathExists("'.$path.'") errored. '.
323             'error="'.$self->{error}.'" errorString="'.$self->{errorString}.'"');
324             return undef;
325             }
326              
327             #error if the path already exists
328             if ($pathExists) {
329             $self->{error}=16;
330             $self->{errorString}='The path "'.$path.'" already exists';
331             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
332             return undef;
333             }
334              
335             #sets the path string
336             my $pathString='';
337             if (defined($paths[0])) {
338             $pathString=join("\n", @paths);
339             }
340              
341             #
342             $self->{zconf}->setVar('zbgset', 'paths/'.$path, $pathString);
343              
344             if ($self->{zconf}->{error}) {
345             $self->{error}=2;
346             $self->{errorString}='ZConf setVar errored. error="'.
347             $self->{zconf}->{error}.'" errorString="'.
348             $self->{zconf}->{errorString}.'"';
349             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
350             return undef;
351             }
352              
353             $self->{zconf}->writeSetFromLoadedConfig({config=>'zbgset'});
354             if ($self->{zconf}->{error}) {
355             $self->{error}=2;
356             $self->{errorString}='ZConf writeSetFromLoadedConfig errored. error="'.
357             $self->{zconf}->{error}.'" errorString="'.
358             $self->{zconf}->{errorString}.'"';
359             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
360             return undef;
361             }
362              
363             return 1;
364             }
365              
366             =head2 delPath
367              
368             This removes a specified path.
369              
370             One arguement is taken and that is the name of the path to remove.
371              
372             $zbg->delPath('somepath');
373             if($zbg->{error}){
374             print "Error!\n";
375             }
376              
377             =cut
378              
379             sub delPath{
380             my $self=$_[0];
381             my $path=$_[1];
382             my $function='delPath';
383              
384             #blanks any previous errors
385             $self->errorblank;
386             if ($self->{error}) {
387             warn($self->{module}.' '.$function.': A permanent error is set');
388             return undef;
389             }
390              
391             if (!defined($path)) {
392             $self->{error}=5;
393             $self->{errorString}='No path specified.';
394             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
395             return undef;
396             }
397              
398             my $pathExists=$self->pathExists($path);
399             if ($self->{error}) {
400             warn('ZConf-BGSet delPath: pathExists("'.$path.'") errored. '.
401             'error="'.$self->{error}.'" errorString="'.$self->{errorString}.'"');
402             return undef;
403             }
404              
405             if (!$pathExists) {
406             $self->{error}=14;
407             $self->{errorString}='The path "'.$path.'" does not exist';
408             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
409             return undef;
410             }
411              
412             #remove it
413             my @deleted=$self->{zconf}->regexVarDel('zbgset', '^paths/'.quotemeta($path).'$');
414             if ($self->{zconf}->{error}) {
415             $self->{error}=2;
416             $self->{errorString}='ZConf writeSetFromLoadedConfig errored. error="'.
417             $self->{zconf}->{error}.'" errorString="'.
418             $self->{zconf}->{errorString}.'"';
419             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
420             return undef;
421             }
422              
423              
424             #write it
425             $self->{zconf}->writeSetFromLoadedConfig({config=>'zbgset'});
426             if ($self->{zconf}->{error}) {
427             $self->{error}=2;
428             $self->{errorString}='ZConf writeSetFromLoadedConfig errored. error="'.
429             $self->{zconf}->{error}.'" errorString="'.
430             $self->{zconf}->{errorString}.'"';
431             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
432             return undef;
433             }
434              
435             return 1;
436             }
437              
438             =head2 getDefaultPath
439              
440             This fetches the default path.
441              
442             my $path=$zbg->getDefaultPath;
443             if($zbg->{error}){
444             print "Error!\n";
445             }
446              
447             =cut
448              
449             sub getDefaultPath{
450             my $self=$_[0];
451             my $function='getDefaultPath';
452              
453             #blanks any previous errors
454             $self->errorblank;
455             if ($self->{error}) {
456             warn($self->{module}.' '.$function.': A permanent error is set');
457             return undef;
458             }
459              
460             if (!defined($self->{zconf}->{conf}{zbgset}{path})) {
461             $self->{error}=15;
462             $self->{errorString}='No default path defined';
463             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
464             return undef;
465             }
466              
467             return $self->{zconf}->{conf}{zbgset}{path};
468             }
469              
470             =head2 getLast
471              
472             This fetches information on the last file set.
473              
474             It also does not have to be checked for errors as it
475             will never set an error.
476              
477             No arguements are taken.
478              
479             my %last=$zbg->getLast;
480             if(!defined($last{file})){
481             print "No previous last.\n";
482             }else{
483             print 'file: '.$last{file}."\n".
484             'filltype: '.$last{filltype}."\n".
485             'display: '.$last{display}."\n".
486             'hostname: '.$last{hostname}."\n";
487             }
488              
489             =cut
490              
491             sub getLast{
492             my $self=$_[0];
493             my $function='getLast';
494              
495             $self->errorblank;
496             if ($self->{error}) {
497             warn($self->{module}.' '.$function.': A permanent error is set');
498             return undef;
499             }
500              
501             my %returnH;
502             $returnH{display}=undef;
503             $returnH{hostname}=undef;
504             $returnH{filltype}=undef;
505             $returnH{file}=undef;
506              
507             #returns it if last has been removed for some bloody reason
508             if (!defined($self->{zconf}->{conf}->{zbgset}->{last})) {
509             return %returnH;
510             }
511              
512             #get the last and remove any thing after the newline
513             my $lastraw=$self->{zconf}->{conf}->{zbgset}->{last};
514             $lastraw=~s/\n.*//g;
515              
516             my @lastA=split(/:/, $lastraw,4);
517              
518             $returnH{file}=$lastA[3];
519             $returnH{filltype}=$lastA[2];
520             $returnH{display}=$lastA[1];
521             $returnH{hostname}=$lastA[0];
522              
523             return %returnH;
524             }
525              
526             =head2 getLastRaw
527              
528             Gets the last variable in it's raw form.
529              
530             No arguements are taken.
531              
532             It also does not have to be checked for errors as it
533             will never set an error.
534              
535             For a description of it's formatting, please see
536              
537             my $rawlast=$zbg->getLastRaw();
538             print $rawlast;
539              
540             =cut
541              
542             sub getLastRaw{
543             my $self=$_[0];
544             my $function='getLastRaw';
545              
546             $self->errorblank;
547             if ($self->{error}) {
548             warn($self->{module}.' '.$function.': A permanent error is set');
549             return undef;
550             }
551              
552             #returns it if last has been removed for some bloody reason
553             if (!defined($self->{zconf}->{conf}->{zbgset}->{last})) {
554             return '';
555             }
556              
557             #return the last
558             return $self->{zconf}->{conf}->{zbgset}->{last};
559             }
560              
561             =head2 getPath
562              
563             This fetches a specified path.
564              
565             One arguement is taken and that is the path name.
566              
567             The returned value is an array
568              
569             my @paths=$zbg->getPath('somepath');
570             if($zbg->{error}){
571             print "Error!\n";
572             }
573              
574             =cut
575              
576             sub getPath{
577             my $self=$_[0];
578             my $path=$_[1];
579             my $function='getPath';
580              
581             #blanks any previous errors
582             $self->errorblank;
583             if ($self->{error}) {
584             warn($self->{module}.' '.$function.': A permanent error is set');
585             return undef;
586             }
587              
588             if (!defined($path)) {
589             $self->{error}=5;
590             $self->{errorString}='No path specified.';
591             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
592             return undef;
593             }
594              
595             my $pathExists=$self->pathExists($path);
596             if ($self->{error}) {
597             warn('ZConf-BGSet getPath: pathExists("'.$path.'") errored. '.
598             'error="'.$self->{error}.'" errorString="'.$self->{errorString}.'"');
599             return undef;
600             }
601              
602             if (!$pathExists) {
603             $self->{error}=14;
604             $self->{errorString}='The path "'.$path.'" does not exist';
605             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
606             return undef;
607             }
608              
609             return split(/\n/, $self->{zconf}->{conf}{zbgset}{'paths/'.$path});
610             }
611              
612             =head2 getSet
613              
614             This gets what the current set is.
615              
616             my $set=$zbg->getSet;
617             if($zcr->{error}){
618             print "Error!\n";
619             }
620              
621             =cut
622              
623             sub getSet{
624             my $self=$_[0];
625             my $function='getSet';
626              
627             $self->errorblank;
628             if ($self->{error}) {
629             warn($self->{module}.' '.$function.': A permanent error is set');
630             return undef;
631             }
632              
633             my $set=$self->{zconf}->getSet('zbgset');
634             if($self->{zconf}->{error}){
635             $self->{error}=2;
636             $self->{errorString}='ZConf error getting the loaded set the config "zbgset".'.
637             ' ZConf error="'.$self->{zconf}->{error}.'" '.
638             'ZConf error string="'.$self->{zconf}->{errorString}.'"';
639             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
640             return undef;
641             }
642              
643             return $set;
644             }
645              
646             =head2 getSetter
647              
648             This fetches a setter.
649              
650             The only image accepted is the name of the setter to fetch.
651              
652             my $setter=$zbg->getSetter('full');
653             if($zbg->{error}){
654             print "Error!\n";
655             }
656              
657             #escapes the image
658             my $image='/tmp/something.jpg';
659             $image=~s/(["`\$\\ ])/\\$1/g;
660             $image=~qq($image);
661              
662             #replaces %%%THEFILE%%% in the setter with the filename
663             $setterr=~s/\%\%\%THEFILE\%\%\%/$image/g;
664              
665             =cut
666              
667             sub getSetter{
668             my $self=$_[0];
669             my $name=$_[1];
670             my $function='getSetter';
671              
672             #blanks any previous errors
673             $self->errorblank;
674             if ($self->{error}) {
675             warn($self->{module}.' '.$function.': A permanent error is set');
676             return undef;
677             }
678              
679             if (!$self->validSetterName($name)) {
680             $self->{error}=6;
681             $self->{errorString}='"'.$name.'" is not a valid setter name.';
682             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
683             return undef;
684             }
685              
686             if (!defined($self->{zconf}->{conf}->{zbgset}->{$name})) {
687             $self->{error}=7;
688             $self->{errorString}='"'.$name.'" does not exist.';
689             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
690             return undef;
691             }
692              
693             return $self->{zconf}->{conf}->{zbgset}->{$name};
694             }
695              
696             =head2 init
697              
698             This initializes it or a new set.
699              
700             If the specified set already exists, it will be reset.
701              
702             One arguement is required and it is the name of the set. If
703             it is not defined, ZConf will use the default one.
704              
705             #creates a new set named foo
706             $zbg->init('foo');
707             if($zbg->{error}){
708             print "Error!\n";
709             }
710              
711             #creates a new set with ZConf choosing it's name
712             $zbg->init();
713             if($zbg->{error}){
714             print "Error!\n";
715             }
716              
717             =cut
718              
719             sub init{
720             my $self=$_[0];
721             my $set=$_[1];
722             my $function='init';
723              
724             #blanks any previous errors
725             $self->errorblank;
726             if ($self->{error}) {
727             warn($self->{module}.' '.$function.': A permanent error is set');
728             return undef;
729             }
730              
731             my $returned = $self->{zconf}->configExists("zbgset");
732             if(defined($self->{zconf}->{error})){
733             $self->{error}=2;
734             $self->{errorString}="Could not check if the config 'zbgset' exists.".
735             " It failed with '".$self->{zconf}->{error}."', '"
736             .$self->{zconf}->{errorString}."'";
737             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
738             return undef;
739             }
740              
741             #create the config if it does not exist
742             if (!$returned) {
743             $self->{zconf}->createConfig("zbgset");
744             if ($self->{zconf}->{error}) {
745             $self->{error}=2;
746             $self->{errorString}="Could not create the ZConf config 'zbgset'.".
747             " It failed with '".$self->{zconf}->{error}."', '"
748             .$self->{zconf}->{errorString}."'";
749             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
750             return undef;
751             }
752             }
753              
754             #create the new set
755             $self->{zconf}->writeSetFromHash({config=>"zbgset", set=>$set},
756             {
757             savelast=>"true",
758             filltype=>"auto",
759             numberoflast=>"15",
760             postSetRefresh=>"false",
761             postSetRefresher=>"zbgfbmb -l",
762             maxdiff=>".2",
763             filltype=>"auto",
764             full=>'hsetroot -full \'%%%THEFILE%%%\'',
765             tile=>'hsetroot -tile \'%%%THEFILE%%%\'',
766             fill=>'hsetroot -fill \'%%%THEFILE%%%\'',
767             center=>'hsetroot -center \'%%%THEFILE%%%\'',
768             path=>'default'
769             }
770             );
771             #error if the write failed
772             if ($self->{zconf}->{error}) {
773             $self->{error}=2;
774             $self->{errorString}="writeSetFromHash failed.".
775             " It failed with '".$self->{zconf}->{error}."', '"
776             .$self->{zconf}->{errorString}."'";
777             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
778             return undef;
779             }
780              
781             return 1;
782             }
783              
784             =head2 listPaths
785              
786             This gets a lists of configured paths.
787              
788             my @paths=$zbg->listPaths();
789             if($zbg->{error}){
790             print "Error!\n";
791             }
792              
793             =cut
794              
795             sub listPaths{
796             my $self=$_[0];
797             my $function='listPaths';
798              
799             #blanks any previous errors
800             $self->errorblank;
801             if ($self->{error}) {
802             warn($self->{module}.' '.$function.': A permanent error is set');
803             return undef;
804             }
805              
806             my %pathsH=$self->{zconf}->regexVarGet('zbgset', '^paths/');
807             if ($self->{zconf}->{error}) {
808             $self->{error}=2;
809             $self->{errorString}="writeSetFromHash failed.".
810             " It failed with '".$self->{zconf}->{error}."', '"
811             .$self->{zconf}->{errorString}."'";
812             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
813             return undef;
814             }
815              
816             #
817             my @keys=keys(%pathsH);
818             my @paths;
819             my $int=0;
820             while (defined($keys[$int])) {
821             my @split=split(/\//, $keys[$int],2);
822              
823             push(@paths, $split[1]);
824              
825             $int++;
826             }
827              
828              
829             return @paths;
830             }
831              
832             =head2 listSets
833              
834             This lists the available sets.
835              
836             my @sets=$zbg->listSets;
837             if($zcr->{error}){
838             print "Error!";
839             }
840              
841             =cut
842              
843             sub listSets{
844             my $self=$_[0];
845             my $function='listSets';
846              
847             #blanks any previous errors
848             $self->errorBlank;
849             if ($self->{error}) {
850             warn($self->{module}.' '.$function.': A permanent error is set');
851             return undef;
852             }
853              
854             my @sets=$self->{zconf}->getAvailableSets('zbgset');
855             if($self->{zconf}->{error}){
856             $self->{error}=2;
857             $self->{errorString}='ZConf error listing sets for the config "zbgset".'.
858             ' ZConf error="'.$self->{zconf}->{error}.'" '.
859             'ZConf error string="'.$self->{zconf}->{errorString}.'"';
860             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
861             return undef;
862             }
863              
864             return @sets;
865             }
866              
867             =head2 pathExists
868              
869             This verifies a path exists.
870              
871             Only one arguement is taken and that is the name of the path.
872              
873             my $returned=$zbg->pathExists('foo');
874             if($zbg->{error}){
875             print "Error!\n";
876             }else{
877             if(!$returned){
878             print "The path 'foo' does not exist.\n";
879             }
880             }
881              
882             =cut
883              
884             sub pathExists{
885             my $self=$_[0];
886             my $path=$_[1];
887             my $function='pathExists';
888              
889             #blank any previous errors
890             $self->errorblank;
891             if ($self->{error}) {
892             warn($self->{module}.' '.$function.': A permanent error is set');
893             return undef;
894             }
895              
896             #error if no path is specified
897             if (!defined($path)) {
898             $self->{error}=5;
899             $self->{errorString}='The path is undefined.';
900             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
901             return undef;
902             }
903              
904             #set fullpath to the full variable name
905             my $fullpath='paths/'.$path;
906              
907             #if it is not defined, return undef
908             if (!defined($self->{zconf}->{conf}->{zbgset}->{$fullpath})) {
909             return undef;
910             }
911              
912             return 1;
913             }
914              
915             =head2 readSet
916              
917             This reads a specific set. If the set specified
918             is undef, the default set is read.
919              
920             #read the default set
921             $zbg->readSet();
922             if($zbg->{error}){
923             print "Error!\n";
924             }
925              
926             #read the set 'someSet'
927             $zbg->readSet('someSet');
928             if($zbg->{error}){
929             print "Error!\n";
930             }
931              
932             =cut
933              
934             sub readSet{
935             my $self=$_[0];
936             my $set=$_[1];
937             my $function='readSet';
938            
939             #blanks any previous errors
940             $self->errorBlank;
941             if ($self->{error}) {
942             warn($self->{module}.' '.$function.': A permanent error is set');
943             return undef;
944             }
945              
946             $self->{zconf}->read({config=>'zbgset', set=>$set});
947             if ($self->{zconf}->{error}) {
948             $self->{error}=2;
949             $self->{errorString}='ZConf error reading the config "zbgset".'.
950             ' ZConf error="'.$self->{zconf}->{error}.'" '.
951             'ZConf error string="'.$self->{zconf}->{errorString}.'"';
952             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
953             return undef;
954             }
955              
956             return 1;
957             }
958              
959             =head2 setBG
960              
961             =head3 args hash
962              
963             =head4 image
964              
965             The picture to set the background to.
966              
967             =head4 filltype
968              
969             The fill type to use. If this is not defined, the default one
970             will be used.
971              
972             =head4 dontSave
973              
974             If this is set to true, it will not be added to the last list.
975              
976             $zbg->setBG({image='/tmp/something.jpg', filltype=>'auto'});
977             if($zbg->{error}){
978             print "Error!\n";
979             }
980              
981             #the same as the above, but not saved to the last list
982             $zbg->setBG({image='/tmp/something.jpg', filltype=>'auto', dontSave='0'});
983             if($zbg->{error}){
984             print "Error!\n";
985             }
986              
987             =cut
988              
989             sub setBG{
990             my $self=$_[0];
991             my %args;
992             if(defined($_[1])){
993             %args= %{$_[1]};
994             }
995             my $function='setBG';
996              
997             $self->errorblank;
998             if ($self->{error}) {
999             warn($self->{module}.' '.$function.': A permanent error is set');
1000             return undef;
1001             }
1002              
1003             #default to the default filltype if none is specified
1004             if (!defined($args{filltype})) {
1005             $args{filltype}=$self->{zconf}->{conf}->{zbgset}->{filltype};
1006             }
1007              
1008             #error if no image is specified
1009             if (!defined($args{image})) {
1010             $self->{error}=5;
1011             $self->{errorString}='$args{image} is not specified.';
1012             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
1013             return undef;
1014             }
1015              
1016             #get the absolute path
1017             $args{image}=File::Spec->rel2abs($args{image});
1018              
1019             my $origimage=$args{image};
1020              
1021             #error if it does not exist or is not a file
1022             if (! -f $args{image}) {
1023             $self->{error}=13;
1024             $self->{errorString}='"'.$args{image}.'" does not exist or is not a file.';
1025             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
1026             return undef;
1027             }
1028              
1029             #get the filltype if it is set to auto
1030             if ($args{filltype} eq 'auto') {
1031             my $x11res=X11::Resolution->new;
1032             my ($xres, $yres)=$x11res->getResolution;
1033              
1034             my $iffs = Image::Size::FillFullSelect->new();
1035             $args{filltype} = $iffs->select($args{image}, undef, undef, $xres, $yres);
1036             if(!defined($args{filltype})){
1037             warn("ZConf-BGSet setBG:7: Auto selection for the image size failed. Image::Size".
1038             "does not regard the file, '".$args{image}."', as a image");
1039             exit 7;
1040             };
1041             }
1042              
1043             #gets the setter and verify it is a legit one
1044             my $setter=$self->getSetter($args{filltype});
1045             if ($self->{error}) {
1046             warn('ZConf-BGSet setBG: getSetter failed');
1047             return undef;
1048             }
1049              
1050             #escapes it
1051             $args{image}=~s/(["`\$\\ ])/\\$1/g;
1052             $args{image}=~qq($args{image});
1053              
1054             #replaces %%%THEFILE%%%% with the image
1055             $setter=~s/\%\%\%THEFILE\%\%\%/$args{image}/g;
1056              
1057             #run it
1058             system($setter);
1059              
1060             #gets the exit code
1061             my $exitcode=$? >> 8;
1062              
1063             if ($? eq '-1') {
1064             $self->{error}=12;
1065             $self->{errorString}='Failed to execute the setter, "'.$setter.'".';
1066             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
1067             return undef;
1068             }
1069              
1070             if ($exitcode > 0) {
1071             $self->{error}=12;
1072             $self->{errorString}='The Ssetter, "'.$setter.'", exited with a non-zero.';
1073             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
1074             return undef;
1075             }
1076              
1077             #only add it to last if we need to
1078             if (!$args{dontSave}) {
1079             $self->addToLast({image=>$origimage,filltype=>$args{filltype}});
1080             if ($self->{error}) {
1081             #we don't set any error numbers here as addToLast already did
1082             warn('ZConf-BGSet setBG: addToLast failed');
1083             return undef;
1084             }
1085             }
1086              
1087             return 1;
1088             }
1089              
1090             =head2 setLast
1091              
1092             This sets the background image to last. It will also not re-append th
1093             e image to the last list.
1094              
1095             No arguements are accepted.
1096              
1097             $zbg->setLast();
1098             if($zbg->{error}){
1099              
1100             }
1101              
1102             =cut
1103              
1104             sub setLast{
1105             my $self=$_[0];
1106             my $function='setLast';
1107              
1108             $self->errorblank;
1109             if ($self->{error}) {
1110             warn($self->{module}.' '.$function.': A permanent error is set');
1111             return undef;
1112             }
1113              
1114             my $lastraw=$self->getLastRaw;
1115              
1116             $lastraw=~s/\n.*//g;
1117              
1118             my @lastA=split(/:/, $lastraw,4);
1119              
1120             $self->setBG({image=>$lastA[3], filltype=>$lastA[2], dontSave=>1});
1121             if ($self->{error}) {
1122             warn('ZConf-BGSet setLast: setBG errored');
1123             return undef;
1124             }
1125              
1126             return 1;
1127             }
1128              
1129             =head2 setRand
1130              
1131             This sets a random background.
1132              
1133             One option is accepted and that is the path to use. If
1134             it is note specified, 'default' will be used.
1135              
1136             #set one from the default path
1137             $zbg->setRand();
1138             if($zbg->{error}){
1139             print "Error!\n";
1140             }
1141            
1142             #set one from the default path
1143             $self->setRand('somepath');
1144             if($zbg->{error}){
1145             print "Error!\n";
1146             }
1147              
1148             =cut
1149              
1150             sub setRand{
1151             my $self=$_[0];
1152             my $path=$_[1];
1153             my $function='setRand';
1154              
1155             $self->errorblank;
1156             if ($self->{error}) {
1157             warn($self->{module}.' '.$function.': A permanent error is set');
1158             return undef;
1159             }
1160              
1161             #set the path to 'default' if it is specified
1162             if (!defined($path)) {
1163             $path=$self->{zconf}{conf}{zbgset}{path};
1164             }
1165              
1166             #error if no path is specified
1167             if (!defined($self->{zconf}{conf}{zbgset}{'paths/'.$path})) {
1168             $self->{error}=14;
1169             $self->{errorString}='The path "'.$path.'" does not exist';
1170             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
1171             return undef;
1172             }
1173              
1174             #splits the path appart
1175             my @paths=split(/\n/, $self->{zconf}{conf}{zbgset}{'paths/'.$path});
1176              
1177             #gets select which to use
1178             my $randomPathInt=rand($#paths);
1179             $randomPathInt =~ s/\.[0123456789]*//;
1180             my $pathToUse=$paths[$randomPathInt];
1181              
1182             #escapes it
1183             $pathToUse=~s/(["`\$\\ ])/\\$1/g;
1184             $pathToUse=~qq($pathToUse);
1185              
1186             my @files=`find $pathToUse -type f`;
1187              
1188             my $filesInt=rand($#files);
1189             $filesInt =~ s/\.[0123456789]*//;
1190              
1191             my $image=$files[$filesInt];
1192              
1193             chomp($image);
1194              
1195             $self->setBG({image=>$image});
1196              
1197             return 1;
1198             }
1199              
1200             =head2 setPath
1201              
1202             This sets a sets/creates a path. If it is set, it will be overwritten.
1203              
1204             Two arguements are required. The first is the name of the path
1205             and the second is a array ref containing the various paths.
1206              
1207             $zbg->setPath('somepath', \@paths);
1208             if($zbg->{error}){
1209             print "Error!\n";
1210             }
1211              
1212             =cut
1213              
1214             sub setPath{
1215             my $self=$_[0];
1216             my $path=$_[1];
1217             my @paths=@{$_[2]};
1218             my $function='setPath';
1219              
1220             #blanks any previous errors
1221             $self->errorblank;
1222             if ($self->{error}) {
1223             warn($self->{module}.' '.$function.': A permanent error is set');
1224             return undef;
1225             }
1226              
1227             if (!defined($path)) {
1228             $self->{error}=5;
1229             $self->{errorString}='No path specified.';
1230             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
1231             return undef;
1232             }
1233              
1234             my $pathString=join("\n", @paths);
1235              
1236             #
1237             $self->{zconf}->setVar('zbgset', 'paths/'.$path, $pathString);
1238              
1239             if ($self->{zconf}->{error}) {
1240             $self->{error}=2;
1241             $self->{errorString}='ZConf setVar errored. error="'.
1242             $self->{zconf}->{error}.'" errorString="'.
1243             $self->{zconf}->{errorString}.'"';
1244             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
1245             return undef;
1246             }
1247              
1248             $self->{zconf}->writeSetFromLoadedConfig({config=>'zbgset'});
1249             if ($self->{zconf}->{error}) {
1250             $self->{error}=2;
1251             $self->{errorString}='ZConf writeSetFromLoadedConfig errored. error="'.
1252             $self->{zconf}->{error}.'" errorString="'.
1253             $self->{zconf}->{errorString}.'"';
1254             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
1255             return undef;
1256             }
1257              
1258             return 1;
1259             }
1260              
1261             =head2 setterExists
1262              
1263             This verifies a path exists.
1264              
1265             Only one arguement is taken and that is the name of the setter.
1266              
1267             my $returned=$zbg->setterExists('foo');
1268             if($zbg->{error}){
1269             print "Error!\n";
1270             }else{
1271             if(!$returned){
1272             print "The setter 'foo' does not exist.\n";
1273             }
1274             }
1275              
1276             =cut
1277              
1278             sub setterExists{
1279             my $self=$_[0];
1280             my $setter=$_[1];
1281             my $function='setterExists';
1282              
1283             #blank any previous errors
1284             $self->errorblank;
1285             if ($self->{error}) {
1286             warn($self->{module}.' '.$function.': A permanent error is set');
1287             return undef;
1288             }
1289              
1290             #error if no path is specified
1291             if (!defined($setter)) {
1292             $self->{error}=5;
1293             $self->{errorString}='The setter is undefined.';
1294             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
1295             return undef;
1296             }
1297              
1298             if (!$self->validSetterName($setter)) {
1299             $self->{error}=6;
1300             $self->{errorString}='"'.$setter.'" is not a valid setter name.';
1301             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
1302             return undef;
1303             }
1304              
1305             #if it is not defined, return undef
1306             if (!defined($self->{zconf}->{conf}->{zbgset}->{$setter})) {
1307             return undef;
1308             }
1309              
1310             return 1;
1311             }
1312              
1313             =head2 setSetter
1314              
1315             Sets the setter to be used for a specific fill type.
1316              
1317             Two arguements are required. The first is the setter name
1318             and the second is setter.
1319              
1320             $zbg->setSetter('full', 'hsetroot -full %%%THEFILE%%%');
1321             if($zbg->{error}){
1322             print "Error!\n";
1323             }
1324              
1325             =cut
1326              
1327             sub setSetter{
1328             my $self=$_[0];
1329             my $name=$_[1];
1330             my $setter=$_[2];
1331             my $function='setSetter';
1332              
1333             #blanks any previous errors
1334             $self->errorblank;
1335             if ($self->{error}) {
1336             warn($self->{module}.' '.$function.': A permanent error is set');
1337             return undef;
1338             }
1339              
1340             if (!$self->validSetterName($name)) {
1341             $self->{error}=6;
1342             $self->{errorString}='"'.$name.'" is not a valid setter name.';
1343             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
1344             return undef;
1345             }
1346              
1347             #set it
1348             $self->{zconf}->setVat('zbgset', $name, $setter);
1349             if ($self->{zconf}->{error}) {
1350             $self->{error}=2;
1351             $self->{errorString}="setVar failed.".
1352             " It failed with '".$self->{zconf}->{error}."', '"
1353             .$self->{zconf}->{errorString}."'";
1354             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
1355             return undef;
1356             }
1357              
1358             #save it
1359             $self->{zconf}->writeSetFromLoadedConfig('zbgset', $name, $setter);
1360             if ($self->{zconf}->{error}) {
1361             $self->{error}=2;
1362             $self->{errorString}="writeSetFromLoadedConfig failed.".
1363             " It failed with '".$self->{zconf}->{error}."', '"
1364             .$self->{zconf}->{errorString}."'";
1365             warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
1366             return undef;
1367             }
1368              
1369             return 1;
1370             }
1371              
1372             =head2 validSetterName
1373              
1374             Checks if a name specified for a setter is valid or not.
1375              
1376             There is no reason to check for an error on this as it does not
1377             set any. It just checks that the specified name is valid. If it
1378             is not set, it will also return false.
1379              
1380             if(!$zbg->validSetterName('monkey')){
1381             print "No valid.\n";
1382             }
1383              
1384             if(!$zbg->validSetterName('full')){
1385             print "No valid.\n";
1386             }
1387              
1388             =cut
1389              
1390             sub validSetterName{
1391             my $self=$_[0];
1392             my $name=$_[1];
1393             my $function='validSetterName';
1394              
1395             $self->errorblank;
1396             if ($self->{error}) {
1397             warn($self->{module}.' '.$function.': A permanent error is set');
1398             return undef;
1399             }
1400              
1401             if (!defined($name)) {
1402             return undef;
1403             }
1404              
1405             if ($name =~ /^ft\//) {
1406             return 1;
1407             }
1408              
1409             if ($name eq 'full') {
1410             return 1;
1411             }
1412              
1413             if ($name eq 'fill') {
1414             return 1;
1415             }
1416              
1417             if ($name eq 'tile') {
1418             return 1;
1419             }
1420              
1421             if ($name eq 'center') {
1422             return 1;
1423             }
1424              
1425             #if we get here it has not been matched and thus false
1426             return undef;
1427             }
1428              
1429             =head2 errorblank
1430              
1431             This blanks the error storage and is only meant for internal usage.
1432              
1433             It does the following.
1434              
1435             $self->{error}=undef;
1436             $self->{errorString}="";
1437              
1438             =cut
1439              
1440             #blanks the error flags
1441             sub errorblank{
1442             my $self=$_[0];
1443              
1444             if ($self->{perror}) {
1445             return undef;
1446             }
1447              
1448             $self->{error}=undef;
1449             $self->{errorString}="";
1450              
1451             return 1;
1452             }
1453              
1454             =head1 FILL TYPES
1455              
1456             =head2 full
1457              
1458             The setter to use for setting fill the screen and keep the same aspect ratio.
1459              
1460             =head2 fill
1461              
1462             The setter to use for setting the image to fill the screen.
1463              
1464             =head2 center
1465              
1466             The setter to use to center the image.
1467              
1468             =head2 tile
1469              
1470             The setter to use to tile the image.
1471              
1472             =head2 auto
1473              
1474             This will automatically choose between fill and full. The variable 'maxdiff'
1475             is used to determine what it should be set to.
1476              
1477             =head2 ^ft/
1478              
1479             Any thing matching the regex /^ft\// can also be used as a setter.
1480              
1481             =head1 ZConf Keys
1482              
1483             =head2 center
1484              
1485             This contains the setter that will be used for when setting a centered image.
1486             '%%%THEFILE%%%' is replaced at runtime with the name of the file.
1487              
1488             center=hsetroot -center %%%THEFILE%%%
1489              
1490             =head2 fill
1491              
1492             This key contains setter to be used for fill the background with a resized image.
1493             '%%%THEFILE%%%' is replaced at runtime with the name of the file.
1494              
1495             fill=hsetroot -fill %%%THEFILE%%%
1496              
1497             =head2 full
1498              
1499             This key contains setter to be used for fill the background with a scaled image.
1500             '%%%THEFILE%%%' is replaced at runtime with the name of the file.
1501              
1502             full=hsetroot -full %%%THEFILE%%%
1503              
1504             =head2 last
1505              
1506             This contains the last several images set. There is one entry per line. The format
1507             is as below.
1508              
1509             :::
1510              
1511             =head2 maxdiff
1512              
1513             This contains the maximum difference for between any two any two sides when choosing
1514             between fill and full.
1515              
1516             maxdiff=.2
1517              
1518             =head2 numberoflast
1519              
1520             The number of last entries to save.
1521              
1522             =head2 path
1523              
1524             This is the path to use for when selecting a random image.
1525              
1526             =head2 paths/
1527              
1528             This is a path. Each path have multiple paths. Each path is seperated by a new line.
1529              
1530             =head2 postSetRefresh
1531              
1532             Wether or not it should run something after it has been set. This is a perl boolean value.
1533              
1534             postSetRefresh=0
1535              
1536             =head2 postSetRefresher
1537              
1538             If 'postSetRefresh' is set to true, this is ran.
1539              
1540             =head2 tile
1541              
1542             This key contains setter to be used for tiling. '%%%THEFILE%%%' is replaced at
1543             runtime with the name of the file.
1544              
1545             tile=hsetroot -tile %%%THEFILE%%%
1546              
1547             =head1 ERROR CODES
1548              
1549             =head2 1
1550              
1551             Could not initialize ZConf.
1552              
1553             =head2 2
1554              
1555             ZConf error.
1556              
1557             =head2 3
1558              
1559             Failed to create the ZConf config 'zbgset'.
1560              
1561             =head2 4
1562              
1563             Autoinit errored.
1564              
1565             =head2 5
1566              
1567             Undefined arguement.
1568              
1569             =head2 6
1570              
1571             Invalid setter name.
1572              
1573             =head2 7
1574              
1575             Setter does not exist.
1576              
1577             =head2 8
1578              
1579             Could not determine the display.
1580              
1581             =head2 9
1582              
1583             Invalid hostname.
1584              
1585             =head2 10
1586              
1587             Invalid display name.
1588              
1589             =head2 11
1590              
1591             Image::Size::FillFullSelect->select failed.
1592              
1593             =head2 12
1594              
1595             The file does not exist.
1596              
1597             =head2 13
1598              
1599             The file does not exist.
1600              
1601             =head2 14
1602              
1603             The path does not exist.
1604              
1605             =head2 15
1606              
1607             No default path defined.
1608              
1609             =head2 16
1610              
1611             The path already exists.
1612              
1613             =head1 AUTHOR
1614              
1615             Zane C. Bowers, C<< >>
1616              
1617             =head1 BUGS
1618              
1619             Please report any bugs or feature requests to C, or through
1620             the web interface at L. I will be notified, and then you'll
1621             automatically be notified of progress on your bug as I make changes.
1622              
1623              
1624              
1625              
1626             =head1 SUPPORT
1627              
1628             You can find documentation for this module with the perldoc command.
1629              
1630             perldoc ZConf::BGSet
1631              
1632              
1633             You can also look for information at:
1634              
1635             =over 4
1636              
1637             =item * RT: CPAN's request tracker
1638              
1639             L
1640              
1641             =item * AnnoCPAN: Annotated CPAN documentation
1642              
1643             L
1644              
1645             =item * CPAN Ratings
1646              
1647             L
1648              
1649             =item * Search CPAN
1650              
1651             L
1652              
1653             =back
1654              
1655              
1656             =head1 ACKNOWLEDGEMENTS
1657              
1658              
1659             =head1 COPYRIGHT & LICENSE
1660              
1661             Copyright 2009 Zane C. Bowers, all rights reserved.
1662              
1663             This program is free software; you can redistribute it and/or modify it
1664             under the same terms as Perl itself.
1665              
1666              
1667             =cut
1668              
1669             1; # End of ZConf::BGSet