Device-SpaceNavigator
view release on metacpan or search on metacpan
lib/Device/SpaceNavigator.pm view on Meta::CPAN
package Device::SpaceNavigator;
use strict;
use Carp;
use IO::Select;
our $VERSION = '0.02';
our $AUTOLOAD;
sub new {
my ($class, $device) = @_;
my $self = {
device => "/dev/input/by-id/usb-3Dconnexion_SpaceNavigator-event-if00",
events => ['x', 'y', 'z', 'pitch', 'roll', 'yaw'],
buttons => ['left_button', 'right_button'],
connected => 0,
};
foreach (@{$self->{'events'}}, @{$self->{'buttons'}}) {
$self->{$_} = 0;
}
bless $self, $class;
}
sub open {
my ($self, $device) = @_;
if ($device) {
$self->{'device'} = $device;
}
open($self->{'_fh'}, $self->{'device'}) || croak("$!");
binmode $self->{'_fh'};
$self->{'_select'} = IO::Select->new($self->{'_fh'});
}
sub close {
my ($self) = @_;
if ($self->{'_fh'}) {
CORE::close $self->{'_fh'} || croak("$!");
}
}
sub update {
my ($self, $wait) = @_;
my $str;
if (!$self->{'_fh'}) {
$self->open();
}
$self->{'_select'}->can_read( defined($wait) ? $wait : 1 ) || return;
if(read($self->{'_fh'}, $str, 8) != 8) {
CORE::close $self->{'_fh'};
return 1;
}
my @s = unpack("C*", $str);
# Handle button
if ($s[0] == 1 && $s[1] == 0) {
if ($self->{'buttons'}->[$s[2]]) {
$self->{$self->{'buttons'}->[$s[2]]} = $s[4];
}
}
# Handle move
if ($s[0] == 2 && $s[1] == 0) {
my $value = unpack("s",chr($s[4]).chr($s[5]));
if ($self->{'events'}->[$s[2]]) {
$self->{$self->{'events'}->[$s[2]]} = $value;
}
}
return 1;
}
sub AUTOLOAD {
my $self = shift;
my $type = ref($self)
or croak "$self is not an object";
my $name = $AUTOLOAD;
$name =~ s/.*://; # strip fully-qualified portion
return if $AUTOLOAD =~ /::DESTROY$/;
unless (exists $self->{$name} ) {
croak "Can't access `$name' field in class $type";
}
return $self->{$name};
}
1;
__END__
=encoding utf-8
=head1 NAME
Device::SpaceNavigator - Read data from 3Dconnexion SpaceNavigator
( run in 2.917 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )