Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No volume media key #17

Open
ghost opened this issue May 21, 2018 · 4 comments
Open

No volume media key #17

ghost opened this issue May 21, 2018 · 4 comments
Labels
topic: code Related to content of the project itself type: enhancement Proposed improvement

Comments

@ghost
Copy link

ghost commented May 21, 2018

Hello it's possible to add these fallowing keys ?

KEY_VOLUME_DOWN
KEY_VOLUME_UP
KEY_MUTE

thanks

@thekunalsaini
Copy link

@Zeskye in which you want to add this library?

@yann44
Copy link

yann44 commented Dec 25, 2021

Hi,
Yes that's a great idea !!!

Maybe inside the keyboard.h ?

I try to find the hex code, but unlucky for the moment

@per1234
Copy link
Contributor

per1234 commented Mar 6, 2022

There is some valuable discussion on this subject at #26

@per1234 per1234 added topic: code Related to content of the project itself type: enhancement Proposed improvement labels Mar 6, 2022
@edgar-bonet
Copy link
Collaborator

Coming back to this issue. Here is a summary of the information I could gather about the volume media keys, and a proposal for moving forward.

The Keyboard library does not support the keys Mute, Volume up, and Volume down. Adding this support does not seem to be completely trivial.

Scan codes

According to the Android documentation, each of these keys can be represented by multiple scan codes (technically called “USB usage codes”). These codes belong to two different sets called “pages”. If I understand correctly, each page represents a specific type of HID device.

HID keyboard and keypad page (0x07):

code key
0x7f KEY_MUTE
0x80 KEY_VOLUMEUP
0x81 KEY_VOLUMEDOWN
0xed KEY_VOLUMEUP
0xee KEY_VOLUMEDOWN
0xef KEY_MUTE

HID consumer page (0x0c):

code key
0xe2 KEY_MUTE
0xe9 KEY_VOLUMEUP
0xea KEY_VOLUMEDOWN

My keyboard uses the “HID consumer page”. It presents itself to the host as two different USB sources: a keyboard (page 0x07) and a consumer device (page 0x0c). Normal key notifications are sent from the keyboard source, but volume media key notifications are sent from the consumer device source.

Using this approach in the Keyboard library would incur a significant cost in terms of complexity and code size, as the Arduino would need to impersonate two USB devices instead of one. Using any of the scan codes available in the keyboard page should be easier, but it remains to be seen how well these codes are supported by common operating systems.

Library-specific encoding

When one issues Keyboard.press(c), the byte c is interpreted in one of three different modes, depending on what range it belongs to:

mode c range interpretation
ASCII 0x00 – 0x7f scan code = KeyboardLayout[c]
modifier 0x80 – 0x87 modifier number = c - 0x80
raw 0x88 – 0xff scan code = c - 0x88

The ASCII mode is used for typing ASCII text (e.g., with Keyboard.print()). The “modifier” mode is used by the modifier macros (KEY_LEFT_CTRL et al.). The raw mode is used by all the other KEY_* macros. For example, we have

#define KEY_RETURN        0xB0

which is interpreted as the scan code 0xB0 - 0x88 = 0x28, which is indeed the USB scan code for the Return key.

It would seem natural to use this mode for the volume media keys, with something like

#define KEY_MUTE (0x7f + 0x88)

This, however, cannot work, as the result (0x107) does not fit in a byte. Only scan codes in the range 0x00 – 0x77 can be encoded this way.

Proposal

Here is an idea: we could change the interpretation of the raw mode this way:

mode c range interpretation
raw 0x88 – 0xff scan code = c - 0x78

The range of scan codes encodable by this scheme would then be shifted from 0x00 – 0x77 to to 0x10 – 0x87:

  • We loose the codes 0x00 – 0x0f. This should be no issue, as the only keys within this range are the letters A – L (in a US keyboard), which are always encodable in ASCII mode (in all supported layouts).

  • We gain the codes 0x78 – 0x87, which includes one possible encoding for each of the three volume media keys.

I can implement this change in a pull request, but this would need some testing. According to the Deskthority Wiki, these scan codes come from the volume media keys on the quite exotic Sun Type 6 and Sun Type 7 keyboards, and should be supported by Unix and Linux. Support by other OSes is uncertain. Personally, I would only be able to test this on an Ubuntu host, and I don't think the change would be worth implementing unless someone can test it under Windows and macOS.

Any volunteers?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: code Related to content of the project itself type: enhancement Proposed improvement
Projects
None yet
Development

No branches or pull requests

4 participants