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

orbkb: Keyboard handling library for Orbital #941

Closed
wants to merge 1 commit into from
Closed

orbkb: Keyboard handling library for Orbital #941

wants to merge 1 commit into from

Conversation

kaedroho
Copy link

@kaedroho kaedroho commented May 10, 2017

First up, apologies for this massive drive-by PR! I did this for fun and wasn't expecting to write this much code (or even submit any of it) when I started so please don't feel any pressure to merge it. I think this contains some useful new features so thought you might be interested!

Problem:

There's a number of basic features missing from RedoxOS's current keyboard implementation.

Solution:

I've created a new library called orbkb* which contains a bunch of keyboard handling code and integrated it into the rest of the system. This adds the following new features to RedoxOS:

  • Modifier keys
  • Alt-Gr key (US layout treats it as another Alt key)
  • Lock keys
  • Numpad (including actions when numlock is off)
  • Key repeat detection
  • Logical keyboard input

* The reason it's separate from orbclient is because I couldn't get cargo test to work.

Components of orbkb

  • KeyboardState: tracks the state of a physical keyboard and converts physical keyboard events ("key 30 has been pressed") into logical keyboard events ("the letter 'a' has been inputted")
  • ScancodeReader: A struct that takes a stream of ps2 scancodes. Remaps scancodes to keycodes (using Linux's keycode mapping) and emits key events
  • Key: An struct that wraps a keycode and provides some convenience methods.
  • Layout: A mapping of keycodes to symbols and other layout configuration (eg, does the layout have an Alt-Gr key?)
  • KeyboardEvent/LogicalKeyboardEvent: Structs used to communicate keyboard events around redox

orbkb is rexported from orbclient as orbclient::kb. I think it would be best to merge it into orbclient when the test issues are fixed.

Why logical keyboard events?

Logical keyboard events simplify the keyboard handling in applications that are driven by text input (terminals, text editors, etc) as there's a number of cases when these type of applications should not intepret a a physical "key press" event as user input, for example:

  • When a key is pressed with the control key pressed (Ctrl+c)
  • When a numpad key is pressed with the numlock off
  • When using compose/multi-key input
  • When using accesibility features such as sticky keys or debouncing

LKEs allow these features to be implemented centrally in ps2d and applications just have to listen for keyboard events that contain a "logical" part. Applications that rely on physical keyboard input, such as games, can just ignore the "logical" part.

Changes introduced by this pull request:

  • Implemented orbkb library
  • Integrated with orbclient
  • Integrated with terminal, browser, orbtk and vesad then updated these where necessary to use logical events

Drawbacks:

  • Logical keyboard events are something I made up and I've not seen anything like them used anywhere else so they could be a bad idea.

TODOs:

  • Rewrite bepo and azerty layouts in new format
  • Keyboard leds
  • Investigate non-latin keyboard support

Fixes:

None of the issues above are reported in a Github issue

State: Ready

Blocking/related:

@kaedroho kaedroho closed this Jul 3, 2017
@kaedroho kaedroho deleted the feature/orbkb branch July 3, 2017 09:52
@kaedroho
Copy link
Author

kaedroho commented Nov 18, 2017

@jackpot51 Wondering if you had any thoughts on this? Or if you would you like to postpone keyboard changes to later on? I'm happy to rebase, reopen and make changes if you think this library is worth having. Should I open up a discussion on discource first?

@jackpot51
Copy link
Member

Sorry for not noticing this when it was submitted. This seems to be a major breaking change, but one that is necessary at some point.

I would like to see how this can help with selecting different languages for the keyboard. Applications should be able to get the physical scancode and the logical one depending on their use case.

@kaedroho
Copy link
Author

kaedroho commented Nov 20, 2017

Thanks @jackpot51!

I would like to see how this can help with selecting different languages for the keyboard.

Like the current implementation, this only supports Latin keyboard layouts. The idea is that orbkb will eventually support many kinds of keyboards and other input methods. For now, this PR is mostly about enabling some missing features that are common to all languages and introducing the "logical keyboard event".

I've moved the keyboard layouts into a data structure, which should make it a little easier to move the layouts into external files.

Applications should be able to get the physical scancode and the logical one depending on their use case.

The physical AT scancodes are remapped to virtual scancodes in scancode.rs. Every single keyboard action fires an event with the "virtual scancode" even if that action didn't lead to a "logical keyboard event" being fired.

We need to remap them to "virtual scancodes" as USB keyboards use a completely different set of scancodes to PS2 keyboards (at the moment, we're relying on the BIOS to perform the remapping for us, but I'm sure we would want to write a USB HID driver eventually as this is required for bluetooth keyboards). Each scancode can be represented by a byte, which allows us to use a small bitmap to track the state of every key.

Note: I've given each key a name like KEY_W following the convention Linux uses, but these names have nothing to do with the keyboard layout. On an azerty keyboard, KEY_W would correspond to the letter "z". Alternatively, we could name these keycodes after their physical location (this key is called AD02 in XKB. Meaning "Alphanumeric, row D, column 02).

The "logical keyboard event" idea is perhaps the most controversial thing in this PR. The idea is to implement common advanced keyboard features such as the compose key and input methods (on screen keyboard, speech recognition, pinyin, etc) in Orbital so applications wouldn't need to care about the user's IME/accessibility settings. But currently, this event only serves to differentiate a key presses for inputting text from key presses that should be interpreted as commands (eg, c key pressed while Ctrl key being held down).

But this job could also be done by a library on the client side, which I believe is how Wayland does it. Perhaps making orbkb part of orbclient and ditching this event would be a better approach? (but I think lock keys and virtual scan codes should be implemented in the keyboard driver anyhow).

@jackpot51 jackpot51 self-assigned this Nov 20, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants