MacOS-Umgebung – Handschrift des Betriebssystems – 39-Caps-Tastenantwort

Caps Schlüsselantwort

1. Einleitung

Im vorherigen Abschnitt haben wir die Verarbeitung der Umschalttaste erfolgreich implementiert

In diesem Abschnitt schauen wir uns den Umgang mit Großbuchstaben an

Wenn diese Taste gedrückt wird, wechseln die in das System eingegebenen Zeichen zwischen Groß- und Kleinschreibung.

Da die Standardeingabe nach dem Start unseres Systems Großbuchstaben sind

Nach Abschluss dieses Abschnitts ändern wir die Standardzeichen des Systems in Kleinbuchstaben

Drücken Sie die Feststelltaste, um die Systemzeichen automatisch auf Großbuchstaben umzustellen.

Wenn die Feststelltaste gedrückt wird, lautet der von der Tastatur an das System gesendete Scancode 0x3a.

Wenn die Taste angezeigt wird, lautet der von der Tastatur gesendete Unterbrechungscode 0xba

Daher ist das entsprechende Schlüsselereignis caps

Verarbeiten Sie einfach die beiden vom Tastatur-Interrupt gesendeten Werte entsprechend.

2.Code

Unsere aktuelle Logik zur Verteilung von Tastaturereignissen lautet wie folgt

Der Hauptprozess, der CMain ausführt, wird jedes Mal aktiviert, wenn ein Schlüsselereignis auftritt.

Bei diesem Vorgang wird der Scancode oder Breakcode der Taste aus der Datenwarteschlange der Tastatur entnommen und anschließend beurteilt

Liegt der aktuelle Eingabefokus auf dem Texteingabefeld, werden die entsprechenden Zeichen der Taste im Textfeld angezeigt.

Wenn der Eingabefokus auf der Befehlszeilenkonsole liegt, stellt der Hauptprozess den Tastaturscancode in die Eingabewarteschlange des Konsolenprozesses.

Dann suspendieren Sie sich und übergeben Sie die Kontrolle über die CPU an den Konsolenprozess

Tatsächlich müssen nicht alle Scancodes der Tasten an den Konsolenprozess übergeben werden. Für einige Sondertasten wie Umschalttaste, Großbuchstaben usw.

Der Hauptprozess kann diese Tastenanschläge selbst verarbeiten und es besteht keine Notwendigkeit, sie an den Befehlszeilenkonsolenprozess zu übergeben.

Deshalb fügen wir eine Funktion hinzu, um zu bestimmen, ob es sich bei dem Schlüssel um einen Sonderschlüssel handelt

int isSpecialKey(int data) {
    transferScanCode(data);

    if (data == 0x3a || data == 0xba || data == 0x2a || data == 0x36
       || data == 0xaa || data == 0xb6) {
        return 1;
    }

    return 0;
}

Wenn der von der Tastatur gesendete Wert dem Scancode oder Breakcode der Umschalttaste entspricht (0x2a, 0x36, 0xaa, 0xb6)

Oder der Scancode oder Breakcode der Caps-Taste (0x3a, 0xa), dann gibt die Funktion 1 zurück

Es stellt sich heraus, dass es ein Problem mit der Verteilung unserer Tastenanschlagsdaten gibt.

Wenn eine Taste gedrückt wird, wird der Tastatur-Interrupt aufgerufen. Der Tastatur-Interrupt sendet den Scan-Code der Taste an die Daten-Cache-Warteschlange der Tastatur.

Sobald Daten in die Datenwarteschlange der Tastatur eingehen, wird der Hauptprozess aktiviert

Der Hauptprozess ruft die Tastaturdaten aus den Daten ab und bestimmt dann, ob der aktuelle Eingabefokus im Fenster eines anderen Prozesses liegt.

Wenn der Eingabefokus auf der Befehlszeilenkonsole liegt, leitet der Hauptprozess die aus der Warteschlange erhaltenen Tastaturdaten an die Prozesswarteschlange des Befehlszeilenfensters weiter.

dann hänge dich auf

Das Problem ist

Durch Drücken der Taste werden zwei Daten generiert

Einer ist der Scan-Code, der ausgegeben wird, wenn die Schaltfläche gedrückt wird, und der andere ist der Unterbrechungscode, der ausgegeben wird, nachdem die Schaltfläche angezeigt wird.

Daher müssen Sie bei der Verarbeitung eines Schlüsselereignisses gleichzeitig den Scancode und den Breakcode verarbeiten.

Der obige Mechanismus bewirkt jedoch, dass, sobald die Taste gedrückt wird,

Der Hauptprozess hat nur den Scancode an den Zielprozess gesendet und dann aufgelegt. Der Code wurde nicht gesendet.

Sie müssen warten, bis der nächste Tastendruck erfolgt, bevor Sie den Unterbrechungscode des letzten Tastendrucks an den Zielprozess senden.

Daher kann es leicht dazu kommen, dass der Zielprozess die Tastaturdaten falsch interpretiert.

Wenn Sie versuchen, das System auszuführen und den Eingabefokus auf die Befehlszeile zu verlagern

Klicken Sie dann auf die Feststelltaste und dann auf die anderen Schaltflächen

Sie werden feststellen, dass Zeichen nicht korrekt angezeigt werden können. Dieses Phänomen wird durch das oben beschriebene Problem verursacht.

Konzentrieren Sie als Nächstes die gesamte Schlüsselverarbeitung in einer Funktion

char  transferScanCode(int data) {
    if (data == 0x2a)  {//left shift key down
        key_shift |= 1;
    }

    if (data == 0x36) {
        //right shift key down 
        key_shift |= 2; 
    }

    if (data == 0xaa) {
        //left shift key up
        key_shift &= ~1;
    }

    if (data == 0xb6) {
       //right shift key up
        key_shift &= ~2;
    }

    //caps lock
    if (data == 0x3a) {
        if (caps_lock == 0) {
            caps_lock = 1;
        } else {
            caps_lock = 0;
        }
    }

    if (data == 0x2a || data == 0x36 || data == 0xaa || data == 0xb6 || 
        data >= 0x54 || data == 0x3a ) {
        return 0;
    }

    char c = 0;

    if (key_shift == 0 && data<0x54 && keytable[data] != 0) {
        c = keytable[data];
        if ('A' <= c && c <= 'Z' && caps_lock == 0) {
            c += 0x20;
        }

    } 
    else if (key_shift != 0 && data < 0x80 && keytable1[data] != 0){
        c = keytable1[data];
    }
    else  {
        c = 0;
    }

    return c;
}

Wenn die Feststelltaste nicht gedrückt wurde, wandeln wir die Zeichen zunächst in Kleinbuchstaben um und geben sie dann an den Fensterprozess zurück

Wenn gedrückt, geben Sie den Großbuchstaben direkt an den Fensterprozess zurück.

Daher kann das Fenster diese Funktion direkt vor der Anzeige von Zeichen aufrufen.

void CMain(void) {
    ...
    for(;;) {
    ....
    else if (key_to == 0) {
               if (transferScanCode(data) != 0 && cursor_x < 144) {
                   boxfill8(shtMsgBox->buf, shtMsgBox->bxsize, COL8_FFFFFF,cursor_x,
                   28, cursor_x + 7, 43);
                   sheet_refresh(shtctl, shtMsgBox, cursor_x, 28, cursor_x+8, 44);
                   char c = transferScanCode(data);
                   char buf[2] = {c, 0};
                   showString(shtctl,  shtMsgBox, cursor_x, 28, COL8_000000, buf);
                   cursor_x += 8;

                   stop_task_A = 1;

                   boxfill8(shtMsgBox->buf, shtMsgBox->bxsize, cursor_c, cursor_x,
                  28, cursor_x + 7, 43);
                  sheet_refresh(shtctl, shtMsgBox, cursor_x, 28, cursor_x+8, 44);
              } 
           } else if (isSpecialKey(data) == 0)  {

                 fifo8_put(&task_cons->fifo, data);
                 if (fifo8_status(&keyinfo) == 0) {             
                     task_sleep(task_a);
                 }
           }

       }
    ....
    }
    ...
}

Die Logik des obigen Codes besteht darin, dass der Hauptprozess die Tastaturdaten abruft

Bestimmen Sie das aktuelle Eingabewinkelfenster. Wenn das Eingabefenster eine Befehlszeilenkonsole ist, bestimmen Sie, ob die aktuelle Taste ein Sonderzeichen ist.

Wenn ja, besteht keine Notwendigkeit zur Verteilung

Wenn nicht, verteilen Sie alle Tastenanschlagsdaten in der Warteschlange, also den Scancode und den Breakcode, an den Prozess des Zielfensters und halten Sie sich dann selbst an.

Dadurch können wir die zuvor genannten Probleme verhindern

Zeichenanzeige im Befehlszeilen-Konsolenfenster

Sie müssen außerdem transferScanCode aufrufen, um die anzuzeigenden Zeichen zu erhalten

Der Code wird wie folgt geändert

void console_task(struct SHEET *sheet) {
....
    for(;;) {
    ....
    else {
             char c = transferScanCode(i);
             if (cursor_x < 240 && c!=0 ) {
                 boxfill8(sheet->buf, sheet->bxsize, 
                           COL8_000000, cursor_x,
                           28, cursor_x + 7, 43);
                 sheet_refresh(shtctl, sheet, cursor_x, 28, 
                 cursor_x+8, 44);

                 char s[2] = {c, 0};
                 showString(shtctl, sheet, cursor_x, 28, 
                 COL8_FFFFFF, s);
                 cursor_x += 8;
        }
    ....
    }
....
}

Nach dem Kompilieren des obigen Codes kann das System die Groß-/Kleinschreibung wechseln.

Wenn Sie den obigen Code ausführen und auf die Feststelltaste klicken, können Groß- und Kleinschreibung tatsächlich normal vertauscht werden.

Es gibt jedoch ein Problem: Nach dem Klicken auf die Feststelltaste leuchtet die Kontrollleuchte daneben nicht auf.

Wenn die Anzeigelampe aufleuchten soll, muss das System Daten auf den Tastaturanschluss schreiben.

Dazu ist viel Code erforderlich, um die Komplexität des Codes so weit wie möglich zu reduzieren.

Das ist mir noch nicht aufgefallen. Interessierte Studierende können es selbst ausprobieren.

3. Kompilieren und ausführen

Fügen Sie hier eine Bildbeschreibung ein

Supongo que te gusta

Origin blog.csdn.net/w776341482/article/details/128660752
Recomendado
Clasificación