Tastendruck unter Linux global fangen

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
Benutzeravatar
Bebu
Beiträge: 562
Registriert: Mi Okt 21, 2009 6:19 pm
Wohnort: In der Nähe von Salzburg - Bin aber kein Österreicher!

Tastendruck unter Linux global fangen

Beitrag von Bebu » Do Jun 09, 2011 12:36 pm

Hallo Leute, ich suche nach einer Möglichkeit einen Hintergrundprozess zu schreiben, der global auf bestimmte F-Tasten reagiert, ohne dabei irgendwie den Fokus zu haben, oder die Eingabe in einem Terminal erfolgt. Ich habe schon ein bisschen gesucht, aber bisher eigentlich nur Funktionen der WindowsAPI gefunden, die mir unter Linux nichts nützen. Einziger Ansatz bisher, ist die Xlib, aber konkretes dazu habe ich auch nicht gefunden. Hat schon einmal jemand so etwas geschrieben und kann mir einen Tipp oder ein Tutorial dazu geben?

Gruß Bebu
Wer immer nach dem Unerreichbaren jagt, der wird irgendwann auf die Schnauze fallen!

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Tastendruck unter Linux global fangen

Beitrag von Xin » Do Jun 09, 2011 12:42 pm

Im Prinzip kannst Du das über die Tastaturbelegung regeln, such mal nach Belegung von Multimedia-Tasten, dafür gibt es ein kleines Tool.

Das hier könnte auch was für Dich sein:
http://keytouch.sourceforge.net/

Ich kann mir gut vorstellen, dass Du das für Console und X getrennt voneinander einrichten musst.
xbindkeys und lineak sind hier ggfs. Stichwörter.

Um wirklich global an die Taste ranzukommen, müsstest Du vermutlich recht nahe an den Kernel ran.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
Bebu
Beiträge: 562
Registriert: Mi Okt 21, 2009 6:19 pm
Wohnort: In der Nähe von Salzburg - Bin aber kein Österreicher!

Re: Tastendruck unter Linux global fangen

Beitrag von Bebu » Do Jun 09, 2011 10:21 pm

So, nach einigen Stunden Sucharbeit, verbunden mit Try and Error Wahrheitsfindung habe ich eine Lösung gefunden. Mein Lösung beachtet zwar keinerlei Tastenkomibinationen, aber für meine Zwecke ist sie wunderbar. Die Lösung ist tatsächlich die Xlib, das hat für mich den Vorteil, mich nicht mit Hardware Scanncodes herumzuschlagen, die bei jedem Hersteller anders sind. Das erledigt der XServer für mich. Langer Rede kurzer Sinn, hier der Code:

Code: Alles auswählen

#include <iostream>
#include <ctime>
#include <unistd.h> /* for usleep() */
#include <X11/Xlib.h>
#include <X11/Xutil.h>

int main(int argc, char *argv[])
{
  Display *dpy = XOpenDisplay( 0 ); //connect to xserver
  Window root = DefaultRootWindow( dpy ); //we working on the X-root window
  XEvent event;

  Window   grab_window     =  root;
  Bool          owner_events    = False;
  int             pointer_mode     = GrabModeAsync;
  int             keyboard_mode = GrabModeAsync;

  //We only interested in KeyPress Events
  XSelectInput(dpy, root, KeyPressMask);
  //Grap all keyboard events
  XGrabKeyboard( dpy,  grab_window, owner_events, pointer_mode, keyboard_mode, CurrentTime );

  while (1)
  {
    //Step events
    XNextEvent(dpy, &event);
    //if KeyPress event found check for right keys
    if( event.type == KeyPress )
    {
     //keys are defined in keysymdef.h from the X11 development files
      if( event.xkey.keycode == XKeysymToKeycode( dpy, XK_F1) ) std::cout << "F1 pressed\n";
      if( event.xkey.keycode == XKeysymToKeycode( dpy, XK_F10) ) std::cout << "F10 pressed\n";
      if( event.xkey.keycode == XKeysymToKeycode( dpy, XK_Q) ) break;
     }
     usleep(100); //cool down the prozessor a little bit
    }
    XUngrabKeyboard( dpy, CurrentTime );
    XCloseDisplay( dpy );
  return 0;
}
Wer auch damit rumspielen will, braucht die Entwicklerdateien von X11( für Debian und Ubuntu das Paket "libx11-dev") und muss die Library "X11" dazulinken.
Große Teile des Codes sind aus verschiedenen Tutorials die ich so gefunden habe zusammengebastelt. Ich weiß copy and paste ist böse, aber was solls :mrgreen:

