Thank you both for your suggestions.

@Shlomi: It seems that i'm completely unable to implement dispatch tables here
(but i now know what they are, hope to use them in the near future), so i used
the given-when approach...it seemed better than endless if-elsif's.

@Brandon: I'll stick with the m//, mostly because it reminds me that i can use
any delimiter instead of the slashes. I hope to get more experience tho, and
get rid of it. Also, i couldn't find any reference that \d in regex is
different from [0-9] (or [:digit:]), but i'm interested for more information
about it.

@both: Thanks again for looking into my code. You helped me learn a lot more
(and in less time) than try to figure them out myself. I tried to use most
of your suggestions...hope I've done it well enough.

So, here is the new code (i'm pretty happy with how it became):

#!/usr/bin/perl

use strict;
use warnings FATAL => qw( uninitialized );
use v5.16;

use X::Osd;
use IPC::Cmd qw( can_run run );

# check if amixer exists and get its path
my $amixer_path = can_run('amixer') 
    or die 'amixer is not available';

# create osd bar (two output lines)
my $osd = X::Osd->new(2);
# osd bar properties
$osd->set_font("-*-terminus-bold-*-*-*-18-*-*-*-*-*-*-*");
$osd->set_shadow_offset(1);
$osd->set_pos(XOSD_bottom);
$osd->set_align(XOSD_center);
$osd->set_horizontal_offset(0);
$osd->set_vertical_offset(30);
$osd->set_timeout(5);

# locate (and if missing create) named pipe
my $fifo_file = $ENV{OSD_VOLUME} // "$ENV{HOME}/.osd-volume.fifo";
unless (-p $fifo_file) {
    # if anyother filetype is there, just die
    if (-e $fifo_file) {
        die "$fifo_file: not a named pipe";
    }
    else {
    # create the named pipe
        require POSIX;
        POSIX::mkfifo( $fifo_file, 0600 )
            or die "cannot mkfifo $fifo_file: $!";
    }
}

# open named pipe
open( my $fifo_fh, "+<", $fifo_file ) 
    or die "cannot open $fifo_file: $!";

my $amixer_vol;

# constantly read from it
FIFO_INPUT:
while (chomp( my $fifo_input = <$fifo_fh> )) {
    given ($fifo_input) {
        when ('up')     { $amixer_vol = '3%+'; }
        when ('down')   { $amixer_vol = '3%-'; }
        when ('toggle') { $amixer_vol = 'toggle'; }
        when ('exit')   { last FIFO_INPUT; }
        default         {
            warn "$fifo_input: invalid input";
            next FIFO_INPUT;
        }
    }

    # set new volume value and read the output
    my $amixer_cmd = "$amixer_path sset Master,0 $amixer_vol";
    my $amixer;
    run(
        command => $amixer_cmd,
        verbose => 0,
        buffer  => \$amixer,
    );

    # red output color if sound mutes, blue otherwise
    my $colour = ( index($amixer, '[off]') != -1 ) ? '#DD0000' : '#1E90FF';
    $osd->set_colour($colour);

    # get new volume value and print osd bar
    if (my ($volume) = $amixer =~ m/(\d{1,3})%/ ) {
        $osd->string(0, "Master Volume:${volume}%");
        $osd->percentage(1, $volume);
    }
}

# close pipe before exit
close($fifo_fh);
exit(0);

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
http://learn.perl.org/


Reply via email to