Taste AltGr benutzen

Antworten
HobbyProgrammer
Beiträge: 166
Registriert: Di 29. Okt 2019, 12:51
Wohnort: Deutschland , Baden-Württemberg

Taste AltGr benutzen

Beitrag von HobbyProgrammer »

Hallo zusammen,

bei meinem Projekt Z180SoftSystem gab es Probleme mit den Sonderzeichen '{[]}\' das diese von Linux auf Windows nicht richtig erkannt und umgesetzt wurden. Das habe ich nun gelöst. Unter Windows kann man diese Zeichen nun wie gehabt mit der 'ALTGR' Taste erreichen.
Unter Linux geht das aber nur mit 'STRG + ALT'. Hat da schon jemand eine Methode wie die Taste 'ALTGR' unter Linux auch so funktioniert wie unter Windows?

Mein Code sieht wie folgt aus:

Code: Alles auswählen

procedure TSystemTerminal.getKeyBoardInput(key: word; shift: TShiftState);
var
    character: byte;
begin
    character := $00;
    if (Shift = []) then begin
        case key of
            08: character := $7F;
            09: character := key; // TAB
            13: character := key; // ENTER
            27: character := $1B; // ESC
            32: character := $20; // SPACE
            33: character := $12; // Ctrl R
            34: character := $03; // Ctrl C
            37: character := $13; // links
            38: character := $05; // oben
            39: character := $04; // rechts
            40: character := $18; // unten
            45: character := $16; // Einfg = Ctrl V
            46: character := $07; // Entf = Ctrl G
            48..57: character := key; // 0..9
            65..90: character := key + 32; // a..z
            187: character := $2B; // +
            188: character := $2C; // ,
            189: character := $2D; // -
            190: character := $2E; // .
            111: character := $3A; // NUM :
            106: character := $2A; // NUM *
            109: character := $2D; // NUM -
            107: character := $2B; // NUM +
            96..105: character := key - 48; // NUM 0..9
            {$ifdef Windows}
            110: character := $2E; // NUM .
            191: character := $23; // #
            219: character := $73; // s
            220: character := $5E; // ^
            221: character := $27; // `
            226: character := $3C; // <
            {$else}
            108: character := $2E; // NUM .
            222: character := $23; // #
            220: character := $73; // s
            150: character := $5E; // ^
            146: character := $27; // `
            225: character := $3C; // <
            {$endif}
            else character := $00;
        end;
    end;

    if ((Shift = [ssShift]) and (key <> 16)) then begin
        case key of
            00: character := key;
            48: character := $3D; // =
            49: character := $21; // !
            50: character := $22; // "
            51: character := $23; // §
            52: character := $24; // $
            53: character := $25; // %
            54: character := $26; // &
            55: character := $2F; // /
            56: character := $28; // (
            57: character := $29; // )
            65..90: character := key; // A..Z
            187: character := $2A; // *
            188: character := $3B; // ;
            189: character := $5F; // _
            190: character := $3A; // :
            {$ifdef Windows}
            191: character := $27; // '
            219: character := $3F; // ?
            220: character := $7E; // ° -> ~
            221: character := $60; // `
            226: character := $3E; // >
            {$else}
            222: character := $27; // '
            220: character := $3F; // ?
            150: character := $7E; // ° -> ~
            146: character := $60; // `
            225: character := $3E; // >
            {$endif}
            else character := $00;
        end;
    end;

    if ((Shift = [ssCtrl]) and (key <> 17)) then begin
        if (key > 64) and (key < 91) then begin
            character := key - 64;
        end;
    end;

    if ((Shift = [ssAlt..ssCtrl]) and (key <> 18)) then begin
        case key of
            48: character := $7D; // }
            55: character := $7B; // {
            56: character := $5B; // [
            57: character := $5D; // ]
            81: character := $40; // @
            187: character := $7E; // ~
            {$ifdef Windows}
            219: character := $5C; // \
            226: character := $7C; // |
            {$else}
            220: character := $5C; // \
            225: character := $7C; // |
            {$endif}
            else character := $00;
        end;
    end;

    if character > $00 then begin
        keyboardBuffer := keyboardBuffer + char(character);
        if (enableLocalEcho) then begin
            writeCharacter(character);
        end;
    end;
end;                              
Grüße

Hobbyprogrammer
Host: Core i7-12700H, NVIDIA RTX3050 6GB, 32GB Ram, 1TB NVME SSD mit KUbuntu 22.04LTS 64bit , VM KUbuntu 22.04 LTS 64bit mit Lazarus 2.2.6 und Cross-Platform Compiler für Linux 32/64bit und Windows 32/64bit. Wine für erste Tests der Windows Binarys.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Taste AltGr benutzen

Beitrag von Winni »

Hi!

xmodmap

heisst der magische Linux Befehl, mit der Du jeder Taste(nkombination) ein Zeichen zuweisen kannst.

Winni

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Taste AltGr benutzen

Beitrag von Mathias »

xmodmap
Ich habe danach gegoogelt, sieht nach einem Konsolenbefehl aus,
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

HobbyProgrammer
Beiträge: 166
Registriert: Di 29. Okt 2019, 12:51
Wohnort: Deutschland , Baden-Württemberg

Re: Taste AltGr benutzen

Beitrag von HobbyProgrammer »

Winni hat geschrieben:
So 28. Jun 2020, 15:50
xmodmap

heisst der magische Linux Befehl, mit der Du jeder Taste(nkombination) ein Zeichen zuweisen kannst.
Das stimmt schon, nur ist es nicht das was ich suche.
a) Müsste ja auf jedem Linux auf dem mein Programm laufen soll, das Tastaturmapping verbogen werden. Die Frage wäre dann auch angebracht ob sich das nicht negativ auf andere Anwendungen auswirkt.

b) Wenn man unter Linux z.b. in Kate schreibt, funktioniert die ALTGR Taste so wie sie soll. Auch beim Programmieren mit Lazarus unter Linux tut ALTGR was es soll. Weshalb soll dann irgendwas verbogen werden?

Ich suche nach einer Lösung im Code für mein Programm.
Host: Core i7-12700H, NVIDIA RTX3050 6GB, 32GB Ram, 1TB NVME SSD mit KUbuntu 22.04LTS 64bit , VM KUbuntu 22.04 LTS 64bit mit Lazarus 2.2.6 und Cross-Platform Compiler für Linux 32/64bit und Windows 32/64bit. Wine für erste Tests der Windows Binarys.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Taste AltGr benutzen

Beitrag von Winni »

Hi!

Okay - ich dachte Du wolltest am Keyboard -Mapping schrauben.

Also dann anders rum:

AltGr löst unter Linux - genau wie nur Alt - ssAlt im Shiftstate aus.
Unter Suse-Linux und da schon ewig und drei Tage.

Setz doch mal in der Form das KeyPreview auf true und häng das in KeyDown ein:

Code: Alles auswählen

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
 var sh:TShiftStateEnum;
    s,s1 : string;
begin
   for sh in shift do
   begin
   writeStr(s1,sh);
   s := s +' / '+s1;
   end;
   showMessage (s);
end;
Und dann sieh mal, was er Dir an SiftStates anzeigt.

Winni

HobbyProgrammer
Beiträge: 166
Registriert: Di 29. Okt 2019, 12:51
Wohnort: Deutschland , Baden-Württemberg

Re: Taste AltGr benutzen

Beitrag von HobbyProgrammer »

Ich habe die Werte 'key' und 'shift' schon die ganze Zeit beobachtet. Diese Werte lasse ich mir in 2 Labels anzeigen.
Als Beispiel hier die Kombination ALTGR+7 welche ja bekanntlich dann das Zeichen '{' erzeugt.

Unter Windows werden beim Drücken von 'ALTGR' zwei Events ausgeklöst:

Code: Alles auswählen

key:17 , shift:[SSCTRL]
key:18 , shift:[SSALT..SSCTRL]
dann die Taste '7'

Code: Alles auswählen

key:55 , shift:[]
allerdings bleibt der ShiftState

