chegewara / EspTinyUSB

ESP32S2 native USB library. Implemented few common classes, like MIDI, CDC, HID or DFU (update).
MIT License
475 stars 70 forks source link

HELP: key combination #55

Closed rahmanshaber closed 2 years ago

rahmanshaber commented 2 years ago

tinyUSB don't have some symbols accessible directly. In order to get $%^&?" and other symbols i used this method but can get it working. if i press the keys i get only numbers. What the issue might be?


//#define KEYS_TILDE      HID_KEY_TILDE|KEYBOARD_MODIFIER_LEFTSHIFT       /* ~ */
#define KEYS_EXCL       HID_KEY_1|KEYBOARD_MODIFIER_LEFTSHIFT           /* ! */
#define KEYS_AT         HID_KEY_2|KEYBOARD_MODIFIER_LEFTSHIFT           /* @ */
#define KEYS_HASH       HID_KEY_3|KEYBOARD_MODIFIER_LEFTSHIFT           /* # */
#define KEYS_DOLLAR     HID_KEY_4|KEYBOARD_MODIFIER_LEFTSHIFT           /* $ */
#define KEYS_PERCENT    HID_KEY_5|KEYBOARD_MODIFIER_LEFTSHIFT           /* % */
#define KEYS_CARET      HID_KEY_6|KEYBOARD_MODIFIER_LEFTSHIFT           /* ^ */
#define KEYS_AMP        HID_KEY_7|KEYBOARD_MODIFIER_LEFTSHIFT           /* & */
#define KEYS_ASTERISK   HID_KEY_8|KEYBOARD_MODIFIER_LEFTSHIFT           /* * */
#define KEYS_LRBRACKET  HID_KEY_9|KEYBOARD_MODIFIER_LEFTSHIFT           /*( */
#define KEYS_RRBRACKET  HID_KEY_0|KEYBOARD_MODIFIER_LEFTSHIFT           /* ) */

#define KEYS_LCBRACKET  HID_KEY_LEFT_BRACE|KEYBOARD_MODIFIER_LEFTSHIFT  /* { */
#define KEYS_RCBRACKET  HID_KEY_RIGHT_BRACE|KEYBOARD_MODIFIER_LEFTSHIFT /* } */
#define KEYS_COLON      HID_KEY_SEMICOLON|KEYBOARD_MODIFIER_LEFTSHIFT   /* : */
#define KEYS_DQUOTE     HID_KEY_QUOTE|KEYBOARD_MODIFIER_LEFTSHIFT       /* " */
#define KEYS_LABRACKET  HID_KEY_COMMA|KEYBOARD_MODIFIER_LEFTSHIFT       /* < */
#define KEYS_RABRACKET  HID_KEY_PERIOD|KEYBOARD_MODIFIER_LEFTSHIFT      /* > */
#define KEYS_QMARK      HID_KEY_SLASH|KEYBOARD_MODIFIER_LEFTSHIFT       /* ? */

static uint8_t keymapSymbols[] =
{
  HID_KEY_GUI_LEFT,     HID_KEY_CAPS_LOCK,      HID_KEY_TAB,          HID_KEY_ESCAPE,           EXPANSION_SWITCH,         'E',                    'E',                  EXPANSION_SWITCH,       HARDWARE_TEST,       KMAP_SWITCH,      LCD_SWITCH,
  HID_KEY_ARROW_LEFT,   KEYS_EXCL,              KEYS_AT,              KEYS_HASH,                KEYS_DOLLAR,              KEYS_PERCENT,           KEYS_CARET,           KEYS_AMP,               KEYS_ASTERISK,       KEYS_LRBRACKET,   KEYS_RRBRACKET,
  HID_KEY_ARROW_RIGHT,  'E',                    HID_KEY_ARROW_UP,     HID_KEY_PAGE_UP,          KEYS_DQUOTE,              HID_KEY_EUROPE_1,       HID_KEY_BRACKET_LEFT, HID_KEY_BRACKET_RIGHT,  HID_KEY_SLASH,       HID_KEY_GRAVE,    KEYS_COLON,
  KMOUSE_LEFT,          'E',                    HID_KEY_ARROW_DOWN,   HID_KEY_PAGE_DOWN,        KEYS_DOLLAR,              HID_KEY_APOSTROPHE,     HID_KEY_EXSEL,        KEYS_QMARK,             HID_KEY_SEMICOLON,   HID_KEY_EUROPE_2, HID_KEY_BACKSPACE,
  KMOUSE_RIGHT,         HID_KEY_CONTROL_LEFT,   HID_KEY_KEYPAD_ADD,   HID_KEY_KEYPAD_SUBTRACT,  HID_KEY_KEYPAD_MULTIPLY,  HID_KEY_KEYPAD_DIVIDE,  HID_KEY_KEYPAD_EQUAL, HID_KEY_COMMA,          HID_KEY_PERIOD,      HID_KEY_SPACE,    HID_KEY_ENTER
};

static uint8_t modifierKey = 0;

static void processKeys( void )
{
  if( !Keyboard.getKeys() ) return;

  // disable the keyboard when display is off
  if( !digitalRead( POWER_LCD ) ) return;

  int i;

  for( i = 0; i < LIST_MAX; i++ )
  {
    if( !Keyboard.key[i].stateChanged ) continue;

    uint8_t key = mapKey( Keyboard.key[i].kchar );

    if( key == KMAP_SWITCH || key == HARDWARE_TEST || key == KMOUSE_LEFT || 
        key == KMOUSE_RIGHT || key == EXPANSION_SWITCH ||  key == LCD_SWITCH  ) continue;

    switch( Keyboard.key[i].kstate )
    {
      case PRESSED:
        if( key == HID_KEY_CONTROL_LEFT )
        {
          HIDdevice.sendPress( 0, KEYBOARD_MODIFIER_LEFTCTRL );
          modifierKey = KEYBOARD_MODIFIER_LEFTCTRL;
        } 
        else if( key == HID_KEY_GUI_LEFT )
        {
          HIDdevice.sendPress( 0, KEYBOARD_MODIFIER_LEFTGUI );
          modifierKey = KEYBOARD_MODIFIER_LEFTCTRL;
        } 
        else
        {
          HIDdevice.sendPress( key, modifierKey );
          modifierKey = 0;
        }
        break;

      case RELEASED:
        HIDdevice.sendRelease();
        modifierKey = 0;
        break;
    }
  }
}
chegewara commented 2 years ago

Just a silly question, how do you get those symbols with hardware keyboard? hint: you have SHIFT key

rahmanshaber commented 2 years ago

I know that, but i don't want to hold the shift key to use the symbols. i want them directly.

chegewara commented 2 years ago

You dont have to hold shift key, you have to send it as modifier. What you are doing is wrong, because you dont send modifier keys, like SHIFT or CTRL, like normal keys. They are modifiers. I see you are sending left CTRL and you can add SHIFT with logic or | to it, but dont add it to key code. This is wrong #define KEYS_AT HID_KEY_2|KEYBOARD_MODIFIER_LEFTSHIFT /* @ */ SHIFT has to be sent togheter with capital letters or with symbols.

rahmanshaber commented 2 years ago

are you talking about this? but this does not work for all the keys


static void processKeys( void )
{
  if( !Keyboard.getKeys() ) return;

  // disable the keyboard when display is off
  if( !digitalRead( POWER_LCD ) ) return;

  int i;

  for( i = 0; i < LIST_MAX; i++ )
  {
    if( !Keyboard.key[i].stateChanged ) continue;

    uint8_t key = mapKey( Keyboard.key[i].kchar );

    if( key == KMAP_SWITCH || key == HARDWARE_TEST || key == KMOUSE_LEFT || 
        key == KMOUSE_RIGHT || key == EXPANSION_SWITCH ||  key == LCD_SWITCH  ) continue;

    switch( Keyboard.key[i].kstate )
    {
      case PRESSED:
        if( key == HID_KEY_CONTROL_LEFT )
        {
          HIDdevice.sendPress( 0, KEYBOARD_MODIFIER_LEFTCTRL );
          modifierKey = KEYBOARD_MODIFIER_LEFTCTRL;
        } 
        else if( key == HID_KEY_GUI_LEFT )
        {
          HIDdevice.sendPress( 0, KEYBOARD_MODIFIER_LEFTGUI );
          modifierKey = KEYBOARD_MODIFIER_LEFTCTRL;
        } 
        else
        {
                    if (key & KEYBOARD_MODIFIER_LEFTSHIFT) {
                        key ^= KEYBOARD_MODIFIER_LEFTSHIFT;
            HIDdevice.sendPress( key, KEYBOARD_MODIFIER_LEFTSHIFT );
                    } else {
            HIDdevice.sendPress( key, modifierKey );
            modifierKey = 0;
                    }
        }
        break;

      case RELEASED:
        HIDdevice.sendRelease();
        modifierKey = 0;
        break;
    }
  }
}
chegewara commented 2 years ago

Which keys are not working? Maybe you have on your PC installed keyboard layout which is not compatible? https://github.com/chegewara/EspTinyUSB/blob/master/src/hidkeylayout.h#L61-L71

rahmanshaber commented 2 years ago

KEYS_EXCL, KEYS_AT, KEYS_HASH, KEYS_DOLLAR, KEYS_PERCENT, KEYS_CARET, KEYS_AMP, KEYS_ASTERISK, KEYS_LRBRACKET, KEYS_RRBRACKET,

result YZ#$#$&&

i typed them in left to right order

chegewara commented 2 years ago

And i told you, this is not the correct definition:

#define KEYS_EXCL       HID_KEY_1|KEYBOARD_MODIFIER_LEFTSHIFT           /* ! */
#define KEYS_AT         HID_KEY_2|KEYBOARD_MODIFIER_LEFTSHIFT           /* @ */
#define KEYS_HASH       HID_KEY_3|KEYBOARD_MODIFIER_LEFTSHIFT           /* # */
#define KEYS_DOLLAR     HID_KEY_4|KEYBOARD_MODIFIER_LEFTSHIFT           /* $ */
#define KEYS_PERCENT    HID_KEY_5|KEYBOARD_MODIFIER_LEFTSHIFT           /* % */
#define KEYS_CARET      HID_KEY_6|KEYBOARD_MODIFIER_LEFTSHIFT           /* ^ */
#define KEYS_AMP        HID_KEY_7|KEYBOARD_MODIFIER_LEFTSHIFT           /* & */
#define KEYS_ASTERISK   HID_KEY_8|KEYBOARD_MODIFIER_LEFTSHIFT           /* * */
#define KEYS_LRBRACKET  HID_KEY_9|KEYBOARD_MODIFIER_LEFTSHIFT           /*( */
#define KEYS_RRBRACKET  HID_KEY_0|KEYBOARD_MODIFIER_LEFTSHIFT           /* ) */
rahmanshaber commented 2 years ago

i can't spare a button to use at a shift, so one can hold it and press the number to get the symbols.

Can you give me correct way to define the combination?

rahmanshaber commented 2 years ago

or just give me an example where pressing one button does a key combination with.

like ctrl +p for paste

chegewara commented 2 years ago

You dont have to use separate pin or make hardware modifications, just use code correctly. You can use example code to test if you will get correct output from:

HIDdevice.sendString("!@#$%^&*()");

This is close to what you need, but you cant modify key value: HIDdevice.sendPress( key, KEYBOARD_MODIFIER_LEFTSHIFT ); as second parameter is telling OS that you have pressed shift and/or ctrl and other special keys.

example of CTRL + P: HIDdevice.sendPress( 'p', KEYBOARD_MODIFIER_CTRL );

You can also use sendChar to send any of !@#$%^&*()