-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello,
despite the disappointing lack of response i kept working on this little plugin. It now features * setting the brightness threshold via the 'brightnessThreshold' X resource * inverting any web-(html-) style color code (e.g. #123abc), named colors (like defined in $prefix/share/X11/rgb.txt) and the convenience urxvt color codes (0-15) * if 'RGBColourFile' is not set (e.g. to /usr/share/X11/rgb.txt) tries to read '/usr/share/X11/rgb.txt' and '/usr/local/share/X11/rgb.txt', does not invert colour otherwise * inverts foreground, background and if set: colorBD, colorIT, and colorUL * respects colorRV resource * currently ignores alpha values for inverted colours, keeps the original colour though I've done some testing with different combinations of colour names/values and I think it works pretty well now. Any comments or bug fixes are welcome though. :) Best regards, Jochen On 19.10.2010 11:04, Jochen Keil wrote: > Hello altogether, > > Maybe you remember my questions back in the end of August about how I > could invert the terminal (using reversed video) as a reaction on the > DBus event 'BrightnessChanged' (at least as it is emitted by the > 'org.gnome.PowerManager.Backlight' interface). > > Marc pointed me to the AnyEvent::DBus module which does a good job > dealing with Net::DBus (no more Net::DBus::Reactor which causes the > module to block). Furthermore, since urxvt provides already an AnyEvent > event loop integrating my module was fairly easy. > > I stumbled about some really nasty problem though which caused the long > delay and nearly brought me away from this. Let me briefly explain it to > you and show you the solution. > > Initially I just tried to get a DBus session bus object with > Net::DBus->session(). This worked but unfortunately the bus object > blocked and kept the process running even after closing the terminal. > The solution to this was quite simple but took me a long time to figure > out because I had to dig through the whole Net::DBus API. A connection > can be closed with the 'disconnect()' method. Having a bus object with a > get_connection() method this is as simple as > '$bus->get_connection()->disconnect()'. Since you are not allowed to > close a shared connection it has to be opened private (session(private > => 1)). > That's it. Now it is possible to shut down the DBus connection and exit > gracefully. > > I hope you found this interesting and if you like this module feel free > to add it to urxvt. Any comments and improvements are welcome. > Some of the ideas I have include > > * making the threshold (currently fixed to 80) a configurable X resource > * reacting on any BrightnessChanged signal, not only from gnome pm > * making the behaviour configurable (e.g. set fg/bg color instead of rvid) > * abstract the whole thing so that any DBus event can cause any action > > Please tell me if you are interested in this, or have suggestions. Of > course, if there's no interest in it I'll probably keep it in an IWM (it > works for me) state.. > > I can also upload to a public repository if you want to, so I don't need > to send updates every time to this list. > > Have fun, > > Jochen > > > > _______________________________________________ > rxvt-unicode mailing list > [email protected] > http://lists.schmorp.de/cgi-bin/mailman/listinfo/rxvt-unicode -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) iEYEARECAAYFAkzB+SwACgkQtVwvsA+W4CD1sQCeOH8qkiDqa3RuHH1saUx9TbVZ ibYAniyQMwjDpUbDKTfCGL6R0i0lu1bI =SAm9 -----END PGP SIGNATURE-----
#! perl
use AnyEvent::DBus;
use Net::DBus::Annotation qw(:call);
sub on_start {
my ($self) = @_;
my ($term) = $self->{term};
my ($reversed) = 0;
my ($thresh) = $term->x_resource("brightnessThreshold");
%{$term->{colours}} = getColours($self);
$term->{bus} = Net::DBus->session(private => 1);
$term->{upower} = $self->{term}->{bus}->get_service('org.gnome.PowerManager');
$term->{object} = $self->{term}->{upower}->get_object(
'/org/gnome/PowerManager/Backlight',
'org.gnome.PowerManager.Backlight');
if ($term->{object}->GetBrightness() < $thresh) {
reverseVideo($self, 1);
$reversed = 1;
}
$term->{object}->connect_to_signal('BrightnessChanged', sub {
my $brightness = $_[0];
if ($brightness < $thresh && $reversed == 0) {
reverseVideo($self, 1);
$reversed = 1;
} elsif ($brightness > $thresh && $reversed == 1) {
reverseVideo($self, 0);
$reversed = 0;
}
});
()
}
sub on_destroy {
my ($self) = @_;
$self->{term}->{bus}->get_connection()->disconnect();
()
}
sub reverseVideo {
my ($self, $reverse) = @_;
my ($term) = $self->{term};
my (%colours) = %{$term->{colours}};
my (%tc) = ("foreground" => 10,
"background" => 11,
"colorIT" => 704,
"colorBD" => 706,
"colorUL" => 707);
if ($reverse == 1) {
while (my ($cotype, $colour) = each(%colours)) {
if ($cotype =~ m/(reverse)(.*)/) {
$term->cmd_parse("\033]$tc{$2};$colour\007");
}
}
} else {
while (my ($cotype, $colour) = each(%colours)) {
if ($cotype !~ m/(reverse)(.*)/) {
$term->cmd_parse("\033]$tc{$cotype};$colour\007");
}
}
}
$self->want_refresh();
}
sub getColours {
my ($self) = @_;
my %colours = readColours($self);
%colours = resolveColours($self, %colours);
return %colours;
}
sub readColours {
my ($self) = @_;
my ($term) = ($self->{term});
return (
foreground => $term->x_resource("foreground")
, background => $term->x_resource("background")
, colorBD => $term->x_resource("colorBD")
, colorIT => $term->x_resource("colorIT")
, colorUL => $term->x_resource("colorUL")
, colorRV => $term->x_resource("colorRV")
);
}
sub invertHexRGB {
my ($colour, $mask, @invrgb);
$_[0] =~ m/rgb(a?):(\w{1,4})\/(\w{1,4})\/(\w{1,4})\/?(\w{1,4})?/i;
my @rgb = ($2, $3, $4);
foreach $colour (@rgb) {
my $bitlen = length($colour);
$mask = "f" x $bitlen;
push(@invrgb, sprintf("%0*x", $bitlen, (hex($mask) - hex($colour))));
}
return "rgb:" . $invrgb[0] . "/" . $invrgb[1] . "/" . $invrgb[2];
}
sub resolveColours {
my ($self, %colours) = @_;
my %reverseColours;
while (my ($key, $value) = each(%colours)) {
if ($key eq "colorRV") {
next;
}
if (!defined($value)) {
if ($key eq "foreground") {
$colours{$key} = "rgb:0000/0000/0000";
$reverseColours{ "reverse" . $key } = "rgb:ffff/ffff/ffff";
} elsif ($key eq "background") {
$colours{$key} = "rgb:ffff/ffff/ffff";
$reverseColours{ "reverse" . $key } = "rgb:0000/0000/0000";
} elsif ($key eq "colorBD") {
$colours{$key} = "rgb:0000/0000/0000";
$reverseColours{ "reverse" . $key } = "rgb:ffff/ffff/ffff";
} elsif ($key eq "colorIT") {
$colours{$key} = "rgb:0000/0000/0000";
$reverseColours{ "reverse" . $key } = "rgb:ffff/ffff/ffff";
} elsif ($key eq "colorUL") {
$colours{$key} = "rgb:0000/0000/0000";
$reverseColours{ "reverse" . $key } = "rgb:ffff/ffff/ffff";
} else {
delete $colours{$key};
}
} elsif ($value =~ m/^(\d{1,2})/i) { # shorthand urxvt
if ((my $colour = getRGBColour($self, resolveShorthand($1))) != -1) {
$colours{$key} = $value;
$reverseColours{ "reverse" . $key } = invertHexRGB($colour);
} else {
delete $colours{$key};
}
} elsif ($value =~ m/(\[\d{1,3}\])((\w|\s)*)/i) { # named colour with alpha
if ((my $colour = getRGBColour($self, $2)) != -1) {
$colours{$key} = $value;
$reverseColours{ "reverse" . $key } = invertHexRGB($colour);
} else {
delete $colours{$key};
}
} elsif ($value =~ m/(^[#])([[:alnum:]]{6})/i) { # web colour
if ((my $colour = resolveWebColour($value)) != -1) {
$colours{$key} = $value;
$reverseColours{ "reverse" . $key } = invertHexRGB($colour);
} else {
delete $colours{$key};
}
} elsif ($value =~ m/(^[^(rgb)|^#])((\w|\s)*)/i) { # named colour
if ((my $colour = getRGBColour($self, $value)) != -1) {
$colours{$key} = $value;
$reverseColours{ "reverse" . $key } = invertHexRGB($colour);
} else {
delete $colours{$key};
}
} elsif ($value =~
m/rgb(a?):(\w{1,4})\/(\w{1,4})\/(\w{1,4})\/?(\w{1,4})?/i) {
$colours{$key} = $value;
$reverseColours{ "reverse" . $key } = invertHexRGB($value);
}
}
if (defined($colours{"colorRV"})) {
$reverseColours{"reversebackground"} = $colours{"colorRV"};
delete $colours{"colorRV"};
}
return (%colours, %reverseColours);
}
sub resolveWebColour {
$_[0] =~ m/(^[#])(\w{2})(\w{2})(\w{2})/i;
return "rgb:" . $2 . "/" . $3 . "/" . $4;
}
sub resolveShorthand {
my (%shorthand) = (
0 => "black"
, 1 => "red3"
, 2 => "green3"
, 3 => "yellow3"
, 4 => "blue3"
, 5 => "magenta3"
, 6 => "cyan3"
, 7 => "antiquewhite"
, 8 => "grey25"
, 9 => "red"
, 10 => "green"
, 11 => "yellow"
, 12 => "blue"
, 13 => "magenta"
, 14 => "cyan"
, 15 => "white" );
if ($_[0] >= 0 && $_[0] <= 15) {
return $shorthand{$_[0]};
} else {
return -1;
}
}
sub getRGBColour {
my ($self, $colourname) = @_;
my ($term) = ($self->{term});
my $file = $term->x_resource("RGBColourFile");
if (!defined($file)) {
if ( ! open(RGB, "</usr/share/X11/rgb.txt")
|| ! open(RGB, "</usr/local/share/X11/rgb.txt")) {
return -1;
}
} elsif (! open(RGB, "<" . $file)) {
return -1;
}
while (<RGB>) {
my ($line) = $_;
chomp($line);
if ($line =~ m/(\d{1,3})\s*(\d{1,3})\s*(\d{1,3})\s*($colourname)/i) {
close RGB;
return sprintf("rgb:%x/%x/%x", $1, $2, $3);
}
}
close RGB;
return -1;
}
rvid-on-brightnesschanged.sig
Description: PGP signature
_______________________________________________ rxvt-unicode mailing list [email protected] http://lists.schmorp.de/cgi-bin/mailman/listinfo/rxvt-unicode
