Tastaturereignisse werden vom Hauptprogramm ignoriert...
Hallo, ich habe ein wohl etwas ungewöhnliches Problem, hoffe aber dass mir hier jemand helfen kann. Ich habe ein Hauptprogramm (in C unter linux) das einen Automaten betreibt. Jetzt starte ich die grafische Oberfläche (SDL) als Thread von diesem Hauptprogramm aus. Von der grafischen Oberfläche benötige ich keinerlei Rückmeldung. Die Grafik läuft also komplett unabhängig vom Hauptprogramm außer das sich die Grafikroutine einige relevante Daten aus einigen globalen Variablen liest. Das Hauptprogramm muss allerdings auf Tastatureingaben reagieren. Sobald aber die Grafikroutine als Thread gestartet ist wird auch die Tastatur über die SDL-Routinen abgefangen und nicht mehr vom Hauptprogramm verarbeitet. Gibt es eine Möglichkeit die Ereignisse der Tastatur nach dem Start des Grafik-Threads wieder an das Hauptprogramm zu übergeben. Danke Michael
Michael Höing wrote:
Das Hauptprogramm muss allerdings auf Tastatureingaben reagieren. Sobald aber die Grafikroutine als Thread gestartet ist wird auch die Tastatur über die SDL-Routinen abgefangen und nicht mehr vom Hauptprogramm verarbeitet.
Gibt es eine Möglichkeit die Ereignisse der Tastatur nach dem Start des Grafik-Threads wieder an das Hauptprogramm zu übergeben.
Du meintest doch sicher eher Funktion als Thread? Das ist die einzige Moeglichkeit, die mir bewusst ist: Du musst mit Threads hantieren. Der Teil der die Grafikroutine aufruft und einen Teil der dann die Tastatureingaben verarbeitet. Die Tastatureingaben an das Grafikfenster musst du natuerlich im Grafikthread verarbeiten. Peter
Du meintest doch sicher eher Funktion als Thread?
Das ist die einzige Moeglichkeit, die mir bewusst ist:
Du musst mit Threads hantieren. Der Teil der die Grafikroutine aufruft und einen Teil der dann die Tastatureingaben verarbeitet.
Die Tastatureingaben an das Grafikfenster musst du natuerlich im Grafikthread verarbeiten.
Peter
Nein ich meine schon Threads. Das Hauptprogramm mit der Steuerung für den Automaten funktioniert tadelos. Die Grafik starte ich dann aus diesem Hauptprogramm direkt als extra Thread. Nur genau in dem Moment in dem der Grafik-Thread gestartet und SDL (in diesem Thread) initialisiert wird, wird auch das EventHandling für die tastatur von der SDL übernommen. Eigentlich bräuchte ich eine Möglichkeit, das EventHandling oder nur das SDL_KeyboardEvent bei der Initialisierung der SDL-Grafik abzuschalten.
Michael Höing wrote:
Eigentlich bräuchte ich eine Möglichkeit, das EventHandling oder nur das SDL_KeyboardEvent bei der Initialisierung der SDL-Grafik abzuschalten.
Nope: http://sdldoc.csn.ul.ie/event.php Event handling is initalised (along with video) with a call to: SDL_Init(SDL_INIT_VIDEO); Beschreib dein Problem mal allgemeiner. Warum kannst/willst du nicht die Event-Behandlung der SDL benutzen? Peter
Eigentlich bräuchte ich eine Möglichkeit, das EventHandling oder nur das SDL_KeyboardEvent bei der Initialisierung der SDL-Grafik abzuschalten.
Nope: http://sdldoc.csn.ul.ie/event.php
Event handling is initalised (along with video) with a call to:
SDL_Init(SDL_INIT_VIDEO);
Beschreib dein Problem mal allgemeiner.
Warum kannst/willst du nicht die Event-Behandlung der SDL benutzen?
Peter
Naja, die Sache ist so. Das Automatensystem läuft bereits problemlos. Die einzigen Rückmeldungen bekomme ich vom Kunden später über einen frei programmierbaren Tastaturcontroller. Die Auswertung des Controllers und damit die Abfrage der Tastatur ist also bereits in der Automatensteuerung implementiert. Jetzt will ich die Grafik halt einfach nur aufsetzten. Ich starte die Grafik also als Thread und alles was ich will ist, dass die Grafik einfach nur Daten auf mein LCD ausgibt. Das macht Sie ja auch schon. Ich brauche keinerlei Ereignisbehandlung, habe keine Buttons, keine Eingabefelder, kein Touchscreen. Ich brauche also keinerlei Rückmeldung von der Grafik. Jetzt habe ich alles soweit fertig (ist übrigens ne Diplomarbeit). Z. Z. starte ich das Programm einfach von der Konsole, das Hauptprogramm startet, damit wird auch der Grafik-Thread erzeugt und das Fenster mit der grafischen Oberfläche für meinen Automaten erscheint. Damit liegt also auch der Focus und die Ereignisbehandlung auf diesem Fenster. Bisher kann ich noch einfach in das Konsolenfenster klicken schalte damit den Focus wieder auf das Hauptprogramm. Da allerdings das Automatensystem nachher direkt bis zur grafischen Oberfläche automatisch hochfahren muss, suche ich halt einen Weg, den Focus nach Aufruf des Grafik-Threads wieder an das aufrufende Programm zurückzugeben oder bei der Initialisierung der SDL-Grafik die Ereignisbehandlung gar nicht mit zu starten. Ich hoffe das war etwas besser erklärt. Vielleicht fällt Dir (Euch) ja jetzt noch was ein... Danke Michael
On Tuesday 10 June 2003 16:58, Michael Höing wrote:
Eigentlich bräuchte ich eine Möglichkeit, das EventHandling oder nur das SDL_KeyboardEvent bei der Initialisierung der SDL-Grafik abzuschalten.
Wenn das nicht geht, kannst du mal folgendes probieren:
#include <iostream>
#include <string>
#include
On Tuesday 10 June 2003 16:58, Michael Höing wrote:
Eigentlich bräuchte ich eine Möglichkeit, das EventHandling oder nur das SDL_KeyboardEvent bei der Initialisierung der SDL-Grafik abzuschalten.
Wenn das nicht geht, kannst du mal folgendes probieren: #include <iostream> #include <string> #include
const int SIZE = 256;
int main() { int fd = dup( 0); close( 0); int n; char buf [SIZE]; while ((n = read( fd, buf, SIZE)) != -1) { std::cout << std::string( buf, buf + n); } return 0; }
Mit dup() kopierst du die Standardeingabe und mit close() schliesst du dann die normale Standardeingabe. Es ist halt noch die Frage, was SDL macht, wenn die geschlossen ist.
Ciao Sebastian
Danke Sebastian... hat zwar etwas gedauert, aber hier die Rückmeldung. Die Sache mit dem Schliessen der Standardeingabe im Grafikteil hat leider nicht funktioniert. Irgendwie bekommt dann die Hauptroutine alle möglichen Sonderzeichen vom Grafikthread und die kann ich nicht gebrauchen (und auch nicht abblocken). Kann man den nicht beim Erzeugen eines Thread mitgeben, dass der Focus auf dem aufrufenden Thread bleibt und nicht von der SDL-Grafik (also dem neuen Thread) übernommen wird? Trotzdem herzlichen Dank für Deinen Tipp!!! Vielleicht fällt ja noch jemandem was ein... Danke Michael
On Thursday 12 June 2003 15:56, Michael Höing wrote: [...]
hat zwar etwas gedauert, aber hier die Rückmeldung. Die Sache mit dem Schliessen der Standardeingabe im Grafikteil hat leider nicht funktioniert.
Irgendwie bekommt dann die Hauptroutine alle möglichen Sonderzeichen vom Grafikthread und die kann ich nicht gebrauchen (und auch nicht abblocken). [...]
Hi, also das verstehe ich nicht. Die Sache laeuft doch so ab: Das Programm wird gestartet und hat eine Standardeingabe -> nun kopierst du den Filediskriptor der Standardeingabe und schliesst den Filedeskriptor 0 -> SDL wird gestartet Die Standardeingabe kommt nun ueber den kopierten Filedeskriptor, von dem SDL aber keine Ahung hat. Das Hauptprogramm muss nun jedoch vom kopierten Filedeskriptor lesen. Wenn sich SDL beschwert, dass die Standardeingabe geschlossen ist, dann kannst du einen FIFO nach 0 umlenken mittels dup2(). Ciao
Hi, also das verstehe ich nicht. Die Sache laeuft doch so ab:
Das Programm wird gestartet und hat eine Standardeingabe -> nun kopierst du den Filediskriptor der Standardeingabe und schliesst den Filedeskriptor 0 -> SDL wird gestartet
Die Standardeingabe kommt nun ueber den kopierten Filedeskriptor, von dem SDL aber keine Ahung hat. Das Hauptprogramm muss nun jedoch vom kopierten Filedeskriptor lesen. Wenn sich SDL beschwert, dass die Standardeingabe geschlossen ist, dann kannst du einen FIFO nach 0 umlenken mittels dup2().
Ciao
Hi, auf die Gefahr hin, dass ich Dich langsam nerve... ich tu es trotzdem. Ich hexe weiterhin an der Sache mit dem Umlenken, bzw. Schliessen der Standardeingabe rum und werde Dich natürlich wissen lassen wie es ausgeht. Da ich nicht unbedingt der Crack bin kann das ganze aber etwas dauern und darum möchte ich Dich auch noch bitten, mir diese (Deine) Zeilen:
while ((n = read( fd, buf, SIZE)) != -1) { std::cout << std::string( buf, buf + n);
insbesondere die zweite Zeile kurz zu erklären. Danke
On Thursday 12 June 2003 17:44, Michael Höing wrote: [...]
und darum möchte ich Dich auch noch bitten, mir diese (Deine) Zeilen:
while ((n = read( fd, buf, SIZE)) != -1) { std::cout << std::string( buf, buf + n);
insbesondere die zweite Zeile kurz zu erklären. [...]
Hier liest du so lange von fd, bis ein Fehler kommt. Wenn kein Fehler kam (n != -1), dann enthaelt n die Anzahl der gelesenen Chars. SIZE ist die Groesse des Puffers buf. Die zweite Zeile ist eigentlich Unsinn, kuerzer ist write( 1, buf, n); Nun was passiert in der urspruenglichen Version? Es wird ein std::string Objekt erzeugt, und zwar mit den Werten von [buf, buf + n), der Zeiger buf fungiert als Iterator. Anschliessend wird dieses Objekt in die Standardausgabe geschoben.
Hi, also das verstehe ich nicht. Die Sache laeuft doch so ab:
Das Programm wird gestartet und hat eine Standardeingabe -> nun kopierst du den Filediskriptor der Standardeingabe und schliesst den Filedeskriptor 0 -> SDL wird gestartet
Die Standardeingabe kommt nun ueber den kopierten Filedeskriptor, von dem SDL aber keine Ahung hat. Das Hauptprogramm muss nun jedoch vom kopierten Filedeskriptor lesen. Wenn sich SDL beschwert, dass die Standardeingabe geschlossen ist, dann kannst du einen FIFO nach 0 umlenken mittels dup2().
Ciao
Die Sache funktioniert soweit ganz gut. Ich hab den Filedeskriptor kopiert und geschlossen -> dann SDL als Thread gestartet. Allerdings reagiert jetzt auch mein Hauptprogramm nicht mehr auf Eingaben. Wie bringe ich den jetzt das Hauptprogramm dazu, aus dem kopierten Filedeskriptor zu lesen? Thx
Michael Höing wrote:
Kann man den nicht beim Erzeugen eines Thread mitgeben, dass der Focus auf dem aufrufenden Thread bleibt und nicht von der SDL-Grafik (also dem neuen Thread) übernommen wird?
Was benutzt du im Endeffekt als SDL output? X11? svgalib? Peter
Kann man den nicht beim Erzeugen eines Thread mitgeben, dass der Focus auf dem aufrufenden Thread bleibt und nicht von der SDL-Grafik (also dem neuen Thread) übernommen wird?
Was benutzt du im Endeffekt als SDL output? X11? svgalib?
Peter
Ich bin mir nicht 100% sicher glaube aber (99%) das SDL X11 nutzt. Gibts da ne Möglichkeit???
Michael Höing wrote:
Kann man den nicht beim Erzeugen eines Thread mitgeben, dass der Focus auf dem aufrufenden Thread bleibt und nicht von der SDL-Grafik (also dem neuen Thread) übernommen wird?
Was benutzt du im Endeffekt als SDL output? X11? svgalib?
Ich bin mir nicht 100% sicher glaube aber (99%) das SDL X11 nutzt. Gibts da ne Möglichkeit???
Naja, SDL ist Multiplattform und kann auf MS Windows kein X11. (Fuer den Programmierer bleibt durch die Lib AFAIK alles beim alten) Bei mir ist SDL auch gegen libaa.so gelinkt, was auf reine Textausgabe hindeutet. Einigen SDL Games muss man auch explizit sagen, das nun X11 gewuenscht ist. Peter
Michael Höing schrieb:
Eigentlich bräuchte ich eine Möglichkeit, das EventHandling oder nur das SDL_KeyboardEvent bei der Initialisierung der SDL-Grafik abzuschalten.
.....
Naja, die Sache ist so. Das Automatensystem läuft bereits problemlos. Die einzigen Rückmeldungen bekomme ich vom Kunden später über einen frei programmierbaren Tastaturcontroller. Die Auswertung des Controllers und damit die Abfrage der Tastatur ist also bereits in der Automatensteuerung implementiert.
Jetzt will ich die Grafik halt einfach nur aufsetzten. Ich starte die Grafik also als Thread und alles was ich will ist, dass die Grafik einfach nur Daten auf mein LCD ausgibt. Das macht Sie ja auch schon. Ich brauche keinerlei Ereignisbehandlung, habe keine Buttons, keine Eingabefelder, kein Touchscreen. Ich brauche also keinerlei Rückmeldung von der Grafik.
Jetzt habe ich alles soweit fertig (ist übrigens ne Diplomarbeit). Z. Z. starte ich das Programm einfach von der Konsole, das Hauptprogramm startet, damit wird auch der Grafik-Thread erzeugt und das Fenster mit der grafischen Oberfläche für meinen Automaten erscheint. Damit liegt also auch der Focus und die Ereignisbehandlung auf diesem Fenster. Bisher kann ich noch einfach in das Konsolenfenster klicken schalte damit den Focus wieder auf das Hauptprogramm. Da allerdings das Automatensystem nachher direkt bis zur grafischen Oberfläche automatisch hochfahren muss, suche ich halt einen Weg, den Focus nach Aufruf des Grafik-Threads wieder an das aufrufende Programm zurückzugeben oder bei der Initialisierung der SDL-Grafik die Ereignisbehandlung gar nicht mit zu starten.
Ich hoffe das war etwas besser erklärt.
Vielleicht fällt Dir (Euch) ja jetzt noch was ein...
Wenn die Ausgabe sowieso nur als Anzeige aufgesetzt wird, lager die doch in ein extra Programm aus und schicke dem einfach jeweils den neuesten Status per Pipe hinüber. (Z.B. mit popen() ) Damit hast Du dann noch eine saubere Trennung zwischen Verarbeitung und Anzeige. (und da das Anzeigeprogramm extra ist, kann man das bei Bedarf leicht gegen was anderes austauschen, Textanzeige, LEDs, ... ) MfG Rene Liebscher
participants (4)
-
M-S-Hoeing@t-online.de
-
Peter Wiersig
-
René Liebscher
-
Sebastian Huber