#!/usr/bin/perl # SUMMARY: Tool to read/save orientation of IBM Lenovo x41 tablet using # HDAPS. Will also return a valid mode to pass to rotatetablet # (http://liken.otsoa.net/pub/x41t/rotatetablet) # By Saikat Guha (saikat AT cs.cornell.edu) and Liken Otsoa (liken AT otsoa.net) # # USAGE: orient reorient|read|getorient|getmode # reorient - Sets a reference point for when the laptop is flat # read - Print orientation saved by 'reorient' # getorient - Gets the current hdaps orientation # getmode - Return mode that should be passed to rotatetablet # # AUTHOR: Dave Clawson (david.scott.clawson AT gmail) use strict ; die "Couldn't read hdaps data $!\n" unless ( -f "/sys/devices/platform/hdaps/position" ) ; if ( $ARGV[0] =~ /reorient/i ) { my $username = getlogin() ; my $file = "/tmp/hdaps_orientation" ; open(REORIENT, ">$file") || die "Couldn't create $file: $!\n" ; my ( $x, $y ) = get_hdaps_position() ; print REORIENT "$x $y" ; close REORIENT ; exit 0 ; } elsif ( $ARGV[0] =~ /read/i ) { my ( $x, $y ) = get_saved_orientation() ; print "$x $y\n" ; } elsif ( $ARGV[0] =~ /getorient/i ) { my ( $x, $y ) = get_relative_orientation() ; print "$x $y\n" ; } elsif ( $ARGV[0] =~ /getmode/i ) { my ( $x, $y ) = get_relative_orientation() ; my $mode = get_appropriate_rotate_mode( $x, $y ) ; print $mode ; exit $mode ; } else { die "Usage: $0 reorient|read|getorient|getmode\n" ; } sub get_appropriate_rotate_mode { my ( $x, $y ) = @_ ; unless ( defined $x && defined $y ) { ( $x, $y ) = get_relative_orientation() ; } # These values can be adjusted to meet the user's desired # sensitivity. I think that they work pretty well, though, # because they're fairly forgiving and only decide that # the tablet is tilted if it's _really_ tilted. if ( ( $x > -50 ) && ( $x < 50 ) && ( $y > -200 ) && ( $y < -100 ) ) { return 0 ; } if ( ( $x > -200 ) && ( $x < -100 ) && ( $y > -50 ) && ( $y < 50 ) ) { return 1 ; } if ( ( $x > -50 ) && ( $x < 50 ) && ( $y > 100 ) && ( $y < 200 ) ) { return 2 ; } if ( ( $x > 100 ) && ( $x < 200 ) && ( $y > -50 ) && ( $y < 50 ) ) { return 3 ; } return -1 ; } sub get_relative_orientation { my ( $basex, $basey ) = @_ ; unless ( defined( $basex ) && defined( $basey ) ) { ( $basex, $basey ) = get_saved_orientation() ; } my ( $x, $y ) = get_hdaps_position() ; my $relx = $x - $basex ; my $rely = $y - $basey ; return ( $relx, $rely ) ; } sub get_saved_orientation { my $file = "/tmp/hdaps_orientation" ; open(ORIENTATION, "$file") || die "Couldn't open $file: $!\n" ; my $data = ; my ( $x, $y ) = split /\s+/, $data ; return ( $x, $y ) ; } sub get_hdaps_position { open( POSITION, "/sys/devices/platform/hdaps/position" ) || die "Couldn't read hdaps data $!\n" ; my $data = ; close(POSITION) ; chomp $data ; $data =~ s/[()]//g ; my ( $x, $y ) = ( split /,/, $data ) ; return ( $x, $y ) ; }