Linux auf einem Convertible

4 January 2009

Ich brauchte einen neuen Laptop in die engere auswahl vielen einige Convertibles. Die wahl viel aus kostengründen auf das MultiBOOK Tablet TN120R, welces beugliech mit dem NEXOC Osiris S621 ist. Beide, und auch diverse andere Tablets im unteren Preisbereich (seinen sie nun von Schenker, Notebookguru oder wie sie alle heißen), basieren auf dem Clevo TN120R. Der vorteil dieses Notebooks war für mich die tatsache, das es klein leich und ohne betriebssystem ausgeliefert wird. die Akkulaufzeit wird mit 2 h bzw für den Hochkapazitätsakku mit 4 h angegeben. Meine wahl viel auf die Variante mit Core-2-Duo T8300 2,4GHz Prozessor dazu kamen 4 Gb Speicher und das Bluetooth-Modul Fesplatte wurde leider nur die Kleinste mit 120 Gig statt der gewünschte 320 Gb mitgeliefert. Doch deswegen ging das Notebook nicht zurück sondern ließ mir den differenzbetrag erstatten. Bei bedarf wid die Platte dann getauscht, was angesichts de Preisverfalls bei Platten nicht unbedingt die schlechtere lösung ist. Zur Akkulaufzeit kann ich nur sagen subjektiv hält bei normaler nutzung länger durch. wer bei gelegenheit mal die zwit messen, die er beim DVD-Abspielen und angeschaltetem Wlan und Bluetooth durchhält.

conv01.jpg

Picture 1 of 7


Beim Betriebssystem viel die Wahl auf Fedora 10. Die installation verlief Problemlos. Webcam, Bluetooth, Wlan, Touchpad, DVD und Cardreader alles lief, nachdem man die Tastenkombinationen zum anschalten gefunden hatte problemlos (Fn+F10 Webcam; Fn+F11 Wlan; Fn+F12 Bluetooth Webcam und Bluetooth sind nicht beschriftet). Nur Modem, Touchscreen und der Fingerprintreader wollten noch nicht. Dazu später mehr. Im großen ganzen bin ich aber zufrieden mit dem Notebook. Die Displayhalterung macht einen soliden eindruch so wie die Verarbeitung für den Preis auch OK ist. Camera, Cardreader (7in1), DVD-Brenner, Touchscreen (1280×800 matt), 2 M-pixel Webcam, 4 Gig Speicher (PC800), Fingerprintreader, Wlan (300Mbit), Lan (1000/100/10), Bluetooth, 3x USB, 1x Firewire, 1x VGA (Intel GM 965), Sound und Modem für unter 1000 Euro (incl. zusatzakku) und unter 2 Kg ist durchaus ok. Eine Schwäche ist das Keybord, hier sind die Tasten ein wenig schief, was den sonst guten Gesamteindruck schmälert.

Touchpanal

Doch ein Convertible ohne Touchscreen macht keinen spaß. Hier began zunächst eine kleine Odyssee der Treiber suche.
ein lsusb -v förderte folgendes zu tage:

iManufacturer 1 ET&T Technology
iProduct 2 TC4UM
bInterfaceClass 3 Human Interface Device

mit diesen informationen und einigen suchen findet man auch einen Treiber, der aber nur bei einem i386 Linux läuft und die Displaycallibrierung verursacht einen Schpeicherzugriffsfehler. Wacom Diamondtouch und wie sie alle heißen helfen auch nicht weiter. Schlieslich brachte mich mein Bruder mit dem Hinweis auf Sam Engströms Seite auf eine Lösung. Wir lesen das device direkt mit Perl aus und und Steuern mittel X11::GUITest. Jetzt begann die such nach dem Device. Das ist einfacher als es klingt ein:

cat /dev/input/event0

