Seytonic / malduino

All the Malduinos!
MIT License
210 stars 52 forks source link

Problem with spanish keyboard #1

Open auveele opened 7 years ago

auveele commented 7 years ago

Hello, I just received my malduino yesterday. I've been testing and enjoying it, but I had a problem with the keyboard layout. Even with the Malduino official web converter.

I read some forums and github issues, and finally I have managed to make it work. I wanna share with you, my changes in the Keyboard.cpp file.

I hope that this will be usefull.

/*
  Keyboard.cpp

  Copyright (c) 2015, Arduino LLC
  Original code (pre-library): Copyright (c) 2011, Peter Barrett

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "Keyboard.h"

#if defined(_USING_HID)

//================================================================================
//================================================================================
//  Keyboard

static const uint8_t _hidReportDescriptor[] PROGMEM = {

  //  Keyboard
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)  // 47
    0x09, 0x06,                    // USAGE (Keyboard)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x85, 0x02,                    //   REPORT_ID (2)
    0x05, 0x07,                    //   USAGE_PAGE (Keyboard)

  0x19, 0xe0,                    //   USAGE_MINIMUM (Keyboard LeftControl)
    0x29, 0xe7,                    //   USAGE_MAXIMUM (Keyboard Right GUI)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
    0x75, 0x01,                    //   REPORT_SIZE (1)

  0x95, 0x08,                    //   REPORT_COUNT (8)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x95, 0x01,                    //   REPORT_COUNT (1)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x81, 0x03,                    //   INPUT (Cnst,Var,Abs)

  0x95, 0x06,                    //   REPORT_COUNT (6)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x65,                    //   LOGICAL_MAXIMUM (101)
    0x05, 0x07,                    //   USAGE_PAGE (Keyboard)

  0x19, 0x00,                    //   USAGE_MINIMUM (Reserved (no event indicated))
    0x29, 0x65,                    //   USAGE_MAXIMUM (Keyboard Application)
    0x81, 0x00,                    //   INPUT (Data,Ary,Abs)
    0xc0,                          // END_COLLECTION
};

Keyboard_::Keyboard_(void) 
{
    static HIDSubDescriptor node(_hidReportDescriptor, sizeof(_hidReportDescriptor));
    HID().AppendDescriptor(&node);
}

void Keyboard_::begin(void)
{
}

void Keyboard_::end(void)
{
}

void Keyboard_::sendReport(KeyReport* keys)
{
    HID().SendReport(2,keys,sizeof(KeyReport));
}

extern
const uint8_t _asciimap[128] PROGMEM;

/*[Language Files are provided by LocaleKeyboard.js (Licensed under MIT) - for more information visit: https://github.com/Nurrl/LocaleKeyboard.js]*/
/*
 * _asciimap took from Keyboard.cpp,
 *  Updated by Borja Garduño with the correct keys,
 *      and ~, ^ and `, fixed by BlueArduino20.
 */

#define SHIFT 0x80
const uint8_t _asciimap[128] =
{
  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,    // "
  0x20,          // #
  0x21|SHIFT,    // $
  0x22|SHIFT,    // %
  0x23|SHIFT,    // &
  0x2d,          // '
  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,      // ;
  0x64,            // <
  0x27|SHIFT,      // =
  0x64|SHIFT,      // > 
  0x2d|SHIFT,      // ?
  0x1f,            // @
  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
  0x1c|SHIFT,      // Y
  0x1d|SHIFT,      // Z
  0x2f,          // [
  0x35,          // bslash
  0x30,          // ]
  0x2f|SHIFT,    // ^
  0x38|SHIFT,    // _
  0x2f,            // `
  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
  0x1c,          // y
  0x1d,          // z
  0x34,    // {
  0x1e,    // |
  0x32,    // }
  0x21,    // ^
  0        // DEL

};

// Init var         
bool _altGrMap[128];
bool _altFine = false;

// Individually define all needed char
void initAltGr() {
  _altFine = true;

  for (int i=0; i<128; i++) {
    _altGrMap[i] = false;
  }

  _altGrMap[126] = true; // ~
  _altGrMap[123] = true; // {
  _altGrMap[91] = true;  // [
  _altGrMap[93] = true;  // ]
  _altGrMap[125] = true; // }
  _altGrMap[92] = true;  // bslash
  _altGrMap[124] = true; // |
  _altGrMap[64] = true;  // @
  _altGrMap[35] = true;  // #
}

uint8_t USBPutChar(uint8_t c);

