So verschieben Sie ein rotes Rechteck mit der Maus im Linux-Zeichenterminal

So verschieben Sie ein rotes Rechteck mit der Maus im Linux-Zeichenterminal

Alles ist eine Datei! UNIX hat es bereits gesagt. Das hat Eric Raymond gesagt, stimmen Sie nicht zu?

Da /dev/fb0 in eine Anzeige abstrahiert wurde, können wir 32-Bit-Echtfarbbilder auf dem Bildschirm zeichnen, indem wir den auf /dev/fb0 abgebildeten Speicher auf dem Zeichenterminal bedienen. Wie bedienen wir also Maus und Tastatur?

/dev/input/mouse0 kann zum Lesen von Mausereignissen verwendet werden. Wenn Sie es in einem Zeichenterminal eingeben und die Maus bewegen, scheint es Ihnen mitzuteilen, dass etwas passiert ist, aber Sie können es nicht interpretieren:


Um die richtige Interpretation zu finden, können Sie entweder Google oder Baidu verwenden. Der direkteste Weg besteht darin, die Lese-Callback-Funktion der Datei mouse0 im Quellcode des Linux-Kernels zu überprüfen:

static ssize_t mousedev_read(Struktur Datei *Datei, char __user *Puffer,
     size_t Anzahl, loff_t *ppos)
{
 Struktur mousedev_client *client = Datei->private_Daten;
 Struktur mousedev *mousedev = Client->mousedev;
 // Die Größe von ps2 in der mousedev_client-Struktur beträgt 6 Bytes.
 signierte Zeichendaten [Größe von (Client-> PS2)];
 int retval = 0;

 spin_lock_irq(&client->paketsperre);

 wenn (!client->Puffer && Client->bereit) {
  // Dies ist der Kern, folgen Sie weiterhin mousedev_packet(client, client->ps2);
  Client->Puffer = Client->Bufsiz;
 }
 ...

Sehen wir uns an, wie mousedev_packet das Paket zusammenstellt:

statisches void mousedev_packet(Struktur mousedev_client *client,
    signiertes Zeichen *ps2_data)
{
 Struktur mousedev_motion *p = &client->packets[client->tail];

 ps2_data[0] = 0x08 |
  ((p->dx < 0) << 4) | ((p->dy < 0) << 5) | (p->buttons & 0x07);
 ps2_data[1] = mousedev_limit_delta(p->dx, 127);
 ps2_data[2] = mousedev_limit_delta(p->dy, 127);
 p->dx -= ps2_data[1];
 p->dy -= ps2_data[2];
...

Ich verstehe es sehr gut. Alles andere interessiert mich nicht und ich habe keine Motivation, es zu lernen. Ich möchte nur die X- und Y-Koordinaten der Maus wissen:

  • p->dx, p->dy Wie aus dem Namen und dem Code ersichtlich ist, handelt es sich hierbei um die Änderung der Koordinaten relativ zur vorherigen!

Alle Informationen sind dort.

Jetzt können wir den Code schreiben:

#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <stdlib.h>

// Die Seitenlänge des Quadrats beträgt 100 Pixel #define LENGTH 100

//Abstrakter Anzeigespeicher unsigned int *mem = NULL;
// Letzten Bildschirm speichern unsigned int *old_mem = NULL;
//Bildschirminformationen statische Struktur fb_var_screeninfo info;
Int Maus_fd, fb_fd;

// Das Quadrat rot anmalen int start = 0xffff0000;

int main(int argc, char **argv)
{
 signiertes Zeichen mouse_event[6];
 Zeichen rel_x, rel_y;
 int alt_x = 0, alt_y = 0;
 int abs_x = 0, abs_y = 0;

 mouse_fd = öffnen("/dev/input/mouse0", O_RDONLY);
 fb_fd = öffnen("/dev/fb0", O_RDWR);

 ioctl(fb_fd, FBIOGET_VSCREENINFO, &info);

 mem = (unsigned int *)mmap(NULL, info.xres*info.yres*info.bits_per_pixel/8, PROT_READ|PROT_WRITE, MAP_SHARED, fb_fd, 0);

 während(lesen(Maus_fd, &Maus_Ereignis[0], 6)) {
 int i, w, h;
 statische int idx = 0;

 // Analysieren Sie die relative Verschiebung gemäß der Definition des Kernel-Mousedev_packet.
 rel_x = (char) Mausereignis[1];
 rel_y = (char) Mausereignis[2];
 // Absolute Verschiebung berechnen abs_x += rel_x;
 abs_y -= rel_y;
 if (abs_x <= 0 || abs_x >= info.xres - LÄNGE || abs_y <= 0 || abs_y >= info.yres - LÄNGE) {
 weitermachen;
 }

 wenn (alter_Speicher == NULL) {
 alter_speicher = (unsigned int *)mmap(NULL, info.xres*info.yres*info.bits_per_pixel/8, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
 wenn (alter_Speicher == NULL) {
 Ausgang (1);
 }
 } anders {
 // Stelle die Pixel im letzten quadratischen Bereich wieder her für (w = old_x; w < old_x + LENGTH; w++) {
 für (h = alt_y; h < alt_y + LÄNGE; h++) {
  idx = h*info.xres + w;
  mem[idx] = alter_mem[idx];
 }
 }
 alt_x = abs_x;
 alt_y = abs_y;
 }

 // Speichere das aktuelle Pixel für die nächste Wiederherstellung for (w = abs_x; w < abs_x + LENGTH; w++) {
 für (h = abs_y; h < abs_y + LÄNGE; h++) {
 idx = h*info.xres + w;
 alter_Speicher[idx] = Speicher[idx];
 }
 }

 // Male das rote Rechteck entsprechend der Mausposition for (w = abs_x; w < abs_x + LENGTH; w++) {
 für (h = abs_y; h < abs_y + LÄNGE; h++) {
 idx = h*info.xres + w;
 mem[idx] = Anfang;
 }
 }
 }

 gebe 0 zurück;
}