ist der anfang jetzt drücht man auch dem Touchscreen rum und wartet ab ob etwas passiert.
ich bin /dev/input durchgegangen und dann /dev/event* und /dev/hid* bei /dev/hiddev0 und /dev/hidraw0 bin ich fündig gweorden. der 1. Schritt war getan. Jetzt kam das 1. Kleine Perl-Script zum Einsatz um die Ausgabe des gerätes zu analysieren:

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/perl -w
use strict;
use warnings;
$|=1
SetEventSendDelay(0);
sleep 1;
open FILEH,"/dev/hiddev0";
while(read(FILEH,my $data,1)) {
	my $o=ord($data);
	    print "$o\t";
  }
close FILEH;

dabei kam raus das die informationen in logischen Blöcken von je 8 Hexwerten zusammengefasst wurden. also ändern der schleife in:

8
9
10
11
12
13
14
15
16
17
18
19
while(read(FILEH,my $data,1)) {
	my $o=ord($data);
	if ($n<=6) {
	    print "$o\t";
	    $n = $n + 1;
	}
	else {
	    print "$o\n";
	    $n = 0;
	}
    }
close FILEH;

Damit war die größte Hürde genommen, das Device war gefunden, die logik konnte nun analysiert werden es kam eine kolonne von 8 Zahlen:
die 0. gibt an was fuer eine information folgt (48 die X Achse; 49 die Y Achse; 66 Stift status; 69 Unbekannt (in der Regel ohne Informationen))
die 1. Zahl ist immer 0
die 2. Zahl ist 1 wenn information der Achsen folgt sonst 13
die 3. Zahl ist immer 0
die 4. Zahl ist die “Nachkommastelle” (0-255) bei Achseninformationen oder 1 bei Stiftkontakt 0 ohne Stiftkontakt
die 5. Zahl “Vorkommastelle” bei Achseninformationen
die 6. Zahl ist immer Null
die 7. Zahl ist immer Null

Als Nächstes machte ich mich auf die Suche nach den zwei Displayknöpfen und wurde unter /dev/event5 fündig zusammen mit den Tastaturinformationen. hier kamen 48 Hexwerte in logischen Blöcken und nach einer weile konnte ich das muster entschlüsseln.

Jetzt ging es mir darum die Anzeige per Knopfdruck zu rotieren. Hierzu verwende ich das Konsolenprogramm “xrandr”
die Statusinformationen (rotiert (1), nicht-rotiert(0)) des Displays werden in /etc/touch.conf geschrieben. Die 2. Taste verwende ich für linken (0,5s), mittleren(1s) und rechten (>1s) Mausclick. Die Mausclicks erzeuge ich mit hilfe des Perl Moduls X11::GUITest.

dazu ein

yum install perl*Digest zlib-devel libX*-devel  perl*CPAN* xorg-sever* perl*YAML* per*X11*

ist ne ziemlich Keule liefert aber alle benötigten Packete um X11::GUITest zu installieren:

perl -MCPAN -e 'install X11::GUITest'

Conf-Datei anlegen für die Späteren Perlscripte

touch /etc/touch.conf
chmod 660 /etc/touch.conf
cchgrp hid /etc/touch.conf

in rc.local folgende Einträge setzten:

chgrp hid /dev/event5
chgrp hid /dev/hiddev0
chmod 660 /dev/event5
chmod 660 /dev/hiddev0

jetzt in /home/user/bin noch folgene Sripte:
run-touch.sh

#!/bin/bash
/home/pinguin/bin/touch.pl &
/home/pinguin/bin/button.pl &

button.pl:

#!/usr/bin/perl -w
#"Touchpanal-button-driver" for Clevo TN120R
#and similar convertibles (Multibook 621, NEXOC Osiris 621 aso.)
#This script is based on an script from  http://samengstrom.com/p1510
use X11::GUITest ("SetEventSendDelay","MoveMouseAbs","PressMouseButton","ClickMouseButton","ReleaseMouseButton","IsMouseButtonPressed",":CONST");
use Time::HiRes;
 
use strict;
use warnings;
 
$|=1;
 
#Variables
my $rotate=0; 	# rotationinformation
my $B1=0;	# Button1 status
my $B2=0;	# Button2 Status
my @Array;	# Array for Buttoninformation
my $timerstart=0;# Timer for Buttons
my $timerend=0;# Timer for Buttons
my $timervalue=0;# Timer for Buttons
 
#Subs
#LeftKlick
sub Leftclick{
	print "leftclick\n";
	ClickMouseButton(M_LEFT);
}
 
# Rightclick
sub Rightclick{
	print "rightclick\n";
	ClickMouseButton(M_RIGHT);
}
 
# Middleclick
sub Middleclick{
	print "middleclick\n";
	ClickMouseButton(M_MIDDLE);
}
 
sub Process {
	    if ($Array[16]==4 && $Array[17]==0 && $Array[18]==4 && $Array[20]==129 && $B1==0) {
		$B1=1;
		#print "Button1 pressed\n";
		$timerstart=Time::HiRes::time;
		}
	    elsif ($Array[16]==4 && $Array[17]==0 && $Array[18]==4 && $Array[20]==129 && $B1==1) {
		$B1=0;
		#print "Button1 released\n";
		$timerend=Time::HiRes::time;
		$timervalue=$timerend - $timerstart;
		if ($timervalue < 0.5){
			Leftclick;
			}
		elsif ($timervalue < 1){
			Middleclick;
			}
		else {
			Rightclick;
			}
		}
	    elsif ($Array[16]==4 && $Array[17]==0 && $Array[18]==4 && $Array[20]==147 && $B2==0) {
		$B2=1
		#print "Button2 (Rotate monitor) pressed \n";
		}
	   elsif ($Array[16]==4 && $Array[17]==0 && $Array[18]==4 && $Array[20]==147 && $B2==1) {
		$B2=0;
		if ($rotate==0){
			print "Screen Left\n";
			$rotate=1;
			system("xrandr -o left");
			open CONF, ">/etc/touch.conf" or die("File error /etc/touch.conf");
			print CONF "1\n";
			close CONF;
			}
					elsif ($rotate==1){
			print "Sreen Normal\n";
			$rotate=0;
			system("xrandr -o normal");
			open CONF, ">/etc/touch.conf" or die("File error /etc/touch.conf");
			print CONF "0\n";
			close CONF;
			}
		#print "Button2 (Rotate monitor) released \n";
		}
	    }
######################## main
SetEventSendDelay(0);
 
sleep 1;
 
open FILEH,"/dev/event5";
 
while(read(FILEH,my $data,1)) {
	my $o=ord($data);
	push @Array,$o;
	if (@Array==48) {
		#print "$o\n";
		Process;
		@Array= ();
		}
}
close FILEH;

touch.pl

#!/usr/bin/perl -w
#"Touchpanal-driver" for Clevo TN120R
#and similar convertibles (Multibook 621, NEXOC Osiris 621 aso.)
#This script is based on an script from  http://samengstrom.com/p1510
#Reading directly from /dev/hiddev you get blocks of each 8 Hex-values
#The 0. Value gives information about the following Data
#		48  X axis
#		49  Y axis
#		66 Pen status
#		69 unknown (usualy just 0 Values)
# 1. Value is 0
# 2. Value ist 1 if axis information follows else 13
# 3. Value is 0
# 4. Value "post decimal position" of Axis ro 1 on pencontact or 0 if pen ist of panel
# 5. Value of Axis
# 6. Value is 0
# 7. Value is 0
use X11::GUITest ("SetEventSendDelay","MoveMouseAbs","PressMouseButton","ClickMouseButton","ReleaseMouseButton","IsMouseButtonPressed",":CONST");
use Time::HiRes;
 
use strict;
use warnings;
 
$|=1;
 
