opensuse Leap 15.6 KDE Wayland - Programmierung

#7997873
Lesenswert?
• ▲
▼

Josef G. schrieb:

Hat jemand eine Idee für Abhilfe?

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.

OP Persönliche Seite #7997976
Lesenswert?
• ▲
▼

Εrnst B. schrieb:

Teste "echo $WAYLAND_DISPLAY" an der Konsole. Wenn das nix ausgibt, hast du an der Stelle kein Wayland.

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.

OP Persönliche Seite #7999418
Lesenswert?
• ▲
▼

Habe den Code etwas umgeschrieben und erweitert:

1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <wayland-client.h>
4
#include <wayland-egl.h>
5

6
int main(){ struct wl_display *display;
7
            struct wl_surface *surface;
8
            struct wl_egl_window *egl_window;
9

10
    display = wl_display_connect(NULL);
11
    if (!display) { printf("Failed\n"); return(0);}
12

13
    egl_window = wl_egl_window_create(surface,480,360);
14
    wl_egl_window_destroy(egl_window);
15

16
    wl_display_disconnect(display);
17
    return(0);}

Versuch zu Compilieren mittels

1
gcc -o wltest wltest.c -lwayland-client

liefert die Fehlermeldungen

undefined reference to wl_egl_window_create' undefined reference to wl_egl_window_destroy'

Weiss jemand warum? Was fehlt in der #include-Liste?

OP Persönliche Seite #8096791
Lesenswert?
• ▲
▼

!!! 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

1
gcc -o square square.c -lwayland-client

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:

1
struct wl_shell_surface *shell_surface = wl_shell_get_shell_surface(shell, surface);

Hat jemand eine Idee, woran es liegen könnte?

: Bearbeitet durch User
#8096802
Lesenswert?
• ▲
▼

Josef G. schrieb:

Hat jemand eine Idee, woran es liegen könnte?

"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

Note! This protocol is deprecated and not intended for production use. For desktop-style user interfaces, use xdg_shell. Compositors and clients should not implement this interface.

sh. Anhang.

Angehängte Dateien:
OP Persönliche Seite #8106930
Lesenswert?
• ▲
▼

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:

1
   wl_surface_damage(surface,0,0,4096,512);
2
   wl_surface_commit(surface);
3
   wl_display_dispatch(display);

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
#8106958
Lesenswert?
• ▲
▼

Josef G. schrieb:

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.

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.

Kann mein Ansatz, die Tastatur mittels ncurses einzulesen, überhaupt funktionieren,

Ja

und wenn ja, was kann ich tun, um das Hängen des Programms zu vermeiden?

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...

1
void keyboard_key_handler
2
(
3
    void *data,
4
    struct wl_keyboard *keyboard,
5
    uint32_t serial,
6
    uint32_t time,
7
    uint32_t key,
8
    uint32_t state
9
) {
10
    if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
11
        printf("key %u pressed\n", key);
12
        paint(something);
13
    }
14
}
15

16
void keyboard_noop() {}
17

18
const struct wl_keyboard_listener keyboard_listener = {
19
    .keymap      = (void *)keyboard_noop,
20
    .enter       = (void *)keyboard_noop,
21
    .leave       = (void *)keyboard_noop,
22
    .key         = keyboard_key_handler,
23
    .modifiers   = (void *)keyboard_noop,
24
    .repeat_info = (void *)keyboard_noop,
25
};

Ansonsten im registry-handler "wl_seat" binden (seat = wl_registry_bind(registry, name, &wl_seat_interface, 1);), und dann

1
    if (seat) {
2
        struct wl_keyboard *keyboard = wl_seat_get_keyboard(seat);
3
        wl_keyboard_add_listener(keyboard, &keyboard_listener, NULL);
4
    }
#8106964
Lesenswert?
• ▲
▼

Hab das mal alles zusammen in eine KI geworfen.

vielleicht kannst du dir was abschauen.

in's compile.sh von oben:

1
gcc -g -o pong pong.c xdg-shell-protocol.c -l wayland-client -lm

die "poll()"-Loop ist vmtl. nicht zwingend nötig, aber praktisch wenn du weitere FDs (Netzwerk-Socket z.B) mit überwachen willst.

Angehängte Dateien:

Antwort schreiben

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.