#!/usr/bin/perl -w #this came from http://samengstrom.com/p1510 use X11::GUITest ("SetEventSendDelay","MoveMouseAbs","PressMouseButton","ClickMouseButton","ReleaseMouseButton","IsMouseButtonPressed",":CONST"); use Time::HiRes; use strict; use warnings; #NOTE: you may need to calibrate these (in the normal landscape mode) #use constant TOPLEFT=>(0.73,1.19); use constant TOPLEFT=>(0.70,1.06); #use constant BOTTOMRIGHT=>(31.51,31.25); use constant BOTTOMRIGHT=>(31.45,31.16); use constant SCREEN=>(1024,600); use constant DIGITIZER=>((BOTTOMRIGHT)[0]-(TOPLEFT)[0],(BOTTOMRIGHT)[1]-(TOPLEFT)[1]); my $prevx=8; my $prevy=0; my $rot=0; sub translate(@) { my $xmaj=$_[1]; my $xmin=$_[0]; my $ymaj=$_[3]; my $ymin=$_[2]; my $xdec=$xmaj+$xmin/128; my $ydec=$ymaj+$ymin/128; #NOTE: uncomment this to find out the values for TOPLEFT and BOTTOMRIGHT print $xdec."\t".$ydec."\n"; my $xn=($xdec-(TOPLEFT)[0])/(DIGITIZER)[0]; my $yn=($ydec-(TOPLEFT)[1])/(DIGITIZER)[1]; my $x=$xn; my $y=$yn; my $sw=(SCREEN)[0]; my $sh=(SCREEN)[1]; if ($rot==1) { $x=$yn; $y=1-$xn; $sw=(SCREEN)[1]; $sh=(SCREEN)[0]; } elsif ($rot==-1) { $x=1-$yn; $y=$xn; $sw=(SCREEN)[1]; $sh=(SCREEN)[0]; } $x=int($x*$sw); $y=int($y*$sh); if ($x<0) { $x=0; } if ($y<0) { $y=0; } if ($x>$sw) { $x=$sw; } if ($y>$sh) { $y=$sh; } return ($x,$y); } sub movemouse(@) { (my $x,my $y)=@_; if (($x ne $prevx)||($y ne $prevy)) { print "$x\t$y\n"; $prevx=$x; $prevy=$y; MoveMouseAbs($x,$y); } } sub press() { print "press\n"; #print PressMouseButton(M_LEFT); #print ClickMouseButton(M_LEFT); #sleep 1; #print ClickMouseButton(M_LEFT); } sub rightpress() { print "rightpress\n"; #print PressMouseButton(M_RIGHT); } sub release() { #print PressMouseButton(M_LEFT); if (IsMouseButtonPressed(M_LEFT)) { #print print "release left\n"; ReleaseMouseButton(M_LEFT); } elsif (IsMouseButtonPressed(M_RIGHT)) { #print print "release right\n"; ReleaseMouseButton(M_RIGHT); } } sub click() { print "click\n"; ClickMouseButton(M_LEFT); } sub rightclick() { print "rightclick\n"; ClickMouseButton(M_RIGHT); } sub simpleprocess(\@) { my @block=@{$_[0]}; my $action=$block[0]; movemouse(translate(@block[1..5])); if (!$action) { return; } if ($action==1) { press(); return; } if ($action==2) { release(); return; } } my $pressx=0; my $pressy=0; my $presstime=0; use constant DRAG=>(5,5); use constant RIGHTCLICKDURATION=>0.5;#seconds my $dragging=0; sub twobuttonprocess(\@) { my @block=@{$_[0]}; my $action=$block[0]; (my $x,my $y)=translate(@block[1..5]); my $now=Time::HiRes::time; if ($action==1) { #touchscreen press movemouse($x,$y); $pressx=$x; $pressy=$y; $presstime=Time::HiRes::time; $dragging=0; } elsif ($action==2) { #touchscreen release if ($dragging) { movemouse($x,$y); release(); #} elsif ($presstime && ($now>$presstime+RIGHTCLICKDURATION)) { # movemouse($pressx,$pressy); # rightclick(); } else { movemouse($pressx,$pressy); click(); } $dragging=0; $presstime=0; } elsif ($dragging) { print "d"; movemouse($x,$y); } elsif ($presstime && ($now>$presstime+RIGHTCLICKDURATION)) { movemouse($pressx,$pressy); rightpress(); $dragging=1; } if ($presstime && !$dragging) { if ( (abs($x-$pressx)>(DRAG)[0]) || (abs($y-$pressy)>(DRAG)[1])) { movemouse($pressx,$pressy); press(); movemouse($x,$y); $dragging=1; } } } sub process(\@) { my @a=@{$_[0]}; #simpleprocess(@a); twobuttonprocess(@a); } use constant SCREENTIMEOUT=>10*60;#seconds my $screenlast=time - SCREENTIMEOUT; sub displayon() { my $now=time; if ($now>$screenlast+SCREENTIMEOUT) { print "enabling display!\n"; system "xset dpms force on"; } $screenlast=$now; } ######################## main SetEventSendDelay(0); $|=1; my $doinit=1; foreach my $v (@ARGV) { if ($v eq "-ni") { $doinit=0; } elsif ($v eq "-cw") { $rot=1; } elsif ($v eq "-ccw") { $rot=-1; } else { print "Invalid option '$v'\n"; print "Usage:\n"; print "\t$0 [options]\n"; print "Options are:\n"; print "\t-ni\tSkip serial port initialization with wacdump\n"; print "\t-cw\tThe screen has been rotated clockwise\n"; print "\t-ccw\tThe screen has been rotated counterclockwise\n"; exit(0); } } if ($doinit) { print "Initializing... (please don't touch the screen)\n"; system "wacdump /dev/ttyS0 &> /dev/null"; sleep 1; } else { print "Skipping initialization...\n"; } print "Ready!\n"; open FILEH,"/dev/ttyS0"; my $last=0; my @block=(); my @pending=(); while(read(FILEH,my $data,1)) { #print $c." "; #$c++; #next; my $o=ord($data); if ($o>130) { @block=(); if ($o==136) { push @block,1; } elsif ($o==138) { push @block,2; } else { push @block,0; } #print "\n$o\t";# } else { push @block,$o; #print "$o\t"; if (@block==5) { process(@block); displayon(); } } $last=$o; } close FILEH;