Führen Sie es aus und bewegen Sie dann die Maus im Zeichenterminal. Der Effekt ist wie folgt:

Nun, das Rechteck bewegt sich mit der Maus und zerstört keine Zeichen, egal, wo es hingeht.

Lassen Sie mich nun noch einmal zusammenfassen, was ich dieses Wochenende gemacht habe und was es bedeutet.

  • Ich kann 32-Bit-Echtfarbbilder auf einem Zeichenterminal zeichnen;
  • Ich kann Maus- und Tastaturereignisse erkennen und darauf reagieren.

Das bedeutet, dass ich ein GUI-System implementieren kann, wenn ich die Zeit und Energie dazu habe.

Natürlich liegen zwischen dem GUI-System und dem Netzwerkprotokollstapel Berge und es wird definitiv eine Menge Probleme geben, nicht nur beim Lesen und Schreiben von zwei Dateien:

  • /Entwickler/fb0
  • /dev/Eingabe/Maus0

Es ist möglich.

Tatsächlich wird dieser Ansatz in echten GUI-Systemen nie verwendet. Sie scheinen sich gegen die UNIX-Philosophie aufzulehnen, bei der alles eine Datei ist, und beweisen, dass das besser ist! Oh, und der Erfolg der Windows-Benutzeroberfläche ist ein Beweis dafür, ebenso wie die neueste Version von MacOS …

Bei den Zeichenterminals werden die Zeichen ebenfalls gezeichnet. Es ist keine große Sache. Wenn Sie jedoch Pixel zum Festlegen von Zeichen verwenden möchten, müssen Sie die Informationen der Zeichenpunktmatrix verstehen ... Dies ist ein anderes Thema in einem anderen Bereich.

Zusammenfassen

Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Lernwert für Ihr Studium oder Ihre Arbeit hat. Vielen Dank für Ihre Unterstützung von 123WORDPRESS.COM.

Das könnte Sie auch interessieren:
  • So ändern Sie Schriftarten im Linux-Systemterminal
  • Detaillierte Erklärung häufig verwendeter Tastenkombinationen für die Linux-Terminal-Befehlszeile
  • Zwei Methoden für den geteilten Terminalbildschirm unter Linux (Screen und tmux)
  • Tutorial zur Linux Shell Script-Reihe (Teil 2): ​​Detaillierte Erklärung der Terminal-Druckbefehle
  • Einfache Möglichkeit, Python im Linux-Befehlszeilenterminal zu verwenden (empfohlen)
  • So beenden Sie die Python-Befehlszeile im Linux-Terminal
  • Die perfekte Lösung für Terminal-Zeichenverfälschungen im Linux-Betriebssystem
  • Selbst gemachtes Tool zum Sperren des Linux-Terminalbildschirms
  • So zeigen Sie Sternchen an, wenn Sie unter Linux ein Passwort im Terminal eingeben

<<:  Tiefgreifendes Verständnis von Worker-Threads in Node.js

>>:  Installieren und konfigurieren Sie MySQL 5.7 unter CentOS 7

Artikel empfehlen

Mysql-Datumsformatierung und komplexe Datumsbereichsabfrage

Inhaltsverzeichnis Vorwort Anwendungsszenarios fü...

So verwenden Sie Vue zum Implementieren von CSS-Übergängen und Animationen

Inhaltsverzeichnis 1. Der Unterschied zwischen Üb...

HTML implementiert problemlos abgerundete Rechtecke

Frage: Wie erreiche ich mit Div+CSS und Positioni...

JS berechnet die Gewinnwahrscheinlichkeit basierend auf dem Preisgewicht

Inhaltsverzeichnis 1. Beispielszenario 1.1. Legen...

Zusammenfassung zur Verwendung des MySQL-Autorisierungsbefehls „grant“

So verwenden Sie den MySQL-Autorisierungsbefehl „...

Fallanalyse mehrerer MySQL-Aktualisierungsvorgänge

Inhaltsverzeichnis Fallstudie Kontostand aktualis...

Beispiele für JavaScript-Entschüttelungen und Drosselung

Inhaltsverzeichnis Stabilisierung Drosselung: Ant...

So ändern Sie das Root-Passwort von MySQL unter Linux

Vorwort Der Dienst wird seit mehreren Monaten auf...

Zusammenfassung der Verwendung von vue Watch und Computed

Inhaltsverzeichnis 01. Hörer beobachten (1) Funkt...

Tiefgreifendes Verständnis des Vue-Übergangs und der Animation

1. Wenn Sie DOM-Elemente einfügen, aktualisieren ...