// press() adds the specified key (printing, non-printing, or modifier)
// to the persistent key report and sends the report.  Because of the way 
// USB HID works, the host acts like the key remains pressed until we 
// call release(), releaseAll(), or otherwise clear the report and resend.
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
    int oldKey = k;
        k = pgm_read_byte(_asciimap + k);
        if (!k) {
            setWriteError();
            return 0;
        }

    // =========
    // ADDED THIS
    // =========  
    // Iniciamos ajustes ALT
    if (!_altFine) initAltGr();

    if (_altGrMap[oldKey]){
      _keyReport.modifiers |= 0x40;
    } else {
      _keyReport.modifiers = 0;
    }
    // ==========

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

    // 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;
}

// release() takes the specified key out of the persistent key report and
// sends the report.  This tells the OS the key is no longer pressed and that
// it shouldn't be repeated any more.
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 {                // it's a printing key
        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;
        }
    }

    // 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;
}

void Keyboard_::releaseAll(void)
{
    _keyReport.keys[0] = 0;
    _keyReport.keys[1] = 0; 
    _keyReport.keys[2] = 0;
    _keyReport.keys[3] = 0; 
    _keyReport.keys[4] = 0;
    _keyReport.keys[5] = 0; 
    _keyReport.modifiers = 0;
    sendReport(&_keyReport);
}

size_t Keyboard_::write(uint8_t c)
{   
    uint8_t p = press(c);  // Keydown
    release(c);            // Keyup
    return p;              // just return the result of press() since release() almost always returns 1
}

Keyboard_ Keyboard;

#endif
spacehuhn commented 7 years ago

Can you please tell us what problems you had and what you changed to solve them?

auveele commented 7 years ago

Of course, sorry.

I had problem with the symbols that need to press ALT_GR (ALT_RIGHT). Like: \ | @ # ~ [ ] { }

The firmware has the initAltGr function, but It never be called. This code is to modify the key, if the key code is in the _altGrMap array.

    if (!_altFine) initAltGr();

    if (_altGrMap[oldKey]){
      _keyReport.modifiers |= 0x40;
    } else {
      _keyReport.modifiers = 0;
    }
spacehuhn commented 7 years ago

We updated the converter! Can you try out if it works?

auveele commented 7 years ago

Hi,

I test the converter in malduino.com/converter, with the es_ES language and i download the arduino Sketch. I test it, but it does not work, like at first.

I compare the Keyboard.cpp and I think it is the same as the beginning, it does not contain the update we talked about in this issue.

Have you updated it in the malduino.com/converter?

spacehuhn commented 7 years ago

Try it again now.

auveele commented 7 years ago

I haven't got the Malduino with me, I'm at office now. But I download the code selecting the language es_Es, and I think that the Keyboard.cpp is the same. I saw that in your github an update in the Keyboard_end.cpp file with the additions.

#ifdef ADD_ALTGR
        if (!_altFine) initAltGr();
        if (_altGrMap[oldKey]){
          _keyReport.modifiers |= 0x40;
        } else {
          _keyReport.modifiers = 0;
        }
#endif

But that part isn't in the malduino.com/converter

spacehuhn commented 7 years ago

Ah you're right @Seytonic ... the converter.js is updated but src/Keyboard_end.cpp not.

Saikomorisan commented 7 years ago

Hi, With the changes that you did in keyboard.ccp I already work well the symbols but does not work the GUI R, what it does is press only GUI and then write R. I hope you can help me

spacehuhn commented 7 years ago

Does it work with the previous spanish keyboard.cpp? You can put it together yourself by making the keyboard.cpp out of these 3 files (in this order): https://github.com/Seytonic/malduino/blob/master/converter/src/Keyboard_begin.cpp + https://github.com/Nurrl/LocaleKeyboard.js/blob/master/locales/es_ES.lang + https://github.com/Seytonic/malduino/blob/master/converter/src/Keyboard_end.cpp

Saikomorisan commented 7 years ago

THANK YOU. Already works, but now instead of writing \ write º, is it possible to solve it?

spacehuhn commented 7 years ago

Ok it's as I thougt. If you want the keys to be correct you gotta use @auveele fix, but then you have the problem with the key combinations again.

@auveele do you have an idea what causes this?

Saikomorisan commented 7 years ago

Hi,

I am not good programming in arduino and wanted to know if it could be in firmware make it look in the string the backslash and make it press ALT 92.

Saikomorisan commented 7 years ago

HI, i'm tested the new converter an now work every special key but the GUI r doesn't´t work again. ;c

balioas commented 6 years ago

Hello, have the same issue on the french keyboard :( Can you help me please, I received my malduino lite today :) thank you !