Hi,
ich habe mit ein Perl Script gebastelt, das mein Bild auf dem X61 Tablet rotiert, wenn ich den Laptop kippe. Das klappt an sich gut - nur gibts ein Problem: Wenn ich glxgears laufen lasse und das Script, stock glxgears einmal pro Sekunde. Die Hauptschleife des Scripts ist ebenfalls mit einem sleep von 1 Sekunde versehen.
glxgears ohne das Script:
glxgears mit Script:
Mal sieht also ganz klar, dass das Script glxgears ausbremst. Zuerst habe ich das im PDF Reader evince bemerkt, wo die paint performance eingebrochen ist. Jetz twährend ich hier schreibe merke ich außerdem, dass jede Sekunde der Text-Cursor kurz freezt, also der Text nicht immer dann erscheint, wenn ich ihn tippe.
Ich nehm jetzt einfach mal an, dass es mit dem Script zu tun hat, denn wenn das Script nicht läuft, geht's ja. Vllt könnte ihr mir helfen das Problem in den Griff zu kriegen. Das Script ist gut kommentiert, sollte also verständlich sein was da passiert. Bei Fragen einfach fragen
cu
serow
Hier das Script:
ich habe mit ein Perl Script gebastelt, das mein Bild auf dem X61 Tablet rotiert, wenn ich den Laptop kippe. Das klappt an sich gut - nur gibts ein Problem: Wenn ich glxgears laufen lasse und das Script, stock glxgears einmal pro Sekunde. Die Hauptschleife des Scripts ist ebenfalls mit einem sleep von 1 Sekunde versehen.
glxgears ohne das Script:
Code:
mathias@apprentice:~$ glxgears
5405 frames in 5.0 seconds = 1080.934 FPS
5637 frames in 5.0 seconds = 1127.357 FPS
5698 frames in 5.0 seconds = 1139.442 FPS
5688 frames in 5.0 seconds = 1137.588 FPS
mathias@apprentice:~$
glxgears mit Script:
Code:
mathias@apprentice:~$ glxgears
3982 frames in 5.0 seconds = 796.266 FPS
4155 frames in 5.0 seconds = 830.858 FPS
4280 frames in 5.0 seconds = 855.567 FPS
mathias@apprentice:~$
Mal sieht also ganz klar, dass das Script glxgears ausbremst. Zuerst habe ich das im PDF Reader evince bemerkt, wo die paint performance eingebrochen ist. Jetz twährend ich hier schreibe merke ich außerdem, dass jede Sekunde der Text-Cursor kurz freezt, also der Text nicht immer dann erscheint, wenn ich ihn tippe.
Ich nehm jetzt einfach mal an, dass es mit dem Script zu tun hat, denn wenn das Script nicht läuft, geht's ja. Vllt könnte ihr mir helfen das Problem in den Griff zu kriegen. Das Script ist gut kommentiert, sollte also verständlich sein was da passiert. Bei Fragen einfach fragen

