qmk / qmk_firmware

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

VendorID dependent macros #120

Closed wez closed 8 years ago

wez commented 8 years ago

I had the idea that it would be nice to have cut/copy/paste keys that work by default on both Windows and OS X systems (I plan to connect my keyboard via a KVM).

I think I can implement this by using macros that send the appropriate key sequences based on the USB VendorID of the host computer system.

Couple of questions:

  1. Is it possible to make this distinction in the qmk_firmware? I'm planning on checking this during matrix_init_user and stashing the vendorid in a global.
  2. Can you point me to a function in the LUFA code (I'm assuming that's the right ballpark) that might help?
  3. Am I going to get screwed by the KVM anyway?

I'm using an ErgoDox EZ and I'm quite handy with C, I'm just unfamiliar with the USB spec and library.

wez commented 8 years ago

... vendorid may not be literally the thing to check, but if there is something that we can test from the keyboard side to detect an OS X host, that will probably be sufficient for my purposes.

jackhumbert commented 8 years ago

We explored some options in this thread! The one I'm most interested in is the passive method mentioned.

If you're looking around, the HID spec is the one you'd want to look at, but from what we could tell, that sort of operation isn't permitted. I'm interested to hear about your findings though!

wez commented 8 years ago

Ah. Coming up with the fingerprinting stuff is a bit out of scope of the time I'd like to spend on this :-/

The other alternative that came to mind was to use the hid_listen program as the base for a simple daemon process that notices when the keyboard is attached and sends a control request to the keyboard containing some basic OS information.

eltang commented 8 years ago

I found a way to program a keyboard to automatically detect the OS of its host with reasonable accuracy and minimal interference with the user experience. However, a change to the PCB will be required. Specifically, the chip needs an alternate power source to use while it completely severs its USB connection to its host (all four pins). Here is a quick rundown of what the keyboard will do.

  1. Connect to the host.
  2. Turn on Caps Lock.
  3. Simulate the keyboard being unplugged and plugged back in.
  4. If the host is a Mac, Caps Lock will have turned off. Set a mac_host flag. Else, turn off Caps Lock.

I have no experience in electrical engineering, but @jackhumbert does.

jackhumbert commented 8 years ago

Have you tried disabling things on the firmware side of things via USB_Disable()? I'm guessing Windows/Linux does things differently?

mecanogrh commented 8 years ago

I tried this on a Mac (physically unplugging and plugging) and Caps Lock turned off :)

…kidding

eltang commented 8 years ago

@jackhumbert I tried that, but the Mac only recognizes that the keyboard has been unplugged and turns off Caps Lock if power stops flowing. Here's why this works: Macs store a state for Caps Lock for every keyboard, so it makes sense to turn Caps Lock off for keyboards as they are unplugged. Windows and Linux, on the other hand, have a universal state for Caps Lock, so it instead makes sense to keep it on. I asked @a0-c what my options were for implementing this and he said I would need to use relays to physically break the USB connections.

@mecanogrh I got that backwards. I edited my comment.

a0-c commented 8 years ago

You can probably use the USB_Detach function of LUFA http://www.fourwalledcubicle.com/files/LUFA/Doc/120219/html/group___group___u_s_b_management___x_m_e_g_a.html#ga8a8d39c5926d319f8e7d897d5ba666b8

Relays would be needed only for electrical disconnection.

eltang commented 8 years ago

@a0-c I'll try that right now. I've never laid eyes on that documentation until now. Do you know if USB_Init and USB_Disable need to be called in conjunction with USB_Attach and USB_Detach?

eltang commented 8 years ago

@a0-c No dice. I looked at the code and USB_Disable already calls USB_Detach. Apple can be frustrating.

eltang commented 8 years ago

Another idea is to use a second power-only USB cable. I remember I tried one of those cables with two plugs on the computer side and unplugging the main plug seemed to work.

eltang commented 8 years ago

I just remembered that Karabiner or Seil can mess with this behavior. Maybe @tekezo can weigh in on this?

algernon commented 8 years ago

Perhaps this could be of use?

jackhumbert commented 8 years ago

@algernon interesting! Thanks for sharing :)

KapJI commented 2 years ago

In case someone is still interested in this or find this in Google:

I made a post about how this can be done in QMK: https://www.reddit.com/r/olkb/comments/x1ezbg/way_to_detect_host_os_in_qmk/