Habe diesen Code getestet (obere Version für clients) https://wayland-book.com/wayland-display/creation.html und erhalte die Meldung "Failed to connect to Wayland display".
Hat jemand eine Idee für Abhilfe?
|
Anzeige
|
opensuse Leap 15.6 KDE Wayland - ProgrammierungHabe diesen Code getestet (obere Version für clients) https://wayland-book.com/wayland-display/creation.html und erhalte die Meldung "Failed to connect to Wayland display". Hat jemand eine Idee für Abhilfe? Hat du denn Wayland laufen oder eventuell noch X11?
Irgendwo geht die Information zu Wayland verloren. Teste "echo $WAYLAND_DISPLAY" an der Konsole. Wenn das nix ausgibt, hast du an der Stelle kein Wayland. Ansonsten enthält "$WAYLAND_DISPLAY" den Namen eines Sockets im "$XDG_RUNTIME_DIR" (also z.B. /run/user/1000/wayland-0). Diese Datei muss für dein Programm auch erreichbar und benutzbar sein. Wenn diese Environment-Variablen nicht gesetzt sind, könntest du den Pfad zum Socket auch als Parameter zu wl_display_connect angeben, ist aber meist eine schlechte Idee. Environment-Variablen vererben sich nicht (automatisch) durch sudo, su, docker-container usw.
Hat nichts ausgegeben, obwohl ich bei der Anmeldung (erstmals) Wayland ausgewählt hatte. Habe mich jetzt nochmal abgemeldet und wieder angemeldet. Jetzt klappt es. "echo $WAYLAND_DISPLAY" liefert jetzt "wayland-0" und das Programm "Connection established!". Allerdings wird jetzt immer wieder mal der Bildschirm etwa eine Sekunde lang schwarz. Aber erst mal Danke. Werde vermutlich noch weitere Fragen haben.
Das ist ein Fehler im Wayland. Das passiert bei den verschiedenen Screenshot-Programmen ebenfalls. Habe den Code etwas umgeschrieben und erweitert:
Versuch zu Compilieren mittels
liefert die Fehlermeldungen undefined reference to Weiss jemand warum? Was fehlt in der #include-Liste? Hat sich erledigt. Compilieren mit
funktioniert. !!! Weitere Frage nach längerer Pause !!!Habe diesen Beispielcode gefunden: https://bugaevc.gitbooks.io/writing-wayland-clients/content/black-square/the-complete-code.html Der Code lässt sich compilieren mit
Starten mit ./square führt zu Abbruch mit Speicherzugriffsfehler. Bei sukzessivem Löschen einzelner Anweisungen vom Ende her verschwindet der Fehler nach Löschen von Zeile 56:
Hat jemand eine Idee, woran es liegen könnte? :
Bearbeitet durch User
"wl_shell_*" war ursprünglich nur als simple Test-Option gedacht, wurde nie von allen Compositors unterstützt, ist vor vielen Jahren aus KDE rausgeflogen. Entweder du nimmst einen alten Weston, oder passt den Code an, "xdg_shell" statt "wl_shell". https://wayland.app/protocols/wayland#wl_shell
sh. Anhang. Danke. Damit bin ich einige Zeit beschäftigt. Ich melde mich wieder. Mit Leap 15.6 bin ich nicht weitergekommen. Mit Tumbleweed/Gnome hat nun alles geklappt. Habe dann das Programm erweitert und eine eigene Grafik in den Datenbuffer geschrieben und ausgegeben. Zum Ausgeben habe ich verwendet:
Auch das hat geklappt. Ich wollte nun Zeichen von der Tastatur einlesen und die Grafik modifizieren. An Wayland-Keyboard-Events habe ich mich bisher nicht herangetraut. Stattdessen habe ich bei geöffneter Grafik das Konsolenfenster in den Vordergrund geholt und ncurses verwndet. Das funktioniert ansatzweise. Ich kann ein oder zwei Zeichen einlesen und die Grafik modifizieren, dann hängt das Programm. Wenn man den Mauszeiger in das Grafikfenster bewegt, erscheint nach ein paar Sekunden eine Meldung, dass das Fenster nicht antwortet, und es wird angeboten, das Fenster zwangsweise zu schließen. Kann mein Ansatz, die Tastatur mittels ncurses einzulesen, überhaupt funktionieren, und wenn ja, was kann ich tun, um das Hängen des Programms zu vermeiden? :
Bearbeitet durch User
Problem, vermutlich: Du wartest blocking auf eine Taste in ncurses. (getch() & co) Das geht nicht, deine Wayland-Loop muss durchlaufen, (also wl_display_dispatch regelmäßig aufgerufen werden). Du kannst nicht zwischendurch pausieren bis eine Taste gedrückt wird.
Ja
Nonblocking auf die Taste warten (timeout(0); getch() gibt dann ERR zurück, wenn keine Taste gedrückt) Oder Multithreading, eigener Thread für ncurses. (Overkill, eher weniger für Anfänger) Ansonsten sind die Keyboard-Events jetzt auch nicht so kompliziert...
Ansonsten im registry-handler "wl_seat" binden (
Hab das mal alles zusammen in eine KI geworfen. vielleicht kannst du dir was abschauen. in's compile.sh von oben:
die "poll()"-Loop ist vmtl. nicht zwingend nötig, aber praktisch wenn du weitere FDs (Netzwerk-Socket z.B) mit überwachen willst.
Habe jetzt deinen Vorschlag timeout(0) für getch() umgesetzt. Der Code ist bis Zeile 152 initscr() dein unveränderter Code (nur die Integer-Vereinbarung i gleich nach main(void) sowie die Werte für width und height sind neu). Das Programm soll ein Rechteck ausgeben. Bei den ersten 4 Tastendrücken soll das Rechteck von oben her sukzessive weiss werden. Beim fünften Tastendruck soll das Programm enden. Das tut es auch. Im Prinzip. Leider reagiert die Grafik aber jeweils erst, wenn man den Mauszeiger über der Grafik bewegt. ??? :
Bearbeitet durch User
"wl_display_dispatch(display)" blockiert normalerweise bis ein neues Event vom Compositor kommt. d.H. statt in getch() hängt dein Programm jetzt dort, wenn du eine Taste im Terminal drückst, läuft das nächste ncurses/getch() trotzdem erst nach dem nächsten Wayland-Event, z.B. einem Mouse-Move. wl_display_dispatch ist eine Abkürzung für ein flush+dispatch_pending (Pending Events raussenden&verarbeiten), ein Poll mit Timeout infinite auf dem Wayland-Socket, read_events (Neue Events vom Socket lesen), und nochmal dispatch_pending um die gleich zu verarbeiten. Wenn dein Programm selber Animationen abspielen soll, oder auf externe Ereignisse reagieren muss (Netzwerk, ncurses-getch, ...) kannst du das nicht verwenden. Stattdessen musst du die Einzelschritte aus dem wl_display_dispatch selber schreiben, also eine eigene Event-Loop aufbauen. Da kannst du dann entweder mit einem kurzen Timeout im poll arbeiten (sh. das "pong.c"-Beispiel) und/oder auch den STDIN-Filedescriptor mit in das poll aufnehmen. in etwa:
Nachtrag: Kann sein, dass du den Buffer auch jedesmal neu Attachen musst:
Hängt vom Compositor ab. Ist zwar "Shared Memory", aber der Compositor kann trotzdem eine Kopie davon machen (z.B. als Textur im Grafikspeicher), die die Änderungen dann nicht mitbekommt. Mir ist gerade ein grundsätzliches Problem des Verfahrens eingefallen. Bei meiner Anwendung wird das Grafikfenster 1024 mal 512 Pixel groß sein. Ich hatte geplant, zum Beenden der Grafik die Escape-Taste vorzusehen. Wenn man nun vergisst, vor dem Start der Grafik das Konsolenfenster nach unten zu schieben, kann es im Extremfall dazu kommen, dass das Grafikfenster das Konsolenfenster komplett verdeckt, so dass man das Konsolenfenster nicht in den Vordergrund holen kann. Dann bleibt die Escape-Taste wirkunglos, und man kann die Grafik nicht mehr beenden. Vielleicht fällt dir auch dazu noch eine Lösung ein. Schön wäre es, das Programm durch einen Klick ins Grafikfenster beenden zu können. Notfalls werde ich im Event-Loop mittels gettimeofday() das Programm per timeout beenden. :
Bearbeitet durch User
Du kannst doch sicher Fenster per Alt-Tab durchwechseln, und deine Konsole wieder nach vorne holen. Oder, je nach Window-Manager, das Fenster mit Alt+Maustaste oder Meta+Maustaste oder "Verschieben"-Aktion in der Taskleiste verschieben. Ansonsten: Trau dich an die Keyboard-Event-Handler. Das "pong.c"-Beispielprogramm von oben beendet sich mit ESC. Auf Maus-Events (also den Klick) im Programm zu reagieren ist da sehr ähnlich. Statt
eben dasselbe mit Suchen&Ersetzen "keyboard" -> "pointer", im pointer_listener deinen Callback für ".button" eintragen (andere/ungenutzte auf No-Op)
Hier gibt's was dazu zu lesen: Antwort schreiben |
Anzeige
|