cu
serow
Hier das Script:
Code:
#!/usr/bin/perl
use strict;
use warnings FATAL => 'all';
#
# configuration
#
my $CALIBRATION_FILE = "/sys/devices/platform/hdaps/calibrate";
my $POSITION_FILE = "/sys/devices/platform/hdaps/position";
my $TOLERANCE = 50;
my $MODE_FILE = "/etc/tablet_mode";
my $LAPTOP_MODE = "x61";
my $TABLET_MODE = "tablet";
my $XRANDR_OUTPUT = "LVDS";
my @buttons = qw(71 6d 6f 6e);
my %keycodes = (
"normal" => "103 106 108 105",
"right" => "105 103 106 108",
"inverted" => "108 105 103 106",
"left" => "106 108 105 103"
);
# runtime variables
my @calibration = &getPositionValues($CALIBRATION_FILE);
#---------------------------
# workaround
# currently the hdaps sensors calibrate wrong sometimes
# depending on how the values are as the module initializes
# to my knowledge there's no way to recalibrate the sensore
# so I take the first position pair I grab as the calibration
@calibration = &getPositionValues($POSITION_FILE);
#---------------------------
print "calibration: @calibration\n";
# main loop
while (1) {
my $start = time;
# check in which mode we are
# if we are in laptop mode, we check if are already in
# normal rotation mode. if not we rotate to normal.
my $mode = &getTiltMode;
if($mode eq $LAPTOP_MODE) {
if(&getRotation ne "normal") {
&rotateNormal;
}
my $stop = time;
print "main loop passed in ", ($stop-$start), " ms\n";
sleep(1);
next;
}
# we reach this line only if we are in tablet mode
# now we have to get the position and decide how to
# rotate.
# get current position
my @position = &getPositionValues($POSITION_FILE);
print "position: @position\n";
# normalize position
@position = ( $position[0]-$calibration[0], $position[1]-$calibration[1] );
# get axis states
my $xAxis = &getAxisStatus($position[0]);
my $yAxis = &getAxisStatus($position[1]);
# decide what to do
if($xAxis == -1 && $yAxis == 0) {
&rotateRight;
} elsif($xAxis == 1 && $yAxis == 0) {
&rotateLeft;
} elsif($yAxis == -1 && $xAxis == 0) {
&rotateNormal;
} elsif($yAxis == 1 && $xAxis == 0) {
&rotateInverted;
}
my $stop = time;
print "main loop passed in ", ($stop-$start), " ms\n";
sleep(1);
}
#
# The following 4 subroutines take care of actually
# rotating the screen and the arrow keys on the display.
# The methods check the current rotation orientation and
# only rotate if necessary.
#
sub rotateNormal {
if (&getRotation ne "normal") {
system("xrandr -o normal");
system("xsetwacom set stylus Rotate 0");
&mapKeys("normal");
}
}
sub rotateInverted {
if (&getRotation ne "inverted") {
system("xrandr -o inverted");
system("xsetwacom set stylus rotate 3");
&mapKeys("inverted");
}
}
sub rotateLeft {
if (&getRotation ne "left") {
system("xrandr -o left");
system("xsetwacom set stylus rotate 2");
&mapKeys("left");
}
}
sub rotateRight {
if (&getRotation ne "right") {
system("xrandr -o right");
system("xsetwacom set stylus rotate 1");
&mapKeys("right");
}
}
#
# Do the arrow key mapping. This subrouting expects
# "normal", "inverted", "left" or "right as an argument
#
sub mapKeys {
my $values = $keycodes{$_[0]};
my @codes = split(/ /, $values);
for(my $i=0; $i < scalar(@buttons); $i++) {
system("setkeycodes $buttons[$i] $codes[$i]\n");
}
}
#
# Returns
# -1 if the movement has exceeded the tolerance
# 0 if the movement is within the tolerance
# 1 if the movement has exceeded the tolerance in the other
# direction
#
sub getAxisStatus {
my $status = 0;
if($_[0] < $TOLERANCE*(-1)) {
$status = -1;
} elsif($_[0] > $TOLERANCE) {
$status = 1;
}
return $status;
}
#
# Reads the file given assuming the format is
# for example (500,500). Then it extracts the
# values and returns them in an array
#
sub getPositionValues {
open(HANDLE, $_[0]);
my $content = join('', <HANDLE>);
my @result = ();
if( $content =~ /([0-9]+),([0-9]+)/ ) {
push(@result, $1);
push(@result, $2);
return @result;
}
return undef;
}
#
# Reads the $MODE_FILE file and
# returns its content.
#
sub getTiltMode {
open(HANDLE, $MODE_FILE);
my $mode = join('', <HANDLE>);
chomp($mode);
return $mode;
}
#
# Returns the current orientation of the
# screen as reported by xrandr -q
#
sub getRotation {
# read the output of xrandr -q
my @out = `xrandr -q`;
# filter lines for those that contain
# the xrandr output device we are looking fore
# at the beginning of the line
@out = grep(/^$XRANDR_OUTPUT/, @out);
# if there is "inverted", "left" or "right before
# the opening bracket and a blank before and after
# this is the current rotation status. So we return it.
if ($out[0] =~ / (inverted|left|right) \(/) {
return $1;
}
# it the regular expression before did not match
# we are in normal mode as normal mode is not
# displayed by xrandr -q
return "normal";
}