Code: Alles auswählen

shift:[SSALT..SSCTRL]
bestehen bis beide Tasten losgelassen werden.

Unter Linux wird beim Drücken von 'ALTGR' nur ein Event ausgelöst:

Code: Alles auswählen

key:235 , shift:[SSALT]
dann die Taste '7'

Code: Alles auswählen

key:55 , shift:[]
und mit Drücken der Taste '7' geht unter Linux der ShiftState auf

Code: Alles auswählen

shift:[]
zurück.
Host: Core i7-12700H, NVIDIA RTX3050 6GB, 32GB Ram, 1TB NVME SSD mit KUbuntu 22.04LTS 64bit , VM KUbuntu 22.04 LTS 64bit mit Lazarus 2.2.6 und Cross-Platform Compiler für Linux 32/64bit und Windows 32/64bit. Wine für erste Tests der Windows Binarys.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Taste AltGr benutzen

Beitrag von Winni »

Hallo!

Hab gerade mal Win7/64 gestartet und geguckt, was das bei mir ausspuckt.

Nun wird die Verwirrung noch größer:

Die Taste AltGr spuckt nur ssCtrl aus - kein ssAlt.
Versteh einer das Key-Mapping.

Verwirrt.

Winni

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Taste AltGr benutzen

Beitrag von Mathias »

Unter das gab es port[$60], mit dem konnte man pysikalich jede Taste einzeln abfrage, egal was für ein Treiber installiert war.

Mal zu CPM zurück, gibt es dort nicht auch keyb.com, wie unter dos ?

Mal etwas anderes, hatte ein CPM Rechner überhaupt eine Alt-Taste ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

HobbyProgrammer
Beiträge: 166
Registriert: Di 29. Okt 2019, 12:51
Wohnort: Deutschland , Baden-Württemberg

Re: Taste AltGr benutzen

Beitrag von HobbyProgrammer »

Winni hat geschrieben:
So 28. Jun 2020, 20:48
Hallo!

Hab gerade mal Win7/64 gestartet und geguckt, was das bei mir ausspuckt.

Nun wird die Verwirrung noch größer:

Die Taste AltGr spuckt nur ssCtrl aus - kein ssAlt.
Versteh einer das Key-Mapping.

Verwirrt.

Winni
Ich hab das ganze auch unter Win7/64bit gemacht. Die beiden Events sind im Debugger mit Breakpoint sehr gut zu sehen.
Host: Core i7-12700H, NVIDIA RTX3050 6GB, 32GB Ram, 1TB NVME SSD mit KUbuntu 22.04LTS 64bit , VM KUbuntu 22.04 LTS 64bit mit Lazarus 2.2.6 und Cross-Platform Compiler für Linux 32/64bit und Windows 32/64bit. Wine für erste Tests der Windows Binarys.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Taste AltGr benutzen

Beitrag von Winni »

@HobbyProgrammierer

Dann hast Du nen anderes Windows als ich.
Definitiv nur 1 keyboard event

@Matthias

Wenn ich mich recht entsinne ist die Alt Taste eine Erfindung des IBM-PC .
D .h. zu CP/M Zeiten gab's noch kein ALT.

Sieht man auch an den Wordstar-Shortcuts, später von Turbo Pascal übermommen:
Weit und breit kein Alt, aber CTRL voll belegt, teilweise sogar mit Doppelbuchstaben wie
CTRL K B oder CTRL K K.

Winni

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Taste AltGr benutzen

Beitrag von Mathias »

An TP mag ich mich noch erinnern, konnte man da nict mit Ctrl K P drucken ?

Zum Z80 Emulator zurück, wäre es da nicht besser direkt die Taste abzufragen, anstelle der Zeichen ?
So wie es Port $60 getan hat ?

Macht DOSBox meines wissens auch so.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Taste AltGr benutzen

Beitrag von Winni »

Hi!

Das Thema mit den Scan Codes wurde im internationalen Forum diskutiert.
Mit einem Windows Beispiel wie man sich einen Hook baut.

https://forum.lazarus.freepascal.org/in ... ic=40752.0

