ubuntuusers.de

Terminal für parallele Eingabe konfigurieren

Status: Ungelöst | Ubuntu-Version: Server 16.04 (Xenial Xerus)
Antworten |

eagle87

Anmeldungsdatum:
29. Dezember 2010

Beiträge: Zähle...

Hallo zusammen,

gibt es eine Möglichkeit das Terminal so zu konfigurieren, dass man gleichzeitig verschiedene Zeichen eingeben kann? Hier ein Beispiel:

1. Taste 'a' wird gedrückt und gehalten → es erscheint oft der Buchstabe 'a'
2. Taste 'b' wird gedrückt und gehalten → es erscheint oft der Buchstabe 'b', aber kein 'a' mehr obwohl die Taste immer noch gedrückt ist.

Was ich will ist, dass die Eingabe von beiden Tasten dauerhaft verarbeitet wird und nicht nur die der letzten gedrückten Taste.

Gruß Michael

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11261

Wohnort: München

Wofür brauchst du das genau? Wenn man sich die Ausgabe von evtest (aus dem gleichnamigen Paket) ansieht, ist es zumindest auf meinem Laptop so, dass es keine Tastenwiederholungsevents für KEY_A mehr gibt, sobald KEY_S gedrückt wird (value=1 Taste zum ersten Mal gedrückt, value=2 Wiederholgunsevent, value=0 Taste losgelassen):

