Deutsches Tastaturlayout
-
Boah ey, ich glaub, das ist zu schwer...
Nicht aufgeben. Es besteht kein Zeitdruck und wir haben ausreichend Expertise im Team.
Ich werde mir die neuen Key Maps anschauen. Ist doch ein interessantes Thema, vor allem auch eine wichtige Schnittstelle. Tyndur hat deutsch hardverdrahtet, soweit ich weiß.
-
tyndur hat die deutsche Tastaturbelegung als Default, man kann aber zur Laufzeit zu beliebigen anderen Tastaturbelegungen wechseln (eine Datei für US-Layout ist dabei, andere müsste man erstmal anlegen).
-
Danke für die korrekte Darstellung, habe das falsch aufgeschnappt. Da können wir sicher von euch "Honig saugen".
Hier findet man ebenfalls das Thema Keyboard beschrieben:
http://www.brokenthorn.com/Resources/OSDev19.html
-
Habe es getestet, spricht noch kein "deutsch", nur qwertz bzw. QWERTZ.
-
Cuervo schrieb:
Problem:
Nur das wichtigste geht (also Fragezeichen und Z mit Y vertauscht)Das mag daran liegen, daß die "program.c" nicht neu kompiliert wurde. Dort ist noch ein "Filter" eingebaut:
// program.c ver 110: // if ( // (input==32) || // space key // (input==45) || // "-" key // (input==63) || // "?" key // ((input>=65)&&(input<=90)) || // capital letters // ((input>=97)&&(input<=122)) || // little letters // ((input>=48)&&(input<=57)) // 0 ... 9 // ) if ((input >= 0x20) && (input <= 0x7E))
Ansonsten läuft es perfekt:
$> rm -rf / <-- Sorry, I do not know this command. $> _:;,.&#'(§$)# !!!111elf <-- Sorry, I do not know this command.
-
Danke für diesen Hinweis! Wir verwenden die shell (program.elf) aus dem User-Space zum Testen. Directory: ...\Source\user\user_program_c\..
program.elf wird dann nach ...\Source\user\init_rd_img\.. kopiert und in initrd.dat eingebunden.
Diese Datei kopiert man nach ...\Source\kernel\..
Auf diese Weise wird program.elf dann mittels incbin "initrd.dat" (im Assembler-Programm data.asm) im ELF-Format in den Kernel eingebunden.
In ckernel.c wird diese Datei ausgelesen und im User Mode gestartet.
-
äöüß ° § ' < > gehen noch nicht, und natürlich die AltGr. Sieht aber schon gut aus.
-
Das ist jetzt eine unangenehme Sache:
ü == 0x81 ä == 0x84 ö == 0x94
Als (signed) "char" sind sie kleiner 0. (Ev. Datentyp ändern). Nun muß man sehen, wo sie überall versehentlich "weggefiltert" werden, z.B.:
if ((input >= 0x20) && (input <= 0x7E)) // :open_mouth:
Aber nachsehen kann man auch morgen noch.
-
@ +gjm+ : Danke für die Unterstützung! Der Tipp mit der "shell" war wichtig.
Weiß nicht mehr genau, warum ich da alles dicht gemacht habe, da gab's bestimmt "Störenfriede".
-
Abgesehen von der "program.c" gibt es nur noch in der "video.c" einen "Filter", der beseitigt werden sollte:
// video.c (version 111) void putch(int8_t c) // else if(c >= ' ') // Läßt nur 0x20 bis 0x7F durch. else if(c != 0) // Falls c == 0 gerät putch seltsamerweise in eine Endlosschleife! // *pos = c | att; *pos = ((uint8_t) c) | att; // Vielleicht kennt jemand einen schöneren Cast hier weil Bit-Operationen // mit 'signed' meistens nicht das erwartete Ergebnis bringen. // Die Umlaute werden sonst z.B. mit 'falschen' Attributen angezeigt.
Nun sollte der "keyboard_GER.h" nichts mehr im Wege stehen.
Bis auf eine Kleinigkeit: Die Taste links vom "y" (<>|) hat bei mir den Scancode 0x56.
-
Danke für das Aufspüren dieser Stellen! Allerdings hat sich nun noch nichts geändert. Nun muss man wieder in den Tastaturtreiber und die Keymaps einsteigen.
Die Taste links vom "y" (<>|) hat bei mir den Scancode 0x56
Ja, das ist eine Taste, die aus der Reihe tanzt. Da hatten wir noch Nullen in der Keymap. Jetzt klappt das wie folgt:
... KDEL, 0, 0, '<', KF11 ... ... KDEL, 0, 0, '>', KF11 ...
US-Keyboard-Layout: http://www.conjective.ch/kbdus/keymap.pdf
Scancodes: http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html#ss1.4
ASCII/ANSI-Tabellen: http://www.torsten-horn.de/techdocs/ascii.htm
Codepage 437: http://lowlevel.brainsware.org/wiki/index.php/Codepage_437 (äöüߧ kommen nicht als solche raus, da muss in putch(...) noch umgewandelt werden)Den Scancode kann man selbst mittels eines zusätzlichen printformat(...) in keyboard.c leicht verfolgen:
uint8_t ScanToASCII() { uint8_t retchar; // The character that returns the scan code to ASCII code scan = FetchAndAnalyzeScancode(); // Grab scancode, and get the position of the shift key /// TEST printformat(" scan:%d ",scan); // <--------- hier! /// TEST if( ShiftKeyDown ) retchar = asciiShift[scan]; // (Upper) Shift Codes else retchar = asciiNonShift[scan]; // (Lower) Non-Shift Codes if( ( !(scan == KRLEFT_SHIFT || scan == KRRIGHT_SHIFT) ) && ( KeyPressed == 1 ) ) //filter Shift Key and Key Release return retchar; // ASCII version else return 0; }
-
Geschafft! äöüß°§ <--- alles geht!
Problem: In der userlib.h/c musste getchar() und putch() umgebaut werden von char auf unsigned char, damit die Werte >127 sauber durch kamen.
-
Die Abfolge der Umwandlungen ist:
Keyboard-Input ==> Scancode (Taste) + Shift(Non-Shift) ==> ASCII ==> Codepage437 ==> Monitor-Output
Damit printformat("äöüߧ°ÄÖÜ") sauber auf dem Monitor ankommt, müssen die keymaps in ASCII geführt werden. Die Umwandlung nach codepage437 darf erst in putch(...) erfolgen. Ich habe dafür in video.c eine Funktion transferFromAsciiToCodepage437(...) eingeführt. Provisorischer Inhalt:
static uint8_t transferFromAsciiToCodepage437(uint8_t ascii) { uint8_t c; if ( ascii == 0xE4 ) c = 0x84; // ä else if ( ascii == 0xF6 ) c = 0x94; // ö else if ( ascii == 0xFC ) c = 0x81; // ü else if ( ascii == 0xDF ) c = 0xE1; // ß else if ( ascii == 0xA7 ) c = 0x15; // § else if ( ascii == 0xB0 ) c = 0xF8; // ° else if ( ascii == 0xC4 ) c = 0x8E; // Ä else if ( ascii == 0xD6 ) c = 0x99; // Ö else if ( ascii == 0xDC ) c = 0x9A; // Ü else { c = ascii; } // to be checked for more deviations return c; }
In putch(...):
void putch(int8_t c) { uint8_t uc = transferFromAsciiToCodepage437((uint8_t)c); // no negative values
Nun funktioniert die deutsche Tastatur sehr gut. Es fehlen nun nur noch die Verarbeitung von AltGr+Taste etc. im Keyboard-Treiber.
Wer das mit prüfen möchte:
http://www.henkessoft.de/OS_Dev/Downloads/111a.zip
(Ich habe diese Version noch nicht nach SVN geschoben, da die shell noch überarbeitet werden muss)
-
Gute Arbeit! Bringt richtig Spaß zu testen. Folgendes könnte noch geändert werden:
//-------------------------------------------- // program.c (version 111a) // if(i<0xFF) // test-wise open if(i<70) // sonst kann entry[80] überlaufen //-------------------------------------------- // keyboard_GER.h (version 111a) static unsigned char asciiNonShift[] = { // ... '0', 0xDF, '´', BACKSPACE, ... '0', 0xDF, '\'', BACKSPACE, // Der Editor setzt für '´' einen falschen Wert.
"AltGr" generiert auf "Druck" zwei Scancodes (0x60+0x38). Wenn man jetzt in der FetchAndAnalyzeScancode "AltGr" abfangen will, müsste man sich den letzten Scancode ständig merken:
// Pseudocode if (inportb(0x64)&1 ) cur_scan = inportb(0x60); // 0x60: get scan code from the keyboard if (cur_scan == 0x38) { if (prv_scan == 0x60) { AltGrDown = 1; // dann AltGr gedrückt oder losgelassen :confused: }} prv_scan = cur_scan;
Außerdem braucht sie dann in der ScanToASCII ihr eigenes "asciiAltGr[]"-Array. Möglicherweise kennt jemand eine elegantere Lösung?
-
Gute Arbeit! Bringt richtig Spaß zu testen.
Danke für das positive Feedback und für deine konstruktiven Anmerkungen. Das motiviert.
// if(i<0xFF) // test-wise open if(i<70) // sonst kann entry[80] überlaufen
Klar! Das war ein Versehen, wird demnächst berichtigt. Befehlszeilen von nahezu einer Zeile reichen zur Zeit völlig aus.
static unsigned char asciiNonShift[] = { // ... '0', 0xDF, '´', BACKSPACE, ... '0', 0xDF, '\'', BACKSPACE, // Der Editor setzt für '´' einen falschen Wert.
Der Akzent führt ja zu einem Zeichen mit Akzent, also einem veränderten Zeichen. Das ist also eine Kombination aus zwei Scancodes, die zu einem dritten führen. So drücke ich zunächst auf die Akzent-Taste, dann auf y, wenn ich týndur schreibe, daraus ergibt sich dann das Zeichen ý. Schreibe ich aber "týndur´s Bedeutung", so ist der von die angesprochene Apostroph anstelle des Akzentes das bessere Zeichen: "týndur's Bedeutung", Das könnte man z.B. sofort korrigieren. Nicht ganz einfaches Thema.
Bezüglich AltGr habe ich bisher noch kein separates Keymap gesehen, aber warum nicht, ist ja weitgehend identisch. Codepage437 hat aber kein Euro-Zeichen.
-
Erhard Henkes schrieb:
So drücke ich zunächst auf die Akzent-Taste, dann auf y, wenn ich týndur schreibe, daraus ergibt sich dann das Zeichen ý. Schreibe ich aber "týndur´s Bedeutung", so ist der von die angesprochene Apostroph anstelle des Akzentes das bessere Zeichen: "týndur's Bedeutung", Das könnte man z.B. sofort korrigieren. Nicht ganz einfaches Thema.
Abgesehen davon das man im Deutschen kein ' benutzt (da heißt es týndurs) halte ich ´s für falsch.
Ansonsten gibt es soweit ich weiß keinen Standard für Keymaps und daher ist es bei Windows und Linux (getestet mit Ubuntu und deutsche standard keymap) unterschiedlich.
Eingabe: Verhalten unter Windows | Verhalten unter Linux ´ + unpassender Buchstabe: ´Buchstabe | nix (weder ´noch der Buchstabe) ´ + Leertaste: ´ | ' ´ + s: ´s | s mit ´ drüber
Ansonsten gibt es in codepage 437 das ´ ohne shift nicht einzelnd. Nur das mit shift.
-
Danke für diese Aufstellung.
-
AltGr wurde nun auch implementiert.
keyboard_GER.h
static unsigned char asciiAltGr[] = { 0, 0, 0, 0xB2, 0xB3, 0, 0, 0, 0x7B, 0x5B, 0x5D, 0x7D, 0x5C, 0, 0, /* ²³ {[]}\ */ 0, 0x40, 0, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0x7E, 0, 0, /* @ € ~ */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xB5, 0, 0, 0, 0, 0, 0, 0, 0, /* µ */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x7C, 0, 0 }; /* | */
keyboard.c
uint8_t FetchAndAnalyzeScancode() { if( inportb(0x64)&1 ) curScan = inportb(0x60); // 0x60: get scan code from the keyboard // ACK: toggle bit 7 at port 0x61 uint8_t port_value = inportb(0x61); outportb(0x61,port_value | 0x80); // 0->1 outportb(0x61,port_value &~ 0x80); // 1->0 if( curScan & 0x80 ) // Key released? Check bit 7 (10000000b = 0x80) of scan code for this { KeyPressed = 0; curScan &= 0x7F; // Key was released, compare only low seven bits: 01111111b = 0x7F if( curScan == KRLEFT_SHIFT || curScan == KRRIGHT_SHIFT ) // A key was released, shift key up? { ShiftKeyDown = 0; // yes, it is up --> NonShift } if( (curScan == 0x38) && (prevScan == 0x60) ) { AltGrKeyDown = 0; } } else // Key was pressed { KeyPressed = 1; if( curScan == KRLEFT_SHIFT || curScan == KRRIGHT_SHIFT ) { ShiftKeyDown = 1; // It is down, use asciiShift characters } if( (curScan == 0x38) && (prevScan == 0x60) ) { AltGrKeyDown = 1; } } prevScan = curScan; return curScan; } uint8_t ScanToASCII() { uint8_t retchar = 0; // The character that returns the scan code to ASCII code curScan = FetchAndAnalyzeScancode(); // Grab scancode, and get the position of the shift key /// TEST // printformat(" scan:%d ",scan); /// TEST if( ShiftKeyDown ) { if( AltGrKeyDown) { /* no reaction */ } else { retchar = asciiShift[curScan]; } } else { if( AltGrKeyDown) { #ifdef KEYMAP_GER retchar = asciiAltGr[curScan]; #endif #ifdef KEYMAP_US /// not yet implemented #endif } else { retchar = asciiNonShift[curScan]; // (Lower) Non-Shift Codes } } //filter Shift Key and Key Release if( ( !(curScan == KRLEFT_SHIFT || curScan == KRRIGHT_SHIFT) ) && ( KeyPressed == 1 ) ) { /// TEST // printformat("ascii:%x ", retchar); /// TEST return retchar; // ASCII version } else { return 0; } }
Die hochgestellte 3 geht nicht in codepage437. Für das Euro-Zeichen wurde einfach das griechische Epsilon verwendet. Alles andere funktioniert bei der deutschen Tastatur nun problemlos. Die AltGr bei der US-Tastatur ist noch nicht eingebaut.
Der Transfer von ASCII nach codepage437 wurde nun erweitert:
video.c
static uint8_t transferFromAsciiToCodepage437(uint8_t ascii) { uint8_t c; if ( ascii == 0xE4 ) c = 0x84; // ä else if ( ascii == 0xF6 ) c = 0x94; // ö else if ( ascii == 0xFC ) c = 0x81; // ü else if ( ascii == 0xDF ) c = 0xE1; // ß else if ( ascii == 0xA7 ) c = 0x15; // § else if ( ascii == 0xB0 ) c = 0xF8; // ° else if ( ascii == 0xC4 ) c = 0x8E; // Ä else if ( ascii == 0xD6 ) c = 0x99; // Ö else if ( ascii == 0xDC ) c = 0x9A; // Ü else if ( ascii == 0xB2 ) c = 0xFD; // ² else if ( ascii == 0xB3 ) c = 0x00; // ³ <-- not available else if ( ascii == 0x80 ) c = 0xEE; // € <-- Greek epsilon used else if ( ascii == 0xB5 ) c = 0xE6; // µ else { c = ascii; } // to be checked for more deviations return c; }
Neueste Version wurde ins SVN überspielt: http://prettyos.svn.sourceforge.net/viewvc/prettyos.tar.gz?view=tar
-
Man könnte noch ein paar geheime AltGr als PrettyOS Feature unterbringen. Ideen?
Die Kombination Shift+AltGr ist auch noch völlig ungenutzt.Das ist darstellbar (Codepage 437): http://lowlevel.brainsware.org/wiki/index.php/Codepage_437
-
In der Emulation mit qemu auf MS Windows funktioniert die AltGr-Taste übrigens nicht, daher bitte in "echt" oder mit qemu auf Linux testen.