Gruß Bebu
Wer immer nach dem Unerreichbaren jagt, der wird irgendwann auf die Schnauze fallen!

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Tastendruck unter Linux global fangen

Beitrag von Xin » Do Jun 09, 2011 10:38 pm

Aber das funktioniert dann nicht auf der Konsole?

Ich habe gerade nochmal nachgeguckt und sehe gerade, dass das auch nicht die Vorgabe war ^^
Mit while(1) habe ich allerdings immer etwas Probleme... gibt es da kein passendes Event, in das man sich reinhängen kann?
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
Bebu
Beiträge: 562
Registriert: Mi Okt 21, 2009 6:19 pm
Wohnort: In der Nähe von Salzburg - Bin aber kein Österreicher!

Re: Tastendruck unter Linux global fangen

Beitrag von Bebu » Fr Jun 10, 2011 7:59 am

Doch es funktioniert auf der Konsole, allerdings fängt das Programm genau wie gewollt die passenden Tastendrücke und reagiert darauf, egal welches Fenster den Fokus hat, weil ich sofort beim Hauptfenster des X-Servers lausche und damit von den Unterfenstern unabhängig bin.

Ich glaube das passende Event heißt Xpending oder so ähnlich, muss nochmal etwas suchen, wenn ich Zeit habe. Mal sehen, vielleicht baue ich das ganze irgendwann zu einem X-Server Keylogger um, wenn ich mit dem eigentlichen Verwendungszweck fertig bin. Aber nicht verraten :P
Wer immer nach dem Unerreichbaren jagt, der wird irgendwann auf die Schnauze fallen!

Benutzeravatar
Dirty Oerti
Beiträge: 2229
Registriert: Di Jul 08, 2008 5:05 pm
Wohnort: Thurndorf / Würzburg

Re: Tastendruck unter Linux global fangen

Beitrag von Dirty Oerti » Fr Jun 10, 2011 10:27 pm

Dürfte aber nur funktionieren, wenn du es ausführst und eine gültige Xauthority hast.
Ansonsten lässt sich ein (richtig konfigurierter) XServer nicht einfach so von einem Backgroundprozess beeinflussen, zumindest sollte das so sein.
Sprich wenn du dein Programm als ein anderer Benutzer ausführst, dann wird das nicht funktionieren.

Mit Konsole meint Xin sicherlich die "echte" Konsole, und nicht das gnome-terminal o.ä.
Sprich das, was du siehst, wenn du ALT + F1 drückst.
Bei Fragen einfach an daniel[ät]proggen[Punkt]org
Ich helfe gerne! :)
----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.

Benutzeravatar
Bebu
Beiträge: 562
Registriert: Mi Okt 21, 2009 6:19 pm
Wohnort: In der Nähe von Salzburg - Bin aber kein Österreicher!

Re: Tastendruck unter Linux global fangen

Beitrag von Bebu » Fr Jun 10, 2011 11:18 pm

Ich bin dabei sowieso auf ein anderes Problem gestoßen. Mit dem aktuellen Code sind teile von Gnome nicht mehr ansprechbar, solange der Prozess läuft. Ich belege vermutlich Resourcen, oder fange Eingaben der Tastatur ab, die auch andere Fenster erwarten. Ich glaube, ich muss mir dazu einen anderen Lösungsansatz überlegen :(

Läuft den auf der "echten" Konsole ein X-Server? Wenn nein, dann ist die Antwort ziemlich klar
Wer immer nach dem Unerreichbaren jagt, der wird irgendwann auf die Schnauze fallen!

Antworten