Event: time 1487014751.312651, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e
Event: time 1487014751.312651, type 1 (EV_KEY), code 30 (KEY_A), value 1
Event: time 1487014751.312651, -------------- SYN_REPORT ------------
Event: time 1487014751.564164, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e
Event: time 1487014751.564164, type 1 (EV_KEY), code 30 (KEY_A), value 2
Event: time 1487014751.564164, -------------- SYN_REPORT ------------
Event: time 1487014751.597202, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e
Event: time 1487014751.597202, type 1 (EV_KEY), code 30 (KEY_A), value 2
Event: time 1487014751.597202, -------------- SYN_REPORT ------------
Event: time 1487014751.630307, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e
Event: time 1487014751.630307, type 1 (EV_KEY), code 30 (KEY_A), value 2
Event: time 1487014751.630307, -------------- SYN_REPORT ------------
Event: time 1487014751.663705, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e
Event: time 1487014751.663705, type 1 (EV_KEY), code 30 (KEY_A), value 2
Event: time 1487014751.663705, -------------- SYN_REPORT ------------
Event: time 1487014751.697858, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e
Event: time 1487014751.697858, type 1 (EV_KEY), code 30 (KEY_A), value 2
Event: time 1487014751.697858, -------------- SYN_REPORT ------------
Event: time 1487014751.731418, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e
Event: time 1487014751.731418, type 1 (EV_KEY), code 30 (KEY_A), value 2
Event: time 1487014751.731418, -------------- SYN_REPORT ------------
Event: time 1487014751.765995, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e
Event: time 1487014751.765995, type 1 (EV_KEY), code 30 (KEY_A), value 2
Event: time 1487014751.765995, -------------- SYN_REPORT ------------
Event: time 1487014751.800822, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e
Event: time 1487014751.800822, type 1 (EV_KEY), code 30 (KEY_A), value 2
Event: time 1487014751.800822, -------------- SYN_REPORT ------------
Event: time 1487014751.834175, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e
Event: time 1487014751.834175, type 1 (EV_KEY), code 30 (KEY_A), value 2
Event: time 1487014751.834175, -------------- SYN_REPORT ------------
Event: time 1487014751.869577, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e
Event: time 1487014751.869577, type 1 (EV_KEY), code 30 (KEY_A), value 2
Event: time 1487014751.869577, -------------- SYN_REPORT ------------
Event: time 1487014751.902456, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e
Event: time 1487014751.902456, type 1 (EV_KEY), code 30 (KEY_A), value 2
Event: time 1487014751.902456, -------------- SYN_REPORT ------------
Event: time 1487014751.935507, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e
Event: time 1487014751.935507, type 1 (EV_KEY), code 30 (KEY_A), value 2
Event: time 1487014751.935507, -------------- SYN_REPORT ------------
Event: time 1487014751.969262, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e
Event: time 1487014751.969262, type 1 (EV_KEY), code 30 (KEY_A), value 2
Event: time 1487014751.969262, -------------- SYN_REPORT ------------
Event: time 1487014752.002712, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e
Event: time 1487014752.002712, type 1 (EV_KEY), code 30 (KEY_A), value 2
Event: time 1487014752.002712, -------------- SYN_REPORT ------------
Event: time 1487014752.035976, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e
Event: time 1487014752.035976, type 1 (EV_KEY), code 30 (KEY_A), value 2
Event: time 1487014752.035976, -------------- SYN_REPORT ------------
Event: time 1487014752.068561, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e
Event: time 1487014752.068561, type 1 (EV_KEY), code 30 (KEY_A), value 2
Event: time 1487014752.068561, -------------- SYN_REPORT ------------
Event: time 1487014752.101001, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014752.101001, type 1 (EV_KEY), code 31 (KEY_S), value 1
Event: time 1487014752.101001, -------------- SYN_REPORT ------------
Event: time 1487014752.351117, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014752.351117, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014752.351117, -------------- SYN_REPORT ------------
Event: time 1487014752.383456, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014752.383456, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014752.383456, -------------- SYN_REPORT ------------
Event: time 1487014752.416794, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014752.416794, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014752.416794, -------------- SYN_REPORT ------------
Event: time 1487014752.449444, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014752.449444, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014752.449444, -------------- SYN_REPORT ------------
Event: time 1487014752.484449, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014752.484449, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014752.484449, -------------- SYN_REPORT ------------
Event: time 1487014752.517624, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014752.517624, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014752.517624, -------------- SYN_REPORT ------------
Event: time 1487014752.550326, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014752.550326, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014752.550326, -------------- SYN_REPORT ------------
Event: time 1487014752.585433, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014752.585433, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014752.585433, -------------- SYN_REPORT ------------
Event: time 1487014752.619651, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014752.619651, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014752.619651, -------------- SYN_REPORT ------------
Event: time 1487014752.652440, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014752.652440, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014752.652440, -------------- SYN_REPORT ------------
Event: time 1487014752.686208, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014752.686208, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014752.686208, -------------- SYN_REPORT ------------
Event: time 1487014752.719545, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014752.719545, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014752.719545, -------------- SYN_REPORT ------------
Event: time 1487014752.752444, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014752.752444, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014752.752444, -------------- SYN_REPORT ------------
Event: time 1487014752.785123, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014752.785123, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014752.785123, -------------- SYN_REPORT ------------
Event: time 1487014752.819428, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014752.819428, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014752.819428, -------------- SYN_REPORT ------------
Event: time 1487014752.854787, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014752.854787, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014752.854787, -------------- SYN_REPORT ------------
Event: time 1487014752.887551, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014752.887551, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014752.887551, -------------- SYN_REPORT ------------
Event: time 1487014752.921460, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014752.921460, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014752.921460, -------------- SYN_REPORT ------------
Event: time 1487014752.954739, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014752.954739, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014752.954739, -------------- SYN_REPORT ------------
Event: time 1487014752.987371, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014752.987371, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014752.987371, -------------- SYN_REPORT ------------
Event: time 1487014753.021338, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014753.021338, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014753.021338, -------------- SYN_REPORT ------------
Event: time 1487014753.054679, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014753.054679, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014753.054679, -------------- SYN_REPORT ------------
Event: time 1487014753.087843, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014753.087843, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014753.087843, -------------- SYN_REPORT ------------
Event: time 1487014753.122401, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014753.122401, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014753.122401, -------------- SYN_REPORT ------------
Event: time 1487014753.154514, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014753.154514, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014753.154514, -------------- SYN_REPORT ------------
Event: time 1487014753.189514, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014753.189514, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014753.189514, -------------- SYN_REPORT ------------
Event: time 1487014753.221549, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014753.221549, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014753.221549, -------------- SYN_REPORT ------------
Event: time 1487014753.256274, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014753.256274, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014753.256274, -------------- SYN_REPORT ------------
Event: time 1487014753.288709, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014753.288709, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014753.288709, -------------- SYN_REPORT ------------
Event: time 1487014753.322631, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014753.322631, type 1 (EV_KEY), code 31 (KEY_S), value 2
Event: time 1487014753.322631, -------------- SYN_REPORT ------------
Event: time 1487014753.356657, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1f
Event: time 1487014753.356657, type 1 (EV_KEY), code 31 (KEY_S), value 0
Event: time 1487014753.356657, -------------- SYN_REPORT ------------
Event: time 1487014753.362487, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e
Event: time 1487014753.362487, type 1 (EV_KEY), code 30 (KEY_A), value 0
Event: time 1487014753.362487, -------------- SYN_REPORT ------------

