Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keyboard.press(KEY_RETURN); types "(" instead of {ENTER} #92

Closed
ciriousjoker opened this issue Nov 2, 2016 · 5 comments
Closed

Keyboard.press(KEY_RETURN); types "(" instead of {ENTER} #92

ciriousjoker opened this issue Nov 2, 2016 · 5 comments

Comments

@ciriousjoker
Copy link

ciriousjoker commented Nov 2, 2016

The headline sums it up pretty well, but I'll further elaborate:

I tried this using a German and the US keyboard layout, but after I looked at the files "TeensyKeylayouts.h" and "ImprovedKeylayouts.h", I noticed that KEY_ENTER always returns 40, which is, - I suppose - an ASCII value.

And that Ascii value translates to "(".

I don't quite get if I'm missing out anything or if that's really a bug no one ever noticed before me ...

EDIT: Typing KEY_RETURN with the default Keyboard.h library works perfectly; Using an Arduino Leonardo

@ciriousjoker ciriousjoker changed the title typeKey(KEY_RETURN) types "(" instead of {ENTER} Keyboard.press(KEY_RETURN); types "(" instead of {ENTER} Nov 2, 2016
@NiKiZe
Copy link

NiKiZe commented Nov 3, 2016

You can see a similar discussion and my response at: #89 (comment)

Keyboards sends keyboard scancodes, there is no concept of ASCII or any type of char, it is just a code for the pressed key.

On page 54 of http://www.usb.org/developers/hidpage/Hut1_12v2.pdf you see scancode 40 in decimal is Enter

@NicoHood
Copy link
Owner

NicoHood commented Nov 3, 2016

German layout is not supported and covered in another issue. Feel free to implement it.

@NicoHood NicoHood closed this as completed Nov 3, 2016
@donid
Copy link

donid commented Nov 3, 2016

For German layout support please see my comment in issue 22

@ciriousjoker
Copy link
Author

ciriousjoker commented Nov 3, 2016

I solved the problem by not using your library and changing the Keyboard.cpp instead.

These are the changes I made and from what I've noticed, it all works pretty well including the ALTGR key on the german keyboard (it's used for these symbols: €²³{[]}~|)

My custom _asciimap[]

extern

// NOTE: Was [128] before
const uint8_t _asciimap[256] PROGMEM;