Und ja: CTRL K P liess den rostigen Nadeldrucker rattern ....

Winni

HobbyProgrammer
Beiträge: 166
Registriert: Di 29. Okt 2019, 12:51
Wohnort: Deutschland , Baden-Württemberg

Re: Taste AltGr benutzen

Beitrag von HobbyProgrammer »

Guten Morgen,

das damalige Tastaturen keine ALT oder ALTGR Taste hatten ist nicht der springende Punkt. Ich will einfach die Sonderzeichen welche auch unter CP/M z.b. zum Programmieren gebraucht werden, so eingeben können wie man es heute gewohnt ist, also z.b. das Zeichen '{' mit ALTGR+7, völlig unabhängig davon wie das damals auf den Tastaturen gelöst wurde. Und das unabhängig davon ob das Z180SoftSystem unter Windows oder Linux läuft.
Mir ist da mittlerweile auch eine Idee gekommen. Mal schauen ob ich die heute Nachmittag ausprobieren kann.
Host: Core i7-12700H, NVIDIA RTX3050 6GB, 32GB Ram, 1TB NVME SSD mit KUbuntu 22.04LTS 64bit , VM KUbuntu 22.04 LTS 64bit mit Lazarus 2.2.6 und Cross-Platform Compiler für Linux 32/64bit und Windows 32/64bit. Wine für erste Tests der Windows Binarys.

HobbyProgrammer
Beiträge: 166
Registriert: Di 29. Okt 2019, 12:51
Wohnort: Deutschland , Baden-Württemberg

Re: Taste AltGr benutzen

Beitrag von HobbyProgrammer »

Hallo,

ich habe nun meine Idee umgesetzt und sie funktioniert. Nun lassen sich die Sonderzeichen auch unter Linux mit 'ALTGR' erreichen. Der Workaround sitzt im MainWindow. Dort wird das OnFormKeyDown Event ausgewertet und die Daten dann an das SystemTerminal weitergereicht. In Verbindung mit dem OnFormKeyUp Event konnte ich dann die Funktion so programmieren wie ich mir das vorgestellt habe. Der Code sieht wie folgt aus:

Im SystemTerminal ist die Prozedur 'getKeyboardInput' gleich geblieben:

Code: Alles auswählen

// --------------------------------------------------------------------------------
procedure TSystemTerminal.getKeyBoardInput(key: word; shift: TShiftState);
var
    character: byte;
begin
    character := $00;
    if (Shift = []) then begin
        case key of
            08: character := $7F;
            09: character := key; // TAB
            13: character := key; // ENTER
            27: character := $1B; // ESC
            32: character := $20; // SPACE
            33: character := $12; // Ctrl R
            34: character := $03; // Ctrl C
            37: character := $13; // links
            38: character := $05; // oben
            39: character := $04; // rechts
            40: character := $18; // unten
            45: character := $16; // Einfg = Ctrl V
            46: character := $07; // Entf = Ctrl G
            48..57: character := key; // 0..9
            65..90: character := key + 32; // a..z
            187: character := $2B; // +
            188: character := $2C; // ,
            189: character := $2D; // -
            190: character := $2E; // .
            111: character := $3A; // NUM :
            106: character := $2A; // NUM *
            109: character := $2D; // NUM -
            107: character := $2B; // NUM +
            96..105: character := key - 48; // NUM 0..9
            {$ifdef Windows}
            110: character := $2E; // NUM .
            191: character := $23; // #
            219: character := $73; // s
            220: character := $5E; // ^
            221: character := $27; // `
            226: character := $3C; // <
            {$else}
            108: character := $2E; // NUM .
            222: character := $23; // #
            220: character := $73; // s
            150: character := $5E; // ^
            146: character := $27; // `
            225: character := $3C; // <
            {$endif}
            else character := $00;
        end;
    end;

    if ((Shift = [ssShift]) and (key <> 16)) then begin
        case key of
            00: character := key;
            48: character := $3D; // =
            49: character := $21; // !
            50: character := $22; // "
            51: character := $23; // §
            52: character := $24; // $
            53: character := $25; // %
            54: character := $26; // &
            55: character := $2F; // /
            56: character := $28; // (
            57: character := $29; // )
            65..90: character := key; // A..Z
            187: character := $2A; // *
            188: character := $3B; // ;
            189: character := $5F; // _
            190: character := $3A; // :
            {$ifdef Windows}
            191: character := $27; // '
            219: character := $3F; // ?
            220: character := $7E; // ° -> ~
            221: character := $60; // `
            226: character := $3E; // >
            {$else}
            222: character := $27; // '
            220: character := $3F; // ?
            150: character := $7E; // ° -> ~
            146: character := $60; // `
            225: character := $3E; // >
            {$endif}
            else character := $00;
        end;
    end;

    if ((Shift = [ssCtrl]) and (key <> 17)) then begin
        if (key > 64) and (key < 91) then begin
            character := key - 64;
        end;
    end;

    if ((Shift = [ssAlt..ssCtrl]) and (key <> 18)) then begin
        case key of
            48: character := $7D; // }
            55: character := $7B; // {
            56: character := $5B; // [
            57: character := $5D; // ]
            81: character := $40; // @
            187: character := $7E; // ~
            {$ifdef Windows}
            219: character := $5C; // \
            226: character := $7C; // |
            {$else}
            220: character := $5C; // \
            225: character := $7C; // |
            {$endif}
            else character := $00;
        end;
    end;

    if character > $00 then begin
        keyboardBuffer := keyboardBuffer + char(character);
        if (enableLocalEcho) then begin
            writeCharacter(character);
        end;
    end;
end;
Im MainWindow sind dann die Anpassungen:

Code: Alles auswählen

private
	...
        {$ifndef Windows}
        isKeyAltGr: boolean;
        {$endif}
        
        
        ....
        ....
        ....
        
        
// --------------------------------------------------------------------------------
procedure TMainWindow.FormKeyDown(Sender: TObject; var Key: word; Shift: TShiftState);
{$ifndef Windows}
var
    termShift: TShiftState;
{$endif}
begin
    {$ifndef Windows}
    if ((Key = 235) and (Shift = [SSALT])) then begin
        isKeyAltGr := True;
    end;
    if (isKeyAltGr) then begin
        termShift := [ssAlt..ssCtrl];
    end
    else begin
        termShift := Shift;
    end;
    SystemTerminal.getKeyBoardInput(Key, termShift);
    {$else}
    SystemTerminal.getKeyBoardInput(Key, Shift);
    {$endif}
end;

// --------------------------------------------------------------------------------
procedure TMainWindow.FormKeyUp(Sender: TObject; var Key: word; Shift: TShiftState);
begin
    {$ifndef Windows}
    if ((Key = 235) and (Shift = [])) then begin
        isKeyAltGr := False;
    end;
    {$endif}
end;
   
Host: Core i7-12700H, NVIDIA RTX3050 6GB, 32GB Ram, 1TB NVME SSD mit KUbuntu 22.04LTS 64bit , VM KUbuntu 22.04 LTS 64bit mit Lazarus 2.2.6 und Cross-Platform Compiler für Linux 32/64bit und Windows 32/64bit. Wine für erste Tests der Windows Binarys.

HobbyProgrammer
Beiträge: 166
Registriert: Di 29. Okt 2019, 12:51
Wohnort: Deutschland , Baden-Württemberg

Re: Taste AltGr benutzen

Beitrag von HobbyProgrammer »

Ich habe nun auch die Version 1.2.1 kompiliert und ebenso wie die Sourcen bei GitHub zum Download eingestellt.

https://github.com/ProgrammingHobby/Z180SoftSystem
Host: Core i7-12700H, NVIDIA RTX3050 6GB, 32GB Ram, 1TB NVME SSD mit KUbuntu 22.04LTS 64bit , VM KUbuntu 22.04 LTS 64bit mit Lazarus 2.2.6 und Cross-Platform Compiler für Linux 32/64bit und Windows 32/64bit. Wine für erste Tests der Windows Binarys.

Antworten