Mit xev sieht es dann als nächstes Glied in der Kette der Weiterleitung der Tastendrücke zum laufenden Terminal auch so aus, dass keine Tastenwiederholungsevents für "A" mehr ankommen, sobald "S" gedrückt wird. Eine Anwendung, die für beide Keys Events generieren wollte, müsste also eine Art Autofeuer-Funktion nutzen, wenn eine Taste gedrückt wurde, aber keine Wiederholungsevents liefert.

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17621

Wohnort: Berlin

Sowas braucht man z.B. für ein Multiplayerspiel an einer Tastatur, wenn einer WASD hat und der andere die Pfeiltasten und man mit Drücken den Gegner blocken kann. ☺

eagle87

(Themenstarter)

Anmeldungsdatum:
29. Dezember 2010

Beiträge: 85

Ich will über die Tastatur ein Fahrzeug steuern. Damit ich mehrere Achsen gleichzeitig verändern kann benötige ich die parallele Eingabe von mehreren Tasten. Das Programm soll unabhängig von X11 sein und auch über ssh funktionieren. Das Programm dazu schreibe ich übrigens in C.

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11261

Wohnort: München

Für die gängigen Programmiersprachen gibt es oft schon fertige Bibliotheken, die einem die Low-Level Aufgaben wie das Lesen von den Kernel Input Devices abnehmen, wie z.B. zeth/inputs für Python oder SDL für C: https://www.libsdl.org/release/SDL-1.2.15/docs/html/guideinputkeyboard.html (Abschnitt "Game-type Input").

Über eine normale SSH-Shell werden soweit ich weiß nur einzelne Zeichen durchgereicht, da müsste man sich vermutlich ein Client-Programm schreiben, das die lokalen Kernel Input Devices auswertet und dann die Daten in einer serialisierten Form an den Server weiterreicht.

Edit: oder man erledigt es zu Fuß, das Datenformat, das von Kernel Input Devices geliefert wird, wird z.B. in https://www.kernel.org/doc/Documentation/input/input.txt beschrieben:

5. Event interface
~~~~~~~~~~~~~~~~~~
  Should you want to add event device support into any application (X, gpm,
svgalib ...) I <vojtech@ucw.cz> will be happy to provide you any help I
can. Here goes a description of the current state of things, which is going
to be extended, but not changed incompatibly as time goes:

  You can use blocking and nonblocking reads, also select() on the
/dev/input/eventX devices, and you'll always get a whole number of input
events on a read. Their layout is:

struct input_event {
	struct timeval time;
	unsigned short type;
	unsigned short code;
	unsigned int value;
};

  'time' is the timestamp, it returns the time at which the event happened.
Type is for example EV_REL for relative moment, EV_KEY for a keypress or
release. More types are defined in include/linux/input.h.

  'code' is event code, for example REL_X or KEY_BACKSPACE, again a complete
list is in include/linux/input.h.

  'value' is the value the event carries. Either a relative change for
EV_REL, absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for
release, 1 for keypress and 2 for autorepeat.

eagle87

(Themenstarter)

Anmeldungsdatum:
29. Dezember 2010

Beiträge: 85

Auch wenn es nicht genau das ist wonach ich suche könnte SDL interessant sein. Bei SDL oder dem Einlesen der Kernel Input Devices habe ich aber die Befürchtung, dass das nicht mehr ohne Root-Rechte gehen wird. Ich würde das Programm gerne als normaler User ausführen können. Das muss ich bei Gelegenheit mal testen.

eagle87

(Themenstarter)

Anmeldungsdatum:
29. Dezember 2010

Beiträge: 85

Kann es sein, dass SDL nur in Kombination mit einer GUI funktioniert?

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11261

Wohnort: München

Soweit ich das gelesen habe, funktioniert es auch ohne X-Server, ein Framebuffer sollte genügen.

eagle87

(Themenstarter)

Anmeldungsdatum:
29. Dezember 2010

Beiträge: 85

Dass es mit Framebuffer gehen soll habe ich auch gelesen. Aber das Programm soll keinerlei GUI haben. Also auch nicht über den Framebuffer.

Das ist mein aktueller Code für SDL:

#include <stdio.h>
#include <SDL2/SDL.h>


int main(int argc, char **argv)
{
	(void) argc;
	(void) argv;
	
	// Video und Timersubsystem initialisieren
//	if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER))
	if(SDL_Init(SDL_INIT_EVENTS|SDL_INIT_TIMER))
	{
		fprintf(stderr, "Konnte SDL nicht initialisieren: %s", SDL_GetError());
		return(1);
	}
	atexit(&SDL_Quit);
	
//	SDL_Window *screen;
//	screen = SDL_CreateWindow("My Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_FOREIGN);
//	if(!screen)
//	{
//		fprintf(stderr, "Konnte Videomodus nicht setzen: %s", SDL_GetError());
//		return(1);
//	}
	
	SDL_Event event;
	while(1)
	{
		if(SDL_PollEvent(&event))
		{
			if(event.type==SDL_QUIT)
			{
				break;
			}
			else if(event.type==SDL_KEYDOWN)
			{
				puts("down");
				printf("\tScancode: 0x%02X\n", event.key.keysym.scancode);
				printf("\tSym:  %c\n", event.key.keysym.sym);
				printf("\tName: %s\n", SDL_GetKeyName(event.key.keysym.sym));
			}
			else if(event.type==SDL_KEYUP)
			{
				puts("up");
				if(event.key.keysym.scancode==0x14)
					break;
			}
		}
	}
	
	return(0);
}

Die Tastatureingaben werden nur eingelesen wenn ich ein Fenster öffnen lasse.

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11261

Wohnort: München

Ich habe mit SDL noch nicht viel gemacht, aber kann man da nicht die Umgebungsvariable SDL_VIDEODRIVER=dummy setzen? http://sdl.beuc.net/sdl.wiki/SDL_envvars

eagle87

(Themenstarter)

Anmeldungsdatum:
29. Dezember 2010

Beiträge: 85

Das setzen der Umgebungsvariable auf dummy führt zwar dazu, dass sich keine GUI mehr öffnet, aber dann kann ich leider auch keine Tastatureingaben mehr einlesen.

Ich denke dass SDL doch nichts passendes ist. Das ist eher für GUI-Programmierung ausgelegt und für ein paar Tastatureingaben etwas viel Overhead. Werd mir eher in den nächsten Tagen mal das Einlesen der Kernel Input Devices anschauen. Trotzdem vielen Dank für deine Tipps zu SDL. Das könnte irgendwann für ein anderes Projekt interessant sein.

Vain

Avatar von Vain

Anmeldungsdatum:
12. April 2008

Beiträge: 2510

eagle87 schrieb:

Das Programm soll unabhängig von X11 sein und auch über ssh funktionieren.

Wie genau meinst du das? Du loggst dich per SSH auf einer anderen Kiste ein, startest dort dein Programm und möchtest dann deine Tastatur verwenden? Das könnte dann echt schwierig werden, weil du ja dann von der anderen Kiste aus wieder auf deinen Rechner zugreifen müsstest, um bei dir die Input-Devices anzuzapfen.

X11 kann auch Forwarding über’s Netzwerk per SSH. Damit ginge das dann wieder: Du loggst dich per SSH irgendwo ein, startest dort dein Programm, aber jetzt passiert das Input-Handling automatisch bei dir auf dem Rechner und wird dann per SSH/X11 an dein Programm auf dem anderen System weitergeleitet.

eagle87

(Themenstarter)

Anmeldungsdatum:
29. Dezember 2010

Beiträge: 85

Vain schrieb:

Du loggst dich per SSH auf einer anderen Kiste ein, startest dort dein Programm und möchtest dann deine Tastatur verwenden?

Genau so hatte ich das ursprünglich vor. Von dem Gedanken muss ich mich wohl verabschieden. X11-Forwarding will ich aufgrund der Sicherheitslücken nicht verwenden. Es wird dann wohl doch eher eine Kombination aus Server und Clientprogramm, wie auch seahawk1986 schon vorgeschlagen hat.

Vain

Avatar von Vain

Anmeldungsdatum:
12. April 2008

Beiträge: 2510

eagle87 schrieb:

X11-Forwarding will ich aufgrund der Sicherheitslücken nicht verwenden.

Nur zum Verständnis: Du musst kein reines X11-Forwarding machen (also X11 auf TCP lauschen lassen und diesen Port z.B. im Internet freigeben). Man kann das stattdessen auch über SSH tunneln. Das eröffnet dann zwar immer noch Angriffsmöglichkeiten, weil eben alles, was auf deinem Server läuft, auf dein X11 zugreifen kann/könnte, aber es ist deutlich harmloser als die erstgenannte Variante. ☺

Antworten |