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

How to catch (neo2) capslock activity? #92

Closed jH4nn3s closed 8 years ago

jH4nn3s commented 8 years ago

Hello guys,

Sorry, but I have absolutely no experience with keyboard firmware and little proper experience with C++... I'm currently trying to associate some LED patterns on my ergodox EZ with the "capslock-active"-mod/event thingy under neo2 layout set in the OS. neo2 (de-)activates capslock upon pressing both shift keys simultaneously.

So far, I have figured out how to manipulate LEDs from within the matrix_scan_user(void)-"loop" in my custom keymap_BLAH.c and associate, for example, a LED activity pattern with a particular Layer being active.

However, I have no good idea how to properly get a handle on a key-press/release event or modifier being active, such as capslock. At this point, my best efforts amount to having copied the function static bool scan_keycode(uint8_t keycode) from bootmagic.c into my custom keymap_BLAH.c and now i can unelegantly catch key-events somehow... By setting some global flags I furthermore managed to detect key-releases for left and right shift keys, which induce somewhat correctly an additional custom "capslock-led-flag" and consequently some LED animation. However, sometimes if I press too fast, capslock gets activated but my diletant "capslock-led-flag" did not catch it.

What would be the proper way of detecting "capslock-active"-mod? Or any other events, for that matter. Any pointers in the right direction or towards more detailed documentation would be highly appreciated ;)

Btw, is there a chance of harming the leds with buggy blink patterns?!

thx for reading, johannes

DidierLoiseau commented 8 years ago

As I guess the caps-lock implemented in neo2 is the standard OS caps-lock, you can actually retrieve the status like this:

if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) {
  ergodox_right_led_3_on();
}

No fancy stuff needed :-)

DidierLoiseau commented 8 years ago

Concerning the LEDs, I'm no expert but I think they are usually made to blink. In fact, this is the only way to dim a single LED. Well, actually, give the illusion of being dimmed.

jH4nn3s commented 8 years ago

Ah, that works, thanx a lot!! If you don't mind another silly question: How does this work? Could you explain the boolean expression? host_keyboard_leds() asks a driver object for the field keyboard_leds... which has a particular value if capslock is on...?

eltang commented 8 years ago

@DidierLoiseau I have a Planck and my keyboard has no LEDs. Is there a similar way I can retrieve the status of my Caps Lock key?

jackhumbert commented 8 years ago

@Eric-L-T it should - just try the boolean (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) in an if statement to output a letter or something (as a macro - not in a loop).

@jH4nn3s the host_keyboard_leds() gets the host's LED status, and the & (1<<USB_LED_CAPS_LOCK) looks at only the caps lock LED. You can see a lot of examples of this here.

LEDs are made to blink really fast - that's how the brightness control (PWM) works in the firmware.

mecanogrh commented 8 years ago

@jackhumbert does it means there is a way to control all or some leds individually? at the moment I'm only firing all leds when capslock is on through a macro.

jackhumbert commented 8 years ago

This is just referencing the LED state between the firmware and the OS - the terminology is reminiscent of all keyboards having those LEDs. I'm not sure what keyboard you're referring to, but the Planck's keyswitch LEDs are all-or-none.

mecanogrh commented 8 years ago

Talking planck here, that's what I thought but suddenly reading through this let me thought there might be a way. But for the planck it would mean adding wires I guess. Now I have a neat cosmetic idea for leds :)