#define SHIFT 0x80
#define ALTGR 0x40
const uint8_t _asciimap[256] =
{
    0x00,             // NUL
    0x00,             // SOH
    0x00,             // STX
    0x00,             // ETX
    0x00,             // EOT
    0x00,             // ENQ
    0x00,             // ACK  
    0x00,             // BEL
    0x2a,           // BS   Backspace
    0x2b,           // TAB  Tab
    0x28,           // LF   Enter
    0x00,             // VT 
    0x00,             // FF 
    0x00,             // CR 
    0x00,             // SO 
    0x00,             // SI 
    0x00,             // DEL
    0x00,             // DC1
    0x00,             // DC2
    0x00,             // DC3
    0x00,             // DC4
    0x00,             // NAK
    0x00,             // SYN
    0x00,             // ETB
    0x00,             // CAN
    0x00,             // EM 
    0x00,             // SUB
    0x00,             // ESC
    0x00,             // FS 
    0x00,             // GS 
    0x00,             // RS 
    0x00,             // US 

    0x2c,          //  ' '
    0x1e|SHIFT,    // !
    0x1f|SHIFT,    // "
    0x31,          // #
    0x21|SHIFT,    // $
    0x22|SHIFT,    // %
    0x23|SHIFT,    // &
    0x31|SHIFT,    // '
    0x25|SHIFT,    // (
    0x26|SHIFT,    // )
    0x30|SHIFT,    // *
    0x30,          // +
    0x36,          // ,
    0x38,          // -
    0x37,          // .
    0x24|SHIFT,    // /
    0x27,          // 0
    0x1e,          // 1
    0x1f,          // 2
    0x20,          // 3
    0x21,          // 4
    0x22,          // 5
    0x23,          // 6
    0x24,          // 7
    0x25,          // 8
    0x26,          // 9
    0x37|SHIFT,    // :
    0x36|SHIFT,    // ;
    0x03,          // <
    0x27|SHIFT,    // =
    0x03|SHIFT,    // >
    0x2d|SHIFT,    // ?
    0x14|ALTGR,    // @
    0x04|SHIFT,    // A
    0x05|SHIFT,    // B
    0x06|SHIFT,    // C
    0x07|SHIFT,    // D
    0x08|SHIFT,    // E
    0x09|SHIFT,    // F
    0x0a|SHIFT,    // G
    0x0b|SHIFT,    // H
    0x0c|SHIFT,    // I
    0x0d|SHIFT,    // J
    0x0e|SHIFT,    // K
    0x0f|SHIFT,    // L
    0x10|SHIFT,    // M
    0x11|SHIFT,    // N
    0x12|SHIFT,    // O
    0x13|SHIFT,    // P
    0x14|SHIFT,    // Q
    0x15|SHIFT,    // R
    0x16|SHIFT,    // S
    0x17|SHIFT,    // T
    0x18|SHIFT,    // U
    0x19|SHIFT,    // V
    0x1a|SHIFT,    // W
    0x1b|SHIFT,    // X
    0x1d|SHIFT,    // Y
    0x1c|SHIFT,    // Z
    0x25|ALTGR,    // [
    0x2d|ALTGR,    // bslash
    0x26|ALTGR,    // ]
    0x35,          // ^
    0x38|SHIFT,    // _
    0x2e|SHIFT,    // `
    0x04,          // a
    0x05,          // b
    0x06,          // c
    0x07,          // d
    0x08,          // e
    0x09,          // f
    0x0a,          // g
    0x0b,          // h
    0x0c,          // i
    0x0d,          // j
    0x0e,          // k
    0x0f,          // l
    0x10,          // m
    0x11,          // n
    0x12,          // o
    0x13,          // p
    0x14,          // q
    0x15,          // r
    0x16,          // s
    0x17,          // t
    0x18,          // u
    0x19,          // v
    0x1a,          // w
    0x1b,          // x
    0x1d,          // y
    0x1c,          // z
    0x24|ALTGR,    // 
    0x03|ALTGR,    // |
    0x27|ALTGR,    // }
    0x35|SHIFT,    // ~
    0x2a,           // DEL
    0x00,             // NUL
    0x00,             // SOH
    0x00,             // STX
    0x00,             // ETX
    0x00,             // EOT
    0x00,             // ENQ
    0x00,             // ACK  
    0x00,             // BEL
    0x2a,           // BS   Backspace
    0x2b,           // TAB  Tab
    0x28,           // LF   Enter
    0x00,             // VT 
    0x00,             // FF 
    0x00,             // CR 
    0x00,             // SO 
    0x00,             // SI 
    0x00,             // DEL
    0x00,             // DC1
    0x00,             // DC2
    0x00,             // DC3
    0x00,             // DC4
    0x00,             // NAK
    0x00,             // SYN
    0x00,             // ETB
    0x00,             // CAN
    0x00,             // EM 
    0x00,             // SUB
    0x00,             // ESC
    0x00,             // FS 
    0x00,             // GS 
    0x00,             // RS 
    0x00,             // US 

    0x2c|ALTGR,       // nobr
    0x1e|ALTGR|SHIFT, // ¡
    0x06|ALTGR,       // ¢
    0x20|ALTGR|SHIFT, // £
    0,                // currency sign
    0,                // yen sign
    0x03|ALTGR|SHIFT, // ¦
    0x20|SHIFT,       // §
    0x2f|ALTGR,       // "
    0,                // copy
    0,                // fem
    0,                // left pointing double angle
    0,                // not
    0,                // soft hyphen
    0,                // reg
    0,                // macron
    0x35|SHIFT,       // degree
    0,                // plus-minus
    0,                // super2
    0,                // super3
    0,                // acute
    0,                // µ
    0,                // pilcrow
    0,                // mid dot
    0,                // cedilla
    0,                // super1
    0,                // masc
    0,                // right pointing double angle
    0,                // quarter
    0,                // half
    0,                // 3 quarter
    0,                // inv questmark
    0,                // À
    0,                // Á
    0,                // Â
    0,                // Ã
    0x34|SHIFT,       // Ä
    0,                // ringA
    0,                // Æ
    0,                // Cedi
    0,                // È
    0,                // É
    0,                // Ê
    0,                // Ë
    0,                // Ì
    0,                // Í
    0,                // Î
    0,                // Ï
    0,                // Eth
    0,                // Ñ
    0,                // Ò
    0,                // Ó
    0,                // Ô
    0,                // Õ
    0x31|SHIFT,       // Ö
    0,                // mult
    0,                // Ø
    0,                // Ù
    0,                // Ú
    0,                // Û
    0x2f|SHIFT,       // Ü
    0,                // Ý
    0,                // Thorn
    0x2d,             // ß
    0,                // à
    0,                // á
    0,                // â
    0,                // ã
    0x34,             // ä
    0,                // æ
    0,                // ç
    0,                // è
    0,                // é
    0,                // ê
    0,                // ë
    0,                // ì
    0,                // í
    0,                // î
    0,                // ï
    0,                // eth
    0,                // ñ
    0,                // ò
    0,                // ó
    0,                // ô
    0,                // õ
    0x31,             // ö
    0,                // div
    0,                // ø
    0,                // ù
    0,                // ú
    0,                // û
    0x2f,             // ü
    0,                // ?
    0,                // thorn
    0,                // ÿ
};

