qmk / qmk_firmware

Open-source keyboard firmware for Atmel AVR and Arm USB families
https://qmk.fm
GNU General Public License v2.0
18.09k stars 38.89k forks source link

Add special chars for us layout #173

Closed GCorbel closed 8 years ago

GCorbel commented 8 years ago

I'm trying to add a mode for french special chars in the colemak layout. In order to do that, I need to find a way to add special chars with the US layout. I think the simplest way is to use keycode, like 130 for eacute.

I tried to define a type like this :

#define FR_EACU LALT(0x130)

I also tried with 0x0130 or 130 but it does not work.

Is there a way to do it?

GCorbel commented 8 years ago

I seached again a solution and I didn't find anything. Is there a solution?

mecanogrh commented 8 years ago

Get position of eacute on your OS input method, define it. Example: on the OSX US Qwerty input method the Euro sign is produced by pressing Shift+Option+2 so I defined it with #define KC_EURO LSFT(LALT(KC_2)). Now for the keycodes, look at tmk_core/common/keycode.h.

mecanogrh commented 8 years ago

Note that codes handled in qmk are USB HID codes and not ASCII read the HID table here http://www.usb.org/developers/hidpage/Hut1_12v2.pdf

GCorbel commented 8 years ago

@mecanogrh thanks for answer. I think some characters are not available with a single keystroke and have to use dead keys even with the us international keyboard or with the french layout like the character "ù".

I have to read the document you just gave.

Thanks for your help!

mecanogrh commented 8 years ago

@GCorbel yes indeed, the thing to grasp here is that you are depending on the USB HID table to send keystrokes and that characters generation is handled by your input method. If you want to output un e avec un accent aigu you must either use the unicode capabilities of the firmware and have your OS input method set to unicode (but can be a complicated process) or use a macro to generate the dead key sequence then the e.

mecanogrh commented 8 years ago

read the Macro examples on the front page here.

GCorbel commented 8 years ago

I think marco is the answer. On linux, I can type Ctrl + Shift + u for unicode chars. I have to ckeck https://en.wikipedia.org/wiki/List_of_Unicode_characters to find correct values.

mecanogrh commented 8 years ago

You don't have to mix Macro and Unicode. You can use a Macro with the sequence you use to output the character normally.

GCorbel commented 8 years ago

I think

MACRO( T(LSHFT(CTL_T(U))), T(E), T(8), END  );

Will give è.

@mecanogrh you're right. It will produce the same result if I use normal keystrokes. Typing unicode code allow to have chars like ⍅ or 玄 but I don't know it's useful.

Anyway, thanks for your help.

GCorbel commented 8 years ago

It works with

return MACRO(D(RSFT), D(LCTRL), T(U), U(RSFT), U(LCTRL), T(E), T(8), T(SPACE), END  );

I close this issue. @ezuk or @jackhumbert please, let me know if there is other solutions.

Thanks!

ezuk commented 8 years ago

@GCorbel not that I know.. @jackhumbert what do you think?

Way to go on solving this btw, thanks to @mecanogrh!

GCorbel commented 8 years ago

For the moment, I did that :

const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
  // MACRODOWN only works in this function
      switch(id) {
        case 0:
            if (record->event.pressed) {
              register_code(KC_RSFT);
            } else {
              unregister_code(KC_RSFT);
            }
            break;
        case 1:
            /* è */
            if (record->event.pressed) {
                return MACRO(D(RSFT), D(LCTRL), T(U), U(RSFT), U(LCTRL), T(E), T(8), T(SPACE), END  );
            }
        case 2:
            /* é */
            if (record->event.pressed) {
                return MACRO(D(RSFT), D(LCTRL), T(U), U(RSFT), U(LCTRL), T(E), T(9), T(SPACE), END  );
            }
        case 3:
            /* ê */
            if (record->event.pressed) {
                return MACRO(D(RSFT), D(LCTRL), T(U), U(RSFT), U(LCTRL), T(E), T(A), T(SPACE), END  );
            }
        case 4:
            /* ë */
            if (record->event.pressed) {
                return MACRO(D(RSFT), D(LCTRL), T(U), U(RSFT), U(LCTRL), T(E), T(B), T(SPACE), END  );
            }
        case 5:
            /* ù */
            if (record->event.pressed) {
                return MACRO(D(RSFT), D(LCTRL), T(U), U(RSFT), U(LCTRL), T(F), T(9), T(SPACE), END  );
            }
        case 6:
            /* ç */
            if (record->event.pressed) {
                return MACRO(D(RSFT), D(LCTRL), T(U), U(RSFT), U(LCTRL), T(E), T(7), T(SPACE), END  );
            }
        case 7:
            /* à */
            if (record->event.pressed) {
                return MACRO(D(RSFT), D(LCTRL), T(U), U(RSFT), U(LCTRL), T(E), T(0), T(SPACE), END  );
            }
      }
    return MACRO_NONE;
};

I can't do capital letter with special chars. Is there a function to change the macro if shift is pressed?

Thanks @ezuk I really like my Ergodox EZ!

ezuk commented 8 years ago

Thank you @GCorbel!! :) That's so awesome to hear :)

mecanogrh commented 8 years ago

@GCorbel you can use a new layer that triggers capitalized ù, é, à, etc. with macros at the same keys positions you used for lower cases.