PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Optische Maus unter Linux abfragen?



nexusnoesis
12.01.2009, 23:51
Hi Leute,

da ich derzeit einen simplen Roboter baue (http://nexno.blogspot.com/) der zur steuerung ein linux netbook benutzt und den anspruch hat von jedem einfach nachbaubar zu sein hatte ich die idee eventuell eine optische aus als bewegungssensor einzusetzen.

hat jemand ne ahnung wie ich die unter linux abfragen kann ohne das sie einfluss auf den mauszeiger in X hat? bzw auch wenn eventuell garkein windowmanager lläuft?

wäre auch schon für ansätze dankbar!

nexusnoesis
13.01.2009, 12:36
OK, habs selbst hinbekommen:



#include <stdio.h>
#include <stdlib.h>
main(){
FILE *fmouse;
char b[3];
fmouse = fopen("/dev/input/mice","r");
int xd=0,yd=0; //x/y movement delta
int xo=0,yo=0; //x/y overflow (out of range -255 to +255)
int lb=0,mb=0,rb=0; //left/middle/right mousebutton
while(!mb){
fread(b,sizeof(char),3,fmouse);
lb=(b[0]&1)>0;
rb=(b[0]&2)>0;
mb=(b[0]&4)>0;
xo=(b[0]&64)>0;
yo=(b[0]&128)>0;
xd=b[1];
yd=b[2];
printf("lb=%d rm=%d mb=%d xo=%d yo=%d xd=%d yd=%d\n",lb,rb,mb,xo,yo,xd,yd);
}
fclose(fmouse);
}


PS: konnts nur mit sudo aufrufen, ansonsten gabs nen segfault.

Besserwessi
13.01.2009, 17:36
Das Problem mit dem Segfault kommt wahrscheinlich daher, das nicht getetstet wird ob das fopen auch erfolgreich war. Vermutlich könnte man das ändern wenn man die File Attribute von /dev/input/mice ändert. Ist aber natürlich auch nicht ganz ohne Nebenwirkungen.

.:Sebastian:.
13.01.2009, 19:46
Also ein kurzer Check mit strace ergab :


open("/dev/input/mice", O_RDONLY) = -1 EACCES (Permission denied)
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++



Genau wie schon vemutet.



if(!fmouse) {
printf("Can't open /dev/input/mice.\n");
return 0;
}

Sollte das abfangen.

Also entweder als root laufen lassen, was eigentlich ganz sinnvoll ist wenn du noch mehr Hardware IO über device-files hast und der Pc außer dir niemandem zugänglich is (Sicherheit) is das höchstens ein Eleganzproblem.

Oder halt als root chmod 666 /dev/input/mice .
Dann muss es nicht als root laufen. Hat imho keine Nebenwirkung, aber man verlagert das Ich-hab-keine-root-rechte-Problem nur an eine andere Stelle.
Aber z.b. ein Init-Skript könnte dir dann alle Rechte für alle Devicefiles die du so brauchst geben.

Übrigens ein nettes Projekt.

Sebastian

pyr0skull
13.01.2009, 22:32
/dev/input/mice sollte eigentlich von jedem User lesbar sein, wenn nicht, würde ich den User der das Device ausliest in die entsprechende Gruppe eintragen. Sowas als root auszuführen ist eigentlich sehr unschön.

Du könntest auch versuchen, das event-Device (evdev) auszulesen, da hast du dann bei Bedarf alle Signale aller Eingabegeräte drin - ist eventuell praktisch für Erweiterungen.

nexusnoesis
13.01.2009, 22:47
Danke für die Aufklärung :)
Hab deine Tips mal umgesetzt und noch alles etwas verschönert. Denke so kann mans vorsichtig mal ne Beta nennen *g*



#include <stdio.h>
#include <stdlib.h>
#include <time.h>

main(int argc, char *argv[]){
char *device = "/dev/input/mice";
FILE *fmouse;
char b[3];

if(argc>1){
if(strcmp(argv[1],"-?")==0 || argc > 2){
printf("Usage:\nmousereader [device]\t(default is /dev/input/mice)\n");
printf("Format:\nlb;mb;rb;xd;yd\t(left-,middle-,right mousebutton, x delta, y delta)\n");
return 0;
}else{
device = argv[1];
}
}

fmouse = fopen(device,"r");
if(fmouse==NULL){
printf("Could not open device '%s'. Check permissions!\n",device);
return 0;
}
int xd=0,yd=0; //x/y movement delta
int xo=0,yo=0; //x/y overflow (out of range -255 to +255)
int lb=0,mb=0,rb=0; //left/middle/right mousebutton
while(1){
fread(b,sizeof(char),3,fmouse);
lb=(b[0]&1)>0;
rb=(b[0]&2)>0;
mb=(b[0]&4)>0;
xo=(b[0]&64)>0;
yo=(b[0]&128)>0;
xd=b[1];
yd=b[2];
//printf("lb=%d rm=%d mb=%d xo=%d yo=%d xd=%d yd=%d\n",lb,rb,mb,xo,yo,xd,yd);
printf("%d;%d;%d;%d;%d\n",lb,mb,rb,xd,yd);
usleep(10);
}
//fclose(fmouse);
}


Isses schlimm das es ne endlosschleife is und man es manuell killen muss? muss/sollte man da noch explizit auf signale reagieren und das fclose dann doch noch irgendwie ausführen oder so? kenn mich da noch nich so jut aus :-/