#Constants
use constant SCREEN=>(1280,800);	# Screenresolution
use constant TOUCH=>(1757,1476);	# maxiumin values for Touchpanal
#Variables
my $X=0; 	#X
my $Y=0;	#Y
my @Array;	#Array for Touchscreen values
my $X1=0;	# 1. X-value Touchpanal
my $X2=0;	# 2. X-value Touchpanal
my $Y1=0;	# 1. Y-value Touchpanal
my $Y2=0;	# 2. Y-value Touchpanal
my $Stift=0;	# Penstatus
my $Xx=((SCREEN)[0]/(TOUCH)[0]); # factor for X-axis
my $Yy=((SCREEN)[1]/(TOUCH)[1]); # factor for Y-axis
my $Xoffset=60;	# X axis offset
my $Yoffset=100;# Y axis offset
my $prevx=8;	# old x value
my $prevy=0;	# old y value
my $rot=0;	# Panelrotation
my $Stiftalt=2;	# Stift informationen fuer mouseevent
my $timervalue=0;# Value dor mouseclick desition
my $timerstart=0;# Startvalue for mouseclick calculation
my $timerend=0;	# Endvalue for mouseclick calulation
my $pressed=0;	# Mousebutton pressed
#Read from device an conf file
sub Read{
	open CONF, "</etc/touch.conf" or die("File error /etc/touch.conf");
	$rot = readline(CONF);
	close CONF;
	if ($Array[0]==48) {
		$X2=$Array[4];
		$X1=$Array[5];
	}
	elsif ($Array[0]==49) {
		$Y2=$Array[4];
		$Y1=$Array[5];
	}
	elsif ($Array[0]==66) {
		$Stift=$Array[4];
	}
}
#move mousepointer
sub Movemouse(@){
	if (($X ne $prevx)||($Y ne $prevy)) {
		$prevx=$X;
		$prevy=$Y;
		if ($rot==0){
			MoveMouseAbs($X,$Y);
			}
		elsif ($rot==1){
			my $Xrot=800-$Y;
			my $Yrot=$X;
			MoveMouseAbs($Xrot,$Yrot);
			}
	}
}
 
#press left button
sub Leftpress {
	print "leftpress\n";
	PressMouseButton(M_LEFT);
}
 
#release left mousebutton
sub Leftrelease{
	print "leftrelease\n";
	ReleaseMouseButton(M_LEFT);
}
 
#eftclick
sub Leftclick{
	print "leftclick\n";
	ClickMouseButton(M_LEFT);
}
 
#Mouseclick selection
sub Mousebutton{
	if ($Stift==1 &amp;&amp; $Stiftalt==0 ){
		$timerend=Time::HiRes::time;
		$timervalue=$timerend - $timerstart;
		if ($timervalue &lt; 0.8){
		Leftpress;
		$pressed=1;
		}
	}
	elsif ($Stift==0 &amp;&amp; $Stiftalt==1 &amp;&amp; $pressed==1){
	Leftrelease;
	$pressed=0;
	}
	elsif ($Stift==0 &amp;&amp; $Stiftalt==1){
	#print "Stift abgehoben\n";
	$timerstart=Time::HiRes::time;
	}
	$Stiftalt=$Stift;
}
 
# Debugging
#sub Print{
#	print "X-Achse \t  $X \n";
#	print "Y-Achse \t  $Y \n";
#	print "Stift  \t $Stift \n";
#	print "$rot\n";
#}
 
#caller
sub Process(@){
	Read;
	Calc;
	Mousebutton;
	Movemouse;
#	Print
}
######################## main
SetEventSendDelay(0);
 
sleep 1;
 
open FILEH,"/dev/hiddev0";
 
while(read(FILEH,my $data,1)) {
	my $o=ord($data);
	push @Array,$o;
	if (@Array==8) {
		#print "$o\n";
		Process;
		@Array= ();
 
close FILEH;