My custom Keyboard.press() function

size_t Keyboard_::press(uint8_t k) 
{
    uint8_t i;
    if (k >= 136) {         // it's a non-printing key (not a modifier)
        k = k - 136;
    } else if (k >= 128) {  // it's a modifier key
        _keyReport.modifiers |= (1<<(k-128));
        k = 0;
    } else {                // it's a printing key
        k = pgm_read_byte(_asciimap + k);
        if (!k) {
            setWriteError();
            return 0;
        }
        if (k & 0x80) {                     // it's a capital letter or other character reached with shift
            _keyReport.modifiers |= 0x02;   // the left shift modifier
            k &= 0x7F;
        }


        // NOTE: This part is new to handle [Alt Gr]
        if (k & 0x40) {
            _keyReport.modifiers |= 0x40;
            k &= 0x3F;
        }
        if (k == 0x03) { // special case 0x64
            k = 0x64;
        }
        // ENDNOTE

    }

    // Add k to the key report only if it's not already present
    // and if there is an empty slot.
    if (_keyReport.keys[0] != k && _keyReport.keys[1] != k && 
        _keyReport.keys[2] != k && _keyReport.keys[3] != k &&
        _keyReport.keys[4] != k && _keyReport.keys[5] != k) {

        for (i=0; i<6; i++) {
            if (_keyReport.keys[i] == 0x00) {
                _keyReport.keys[i] = k;
                break;
            }
        }
        if (i == 6) {
            setWriteError();
            return 0;
        }   
    }
    sendReport(&_keyReport);
    return 1;
}

My custom Keyboard.release() function

size_t Keyboard_::release(uint8_t k) 
{
    uint8_t i;

     if (k >= 136) {            // it's a non-printing key (not a modifier)
        k = k - 136;
    } else if (k >= 128) {  // it's a modifier key
        _keyReport.modifiers &= ~(1<<(k-128));
        k = 0;
    } else {        

        k = pgm_read_byte(_asciimap + k);
        if (!k) {
            return 0;
        }
        if (k & 0x80) {                         // it's a capital letter or other character reached with shift
            _keyReport.modifiers &= ~(0x02);    // the left shift modifier
            k &= 0x7F;
        }


        // NOTE: This part is new to handle [Alt Gr]
        if (k & 0x40) {
            _keyReport.modifiers &= ~(0x40);
            k &= 0x3F;
        }
        if (k == 0x03) { // special case 0x64
            k = 0x64;
        }
        // ENDNOTE

     }

    // Test the key report to see if k is present.  Clear it if it exists.
    // Check all positions in case the key is present more than once (which it shouldn't be)
    for (i=0; i<6; i++) {
        if (0 != k && _keyReport.keys[i] == k) {
            _keyReport.keys[i] = 0x00;
        }
    }

    sendReport(&_keyReport);
    return 1;
}

I have no idea how this would work together with your library, but I also don't have the time to completely read into it.

I just thought this might be helpful for you, so here you go, maybe you'll find a way to correctly implement it.

Here's the complete Keyboard.cpp file, currently you'd have to put it in the .ino directory and #include it directly.

Keyboard.zip

@scpcom
Copy link

scpcom commented Apr 19, 2017

For AltGr and special case 0x64 you do not need to modify the Keyboard the library.
Example:

#include "Keyboard.h"

#define KEY_ALT_GR KEY_RIGHT_ALT

void setup()
{
  Keyboard.begin();
}

void loop()
{
  if (doIt)
  {
    // special case 0x64 (0xEC = 0x88 + 0x64)
  
    // <
    Keyboard.press(0xEC);
    Keyboard.releaseAll();

    // >
    Keyboard.press(KEY_LEFT_SHIFT);
    Keyboard.press(0xEC);
    Keyboard.releaseAll();

    // |
    Keyboard.press(KEY_ALT_GR);
    Keyboard.press(0xEC);
    Keyboard.releaseAll();
  }
}

For some special characters you can use Keyboard.press() with corresponding codes by creating a lookup table or something else:

21 !
22 Ä
23 §
24 $
25 %
26 /
27 ä
28 )
29 =
2A (

2C ,
2D ß
2E .
2F -
 
3A Ö
3B ö
3C ;
3D ´
3E :
3F _
40 "

5B ü
5C #
5D +
5E &
5F ?
60 ^

7B Ü
7C '
7D *
7E °

For other keys you can use Keyboard.press() with existing definitions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants