-         

Seite 1 von 4 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 33

Thema: C/C++ lib für Sonderzeichenkombinationen (F1-12, +shift, alt, ctrl) als Scancode

  1. #1
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    2.452

    C/C++ lib für Sonderzeichenkombinationen (F1-12, +shift, alt, ctrl) als Scancode

    Anzeige

    hallo,
    wer kennt eine C/C++ lib für Sonderzeichenkombinationen (F1-12, +shift, alt, ctrl), um sie als Art "scancode" von der Tastatur zu lesen?

    es soll so ähnlich funktionieren wie mit getch() / getchar(), nur dass nicht ein ASCII Zeichen gelesen werden soll, sondern ein einzigarteiger "Scancode" für die Tastenkombi (also keine Folge von einzelnen chars), z.B.
    64031 für F1
    65031 für ctrl+F1
    66031 für shift+F1
    ...
    usw,
    praktischerweise auch
    27 für ESC und
    65 für 'A' etc,

    um sie einfach abfragen und behandeln zu können, wie hier im Pseudocode:

    Code:
    int32_t i=getkeycode();
     
    if(i==27) {...} // ESC: return NULL, terminate program (quit)
    else
    if(i==64031) {...} // F1: switch openVG window 1
    else
    if(i==64032) {...} // F2: switch openVG window 2
    else
    if(i==64033) {...} // F3: switch openVG window 3
    else
    if(i==63001) {...} // ctrl + : zoom in
    else
    if(i==63002) {...} // ctrl - : zoom out
    else
    if(i==64111) {...} // cur_up: move slow forward
    else
    if(i==64112) {...} // cur_dn: move slow reverse
    else
    if(i==66111) {...} // shift+cur_up: move fast forward
    else
    if(i==66112) {...} // shift+cur_dn: move fast reverse
    else
    if(i==64113) {...} // cur_left: turn slow left
    else
    if(i==64114) {...} // cur_right: turn slow right
    else
    if(i==66113) {...} // shift+cur_left: turn strong left
    else
    if(i==66114) {...} // shift+cur_right: turn strong right
    else
    if(i==65113) {...} // ctrl+cur_left: spin left
    else
    if(i==65114) {...} // ctrl+cur_right: spin right
    else
    if(i==64120) {...} // end: stop move, coast
    else
    if(i==65120) {...} // ctrl+end: stop move, brake
    ...

    Man bräuchte dazu allerdings auch eine Tabelle als Übersicht, um die Zeichen nachschlagen zu können:

    Code:
     key         plain   shift   ctrl   alt   shift+ctrl   ctrl+alt   shift+alt   shift+ctrl+alt
    Home   
    Insert   
    Delete 
    End     
    Pgup   
    PgDn   
     F1   
     F2     
     F3   
    ...
    cur_up
    cur_dn
    cur_left
    cur_right
    ...
    A
    B
    C
    ...
    a
    b
    c
    ...
    wo gibt's sowas, nach 40 Jahren C und Unix/Linux ?
    Geändert von HaWe (04.04.2016 um 22:15 Uhr)
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    599
    Hallo,

    mit Tastaturen unter Linux kenne ich mich nicht so aus. Du musst die Linux Doku finden, die die entsprechnenden Dinge beschreibt, wie hier das Windows Gegenstück:
    https://msdn.microsoft.com/en-us/lib...=vs.85%29.aspx

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    59
    Beiträge
    2.435
    Hallo,

    Die Frage ist jetzt auf welcher Ebene du ansetzen willst?

    Ganz früher haben Tastaturcontroller direkt den ASCII-Code der Tasten geliefert. Das brauchte dann aber für jede Tastenanordnung (Sprache) einen anderen Controller. STRG und SHFT wurden nur intern verwendet. An Computer wurden Terminals angeschlossen, Einheiten aus Tastatur und Bildschirm. Für die Codierung von z.B. Coursor-Tasten, welche in ASCII nicht vorgesehen sind, hatte jeder Terminal-Hersteller eine eigene Lösung. Wie auch für die Steuerbefehle ans Terminal.
    Sehr verbreitet waren die DEC VT100 Terminals, woraus sich dann auch eine ANSI-Norm für Terminals entwickelte.


    IBM hat dann beim PC die Tasten einfach durchnummeriert. Jede Taste setzt dann ein Signal beim Drücken und eines beim loslassen ab (Scancode).
    Im PC war dann ein Tastaturtreiber, welcher aus den Scancodes dann die entsprechenden ASCII-Werte erzeugt und die speziellen Tasten wie STRG, SHFT usw. auswertet.
    Für Sondertasten gibt es keine definierte ASCII-Codes, also wurden für sie zwei Zeichen erzeugt.

    wo gibt's sowas, nach 40 Jahren C und Unix/Linux ?
    Da liegt halt der Hund begraben!
    Den IBM-PC gibt es erst seit 35 Jahren und Unix kam erst später auf den IBM-PC.
    Unix war zuerst auf Grossrechnern vorhanden, weshalb es unter Unix/Linux deshalb heute immer noch eine Menge Treiber für Terminals gibt oder Treiber welche eines der Terminals simulieren.

    MfG Peter(TOO)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    599
    Ich glaube mit Terminal hat Peter das richtige Stichwort genannt.

    getch() und Verwandte setzen wahrscheinlich auf den Terminal-Funktionen auf. Man muss also mindestens auf diese Ebene herunter. Es gibt da auch einen raw Modus, möglicherweise liefert der das gesuchte. Das alles ist verwandt mit den Funktionen zur UART-Programmierung, das ist für Unix alles das selbe, genau wie Peter schon sagt. Früher hingen alle Textterminals an seriellen Schnittstellen.

    Noch tiefer kommt man wohl nur mit raw input, das geht irgendwie mit Sachen aus den /dev/... Verzeichnissen. Hab ich noch nie gemacht.

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    2.452
    im Prinzip ist mir die Ebene egal, ich lese die Tastatur in einer Art pthread "keyboard watcher task" - bisher wird nur die Taste ESC überwacht für einen program abort, aber nun sollen auch andere Tasten überwacht werden, insbesondere Sondertasten:

    *arrrgs* wieder kein Code Tag!!!
    Code:
    void* thread1Go(void *)   // medium priority:  keyboard + heartbeat monitoring
    {
       int   c;  // keyboard key
       
       while(_TASKS_ACTIVE_) {         
          c=0;
          if (kbhit())    {           // <<<<<<<<<<<<<<<<<<
              c = getchar();          
              if( c==27 ) {           // ESC to quit program
                   printf("\n\n ESC pressed - program terminated by user \n");
                   _TASKS_ACTIVE_=0;  // semaphore to stop all tasks
                   printf("\n wait for tasks to join main()... \n\n");
                   return NULL;
              }
          }
         
         //... ***SNIP***
    
         delay(50);
       }         
       return NULL;
    }
    kbhit habe ich als conio-mimic hierraus:

    Code:
    #ifndef RPICONIO_H
    #define   RPICONIO_H
    
    
    #include <stdbool.h>
    #include <stdio.h>
    #include <string.h>
    #include <termio.h>
    #include <unistd.h>
    
    bool kbhit(void)
    {
        struct termios original;
        tcgetattr(STDIN_FILENO, &original);
    
        struct termios term;
        memcpy(&term, &original, sizeof(term));
    
        term.c_lflag &= ~ICANON;
        tcsetattr(STDIN_FILENO, TCSANOW, &term);
    
        int characters_buffered = 0;
        ioctl(STDIN_FILENO, FIONREAD, &characters_buffered);
    
        tcsetattr(STDIN_FILENO, TCSANOW, &original);
    
        bool pressed = (characters_buffered != 0);
    
        return pressed;
    }
    
    
    //... ***SNIP***
    
    
    #endif


    über wiederholtes getchar() Auslesen ginge es zwar prinzipiell, aber F1 liefert 3 Zechen im keyb-Puffer (27,79,80) und shift-F1 wohl sogar 6, was ein Unding wäre, das über eine extra state machine verarbeiten zu wollen - für alle 102x7 möglichen key+modifier-Kombis.
    Also wird eine Art "Scancode" gebraucht, so wie es das schon früher bei Turbo Pascal und Turbo C optional, zusätzlich zu readkey oder getchar gab.
    Geändert von HaWe (05.04.2016 um 11:55 Uhr)
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  6. #6
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    599
    Zitat Zitat von HaWe Beitrag anzeigen
    Also wird eine Art "Scancode" gebraucht,
    Die Werte der Codes siehst du in /usr/include/linux/input.h

    Wahrscheinlich arbeitet man damit, in dem man /dev/input/irgendwas öffnet. Habe ich, wie gesagt, noch nie probiert. Meine Raspis haben nichtmal eine Tastatur.

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    28.03.2016
    Beiträge
    8
    über wiederholtes getchar() Auslesen ginge es zwar prinzipiell, aber F1 liefert 3 Zechen im keyb-Puffer (27,79,80) und shift-F1 wohl sogar 6, was ein Unding wäre, das über eine extra state machine verarbeiten zu wollen - für alle 102x7 möglichen key+modifier-Kombis.
    Shift-F1 ist eine Kombination, ich denke bei 3 für eine Einzelne ist Schluss. Kombinationen muss man immer nach dem Puffer verarbeiten. Ausser man nutzt eine library wie ncurses, welche ich persönlich gern nutze. Sehr einfache Struktur und mit ein paar Zeilen Ergebnisse.

    So aufwendig ist das ohne eine Library auch nicht... Pseudocode:
    Code:
    uint8_t c, len;
    int ret;
    
    c = get_scancode();
    len = lookup_len(c);        // tabelle/array mit möglichen längen (1-3)
    array_rcv[0] = c;         // erstes/einzelnes zeichen speichern
    if(len > 1) {
          ret = get_more(array[1], array[2], len);        // empfange len mehr zeichen, return = empfangene zeichen
          // etwas tun
    }

  8. #8
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    2.452
    ncurses nutzt eine eigenes Terminal-Window mit eigener print-Funktion
    mvaddstr
    und mit einem ziemlichen Initialisierungs-Overhead

    initscr();
    raw();
    noecho();
    keypad(stdscr, TRUE);

    und mit Eigenschaften, die std-printf()-Ausgaben "verzerren", so wird z.B. nach \n kein carriage return ausgeführt. Mehrmals einen string mit \n ausgeben lässt ihn daher mit Treppenstufen-Versatz in die nächste Zeile nach rechts rutschen, nicht untereinander ab Anfang jeder Zeile.
    Außerdem kann ncurses - zumindest per Testcode - z.B. kein shift+F1 anzeigen. Von daher ist also einerseits nicht mehr standardconform, und zum anderen auch noch von sehr eingeschränktem Nutzungsumfang.

    für ncurses hatte ich mal diesen testcode ausprobiert:

    Code:
    #include <ncurses.h>
    
    int
    main( void )
    {
         /*  Initialize ncurses  */
       initscr();
       const char *str;
       int ch;
    
         /*  Switch of echoing and enable keypad */
       raw();
       noecho();
       keypad(stdscr, TRUE);
       mvaddstr( LINES-1, 0, "Press keys, 'q' to quit" );
    
        /*  Loop until user hits 'q' to quit  */
       while( (ch = getch()) != 'q' )
       {
         switch( ch )
         {
          case KEY_F(1):
             str = "F1 key";
             break;
          case KEY_F(2):
             str = "F2 key";
             break;
          case KEY_F(3):
             str = "F3 key";
             break;
          case KEY_F(4):
             str = "F4 key";
             break;
    
          case 'a' ... 'z':
             str = "Lower case letter";
             break;
          case 'A' ... 'Z':
             str = "Upper case letter";
             break;
          case '0' ... '9':
             str = "Digit";
             break;
    
          case KEY_UP:
             str = "KEY_UP";
             break;
    
          case KEY_DOWN:
             str = "KEY_DOWN";
             break;
          case KEY_LEFT:
             str = "KEY_LEFT";
             break;
          case KEY_RIGHT:
             str = "KEY_RIGHT";
             break;
          case KEY_HOME:
             str = "KEY_HOME";
             break;
          case KEY_END:
             str = "KEY_END";
          }
    
       //mvaddstr( LINES-1, 0, str );
       printf("%s\n", str);
            clrtoeol();
     }
    
       /*  Clean up after ourselves  */
    endwin();
    
     return 0;
    }



    Einen (wünschenswerten) Pseudocode hatte ich ja bereits selber skizziert, zu Erläuterungszwecken.

    Was ich aber jetzt brauche, ist kein Pseudocode, sondern echten Code, zusammen mit einer Liste aller möglichen denkbaren modifier-Kombis, damit man nicht das Rad neu erfinden muss.


    **arrrgs** und schon wieder keine Code Tags hier vorhanden...
    Code:
     key         plain   shift   ctrl   alt   shift+ctrl   ctrl+alt   shift+alt   shift+ctrl+alt
    Home   
    Insert   
    Delete 
    End     
    Pgup   
    PgDn   
     F1   
     F2     
     F3   
    ...
    cur_up
    cur_dn
    cur_left
    cur_right
    ...
    A
    B
    C
    ...

    "Das Rad nicht neu erfinden" gilt übrigens auch für meine gesuchte Funktion, ich denke, das müsste es nach 40 Jahren UNIX/Linux sicher schon längst geben.




    - - - Aktualisiert - - -

    pps,
    für BIOS/MSDOS etc gabs das ja, gelistet z.B. hier
    http://flint.cs.yale.edu/cs422/doc/a...pdf/APNDXC.PDF
    (Appendices Page 1353)

    so etwas bräuchte ich nun für Linux als Art "getscancode()" etc.
    Geändert von HaWe (05.04.2016 um 15:12 Uhr) Grund: per code tags nachformatiert
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    28.03.2016
    Beiträge
    8
    Hmm... Die Modifier-Tasten sind eben nur Modifier und ich kenne da keinen anderen Weg. Vielleicht hilft dir das ja weiter, um alles Steuerzeichen direkt zu bekommen:

    https://www.daniweb.com/programming/...g-gcc-compiler

    - - - Aktualisiert - - -

    Hmm... Die Modifier-Tasten sind eben nur Modifier und ich kenne da keinen anderen Weg. Vielleicht hilft dir das ja weiter, um alles Steuerzeichen direkt zu bekommen:

    https://www.daniweb.com/programming/software-development/threads/147540/how-can-we-get-scan-code-in-c-using-gcc-compiler

  10. #10
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    2.452
    das ist die oben von mir skizzierte kaskadierte Methode.
    Für F1 muss man dazu hintereinander 27, dann 79, dann 80 auslesen, um es als F1 zu identifizieren, und für shift-F1 nochmal 3 chars zusätzlich.
    Dann denk mal drüber nach, welche Verrenkungen nötig sind, um ein ctr+shift+F1 von einem ctr+shift+F2 oder einem alt+ctrl+F2 oder einem shift+ctrl+alt+F1 oder shift+ctrl+alt+F2 zu unterscheiden....

    Das bringt doch wie gesagt nichts.
    Was man bräuchte, wäre der Scancode, was eher dem gleichkommt, was die Keyboard-Hardware selber produziert, nicht das, was das Linux-Terminal daraus macht.

    wie könnte man z.B.
    /dev/input/*
    auslesen?

    Und wo findet man die zugehörige Tasten-Kombinationen-Tabelle?
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

Seite 1 von 4 123 ... LetzteLetzte

Ähnliche Themen

  1. Antworten: 10
    Letzter Beitrag: 01.11.2017, 13:53
  2. Neue Atmega "A" und "PA" Typen
    Von AVR168 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 07.05.2012, 17:47
  3. Antworten: 2
    Letzter Beitrag: 15.06.2011, 22:18
  4. "Lichtverfolgung" in "TV-Remote" einbaue
    Von fabqu im Forum Robby RP6
    Antworten: 3
    Letzter Beitrag: 04.01.2011, 11:14
  5. "Soft-Reset?" und "Finger-Interrupt?"
    Von trapperjohn im Forum Asuro
    Antworten: 8
    Letzter Beitrag: 11.06.2008, 00:02

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •