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

Text input with external keyboard #9540

Merged
merged 49 commits into from
Oct 29, 2022
Merged

Conversation

lykahb
Copy link
Contributor

@lykahb lykahb commented Sep 21, 2022

This adds the ability to input text with external keyboard. I have developed and tested this on Kobo Libra 2. Likely this works on any Linux device that has USB HID enabled in the kernel.

There is a corresponding PR koreader/koreader-base#1520

Here is an overview of changes:

  • Added a new plugin external-keyboard. It listens to USB events. When keyboard is plugged in or plugged out, it updates device and input configuration accordingly.
  • Added new fake events UsbDevicePlugIn and UsbDevicePlugOut that are emitted when a device is connected to a book reader that plays the role of USB host. The usage of the existing events UsbPlugIn and UsbPlugOut has not changed - they are used when a reader is connected to a host. The koreader-base has a related PR for those events.
  • Did a small refactoring of initialization for the modules FocusManager and InputText. They check device keyboard capabilities on their when the module is first loaded and store it. Some of the initialization code has been extracted into functions, so that we can re-initialize them when keyboard is (dis)connected.

What works now:

  • Typing text into a text input, changing case with Shift.
  • The behavior is stable. I tested this out with several keyboards and plugged in/out multiple times. The file descriptors for the unplugged devices are cleaned up from the array of file descriptors at input.c
  • Key shortcuts defined at inputtext

Future work:

  • Common motions with Ctrl and selection with Shift aren't implemented
  • CapsLock does not change the case
  • Input with the external only supports one layout, independent of the layout of the virtual keyboard. It would be nice to use the standard binary .kmap format and kernel mechanism for layouts, similar to how busybox does it.
  • The virtual keyboard is still shown on the screen for the inputs. I tried using inputtext with the physical keyboard module. But it seems to be coupled with the Kindle keyboard (special handling of the number row) and doesn't seem to interact well with inputtext.
  • Koreader has keyboard-based navigation. It does not activate when plugging in a keyboard because the instances of focus manager keep their state. It is difficult to propagate events to widgets that are not on the window_stack of the uimanager.

I left those features out to keep the scope smaller.


This change is Reviewable

Charging = true, NotCharging = true,
WakeupFromSuspend = true, ReadyToSuspend = true,
UsbDevicePlugIn = true, UsbDevicePlugOut = true,
},
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracted the event names into a set when I needed to add one more check if event is fake.

@@ -256,6 +265,8 @@ function Input:init()
self.event_map[10021] = "NotCharging"
self.event_map[10030] = "WakeupFromSuspend"
self.event_map[10031] = "ReadyToSuspend"
self.event_map[10040] = "UsbDevicePlugIn"
self.event_map[10041] = "UsbDevicePlugOut"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The event name for plugging into a host remains the same, "UsbPlugIn". I didn't update it to avoid potential breakage of any third party plugins outside of the koreader repository. If that's not a concern, I think that it's better to rename it to match names in koreader-base.

@@ -356,6 +356,49 @@ function UIManager:tickAfterNext(action)
end
--]]

function UIManager:debounce(seconds, immediate, action)
-- Ported from underscore.js
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is only called with immediate=false so far. I think that it's nice to keep it general, though.

@@ -249,6 +252,15 @@ function FocusManager:onFocusMove(args)
return true
end

function FocusManager:onPhysicalKeyboardConnected()
-- Re-initialize with new keys info. It's called without "self:" in case descendants override init.
FocusManager.init(self)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I experimented with adding the self:init() call too. This re-initializes the menus and adds key shortcuts (letters within squares) to the file browser. But it's not clear if calling init twice is safe in the general case. Also, the interface for the file browser refreshes not immediately after connecting a keyboard. I have to open a book and quit, which creates an impression of inconsistent behavior.

initDPadEvents()
else
Keyboard = require("ui/widget/physicalkeyboard")
end
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same logic, but extracted into functions.

@@ -768,6 +769,7 @@ local VirtualKeyboard = FocusManager:new{
}

function VirtualKeyboard:init()
FocusManager.init(self)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-initialize focus manager in case the keyboard was (dis)connected. That's necessary because VirtualKeyboard accesses fields builtin_key_events and extra_key_events on the DPad condition. If device has DPad, it assumes that those fields were initialized.

@Frenzie Frenzie added this to the 2022.09 milestone Sep 21, 2022
@Frenzie
Copy link
Member

Frenzie commented Sep 21, 2022

I'm now in the middle of moving; at a glance it looks good but I'm sure more in-depth comments will follow.

@NiLuJe
Copy link
Member

NiLuJe commented Sep 27, 2022

Got an OTG cable, just need to find some time to review this (and also figure out how this shit works on sunxi to actually test it ;p).

@NiLuJe
Copy link
Member

NiLuJe commented Oct 5, 2022

Heads up that the init shenanigans may have to be rethought after #9586 ;).

Copy link
Member

@NiLuJe NiLuJe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See also https://www.mobileread.com/forums/showthread.php?p=4135724 for a comment about fancy keyboards w/ custom HID drivers.

Reviewed 12 of 12 files at r1, all commit messages.
Reviewable status: all files reviewed, 17 unresolved discussions (waiting on @lykahb and @NiLuJe)


frontend/device/input.lua line 185 at r1 (raw file):

Previously, lykahb (Borys Lykah) wrote…

Extracted the event names into a set when I needed to add one more check if event is fake.

Good call, the if ladders were becoming unwieldy ;).


frontend/device/input.lua line 269 at r1 (raw file):

Previously, lykahb (Borys Lykah) wrote…

The event name for plugging into a host remains the same, "UsbPlugIn". I didn't update it to avoid potential breakage of any third party plugins outside of the koreader repository. If that's not a concern, I think that it's better to rename it to match names in koreader-base.

Yeah, better let sleeping dogs lie ;).


frontend/device/input.lua line 541 at r1 (raw file):

    end

    if self.fake_event_set[keycode] ~= nil then

Can be simplified to just if self.fake_event_set[keycode] then ;).


frontend/device/input.lua line 648 at r1 (raw file):

    end

    if self.fake_event_set[keycode] ~= nil then

Ditto


frontend/ui/uimanager.lua line 387 at r1 (raw file):

    local debounced_action_wrapper = function(...)
        n = select('#', ...)
        va = {...}

You can now use table.pack for this sort of stuff (and simplify the unpack calls to unpack(va).

Code quote:

        n = select('#', ...)
        va = {...}

frontend/ui/uimanager.lua line 1358 at r1 (raw file):

    if Input.fake_event_set[input_event] ~= nil then
        self.event_hook:execute("FakeInputEvent", input_event)
    end

I'd rather not have a dedicated event for them, actually ;). Or at least, not this way.

They already generate named events (well, not Event), so I'd rather see those being handled via UIManager.event_handlers (either via a mechanism to register new ones, or to simply add generic handlers in UIManager for the required ones that send and/or broadcast an actual named Event).

Code quote:

    if Input.fake_event_set[input_event] ~= nil then
        self.event_hook:execute("FakeInputEvent", input_event)
    end

frontend/ui/widget/focusmanager.lua line 257 at r1 (raw file):

Previously, lykahb (Borys Lykah) wrote…

I experimented with adding the self:init() call too. This re-initializes the menus and adds key shortcuts (letters within squares) to the file browser. But it's not clear if calling init twice is safe in the general case. Also, the interface for the file browser refreshes not immediately after connecting a keyboard. I have to open a book and quit, which creates an impression of inconsistent behavior.

Besides the rebase, this needs to be adapted since #9586.

At a quick glance, transforming the module-scope do block into an actual method that is called both at parsing time and on your events should do it?


frontend/ui/widget/inputtext.lua line 76 at r1 (raw file):

local function initTouchEvents()
    if Device.isTouchDevice() then

I'd prefer if we kept the : syntactic sugar (for consistency's sake, if anything) ;).


frontend/ui/widget/inputtext.lua line 286 at r1 (raw file):

local function initDPadEvents()
    if Device.hasDPad() then

Ditto


frontend/ui/widget/inputtext.lua line 308 at r1 (raw file):

-- only use PhysicalKeyboard if the device does not have touch screen
function InputText.initInputEvents()
    FocusManagerInstance = FocusManager:new{}

May need to be rethought after #9586


frontend/ui/widget/virtualkeyboard.lua line 772 at r1 (raw file):

Previously, lykahb (Borys Lykah) wrote…

Re-initialize focus manager in case the keyboard was (dis)connected. That's necessary because VirtualKeyboard accesses fields builtin_key_events and extra_key_events on the DPad condition. If device has DPad, it assumes that those fields were initialized.

AFAICT, this shouldn't be necessary anymore since #9586 (same for the previous one).


plugins/externalkeyboard.koplugin/find-keyboard.lua line 6 at r1 (raw file):

local KEY_UP = 103
local BTN_DPAD_UP = 0x220

Out of curiosity, where do the constants come from/what do they relate to?

Code quote:

local KEY_UP = 103
local BTN_DPAD_UP = 0x220

plugins/externalkeyboard.koplugin/main.lua line 39 at r1 (raw file):

local function no() return false end  -- luacheck: ignore

local ExternalKeyboard = WidgetContainer:new{

new -> extend


plugins/externalkeyboard.koplugin/main.lua line 122 at r1 (raw file):

function ExternalKeyboard:getOtgRole()
    local role = USB_ROLE_DEVICE
    local file = io.open(OTG_CHIPIDEA_ROLE_PATH, "r")

Unlikely to be an issue in practice but we try to enforce CLOEXEC usage regardless ;). -> "re".


plugins/externalkeyboard.koplugin/main.lua line 136 at r1 (raw file):

function ExternalKeyboard:setOTG(role)
    logger.dbg("ExternalKeyboard:setOTG setting to", role)
    local file = io.open(OTG_CHIPIDEA_ROLE_PATH, "w")

Ditto. "we"


plugins/externalkeyboard.koplugin/main.lua line 191 at r1 (raw file):

-- The keyboard events with the same key codes would override the original events.
-- That may cause embedded buttons to lose their original function and produce letters.
-- Can we tell from which device a key press comes? The koreader-base passes values of input_event which do not have file descriptors.

Yeah, that's a design limitation that hasn't been much more than a mild annoyance in some very edgy cases so far ;).

@NiLuJe
Copy link
Member

NiLuJe commented Oct 28, 2022

Tweaked a few things and added support for sunxi, so I can finally test all this ;p.

The less indirection layers there is, the happier I am ;o).
@NiLuJe
Copy link
Member

NiLuJe commented Oct 28, 2022

And I apparently managed to not break anything \o/.

10/28/22-22:02:23 DEBUG key event => code: 10040 (UsbDevicePlugIn), value: 1, time: 0.000000 
10/28/22-22:02:23 DEBUG AutoSuspend: onInputEvent 
10/28/22-22:02:23 DEBUG key event => code: 10040 (UsbDevicePlugIn), value: 1, time: 0.000000 
10/28/22-22:02:23 DEBUG AutoSuspend: onInputEvent 
10/28/22-22:02:23 DEBUG key event => code: 10040 (UsbDevicePlugIn), value: 1, time: 0.000000 
10/28/22-22:02:23 DEBUG AutoSuspend: onInputEvent 
10/28/22-22:02:23 DEBUG key event => code: 10040 (UsbDevicePlugIn), value: 1, time: 0.000000 
10/28/22-22:02:23 DEBUG AutoSuspend: onInputEvent 
10/28/22-22:02:23 DEBUG key event => code: 10040 (UsbDevicePlugIn), value: 1, time: 0.000000 
10/28/22-22:02:23 DEBUG AutoSuspend: onInputEvent 
10/28/22-22:02:23 DEBUG key event => code: 10040 (UsbDevicePlugIn), value: 1, time: 0.000000 
10/28/22-22:02:23 DEBUG AutoSuspend: onInputEvent 
10/28/22-22:02:23 DEBUG ExternalKeyboard:findAndSetupKeyboard found event path /dev/input/event5 has_dpad true 
10/28/22-22:02:23 DEBUG ExternalKeyboard:findAndSetupKeyboard found event path /dev/input/event4 has_dpad true

EDIT: With the latest base code:

10/29/22-03:55:16 DEBUG key event => code: 10040 (UsbDevicePlugIn), value: 4, time: 0.000000 
10/29/22-03:55:16 DEBUG AutoSuspend: onInputEvent 
10/29/22-03:55:16 DEBUG key event => code: 10040 (UsbDevicePlugIn), value: 5, time: 0.000000 
10/29/22-03:55:16 DEBUG AutoSuspend: onInputEvent 
10/29/22-03:55:16 DEBUG key event => code: 10040 (UsbDevicePlugIn), value: 6, time: 0.000000 
10/29/22-03:55:16 DEBUG AutoSuspend: onInputEvent 
10/29/22-03:55:16 DEBUG ExternalKeyboard:findAndSetupKeyboard found event path /dev/input/event5 has_dpad true 
10/29/22-03:55:16 DEBUG ExternalKeyboard:findAndSetupKeyboard found event path /dev/input/event4 has_dpad true

@NiLuJe
Copy link
Member

NiLuJe commented Oct 28, 2022

And because we're European weirdos: I heartily concur on future improvements to layout handling (French AZERTY here ;p).

Far too many years of early Counter-Strike gaming have made me familiar with the braintwist of using qwerty-on-azerty, though, but that's me ;p.

Copy link
Member

@NiLuJe NiLuJe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 3 of 3 files at r5, 2 of 2 files at r6, 2 of 2 files at r7, 5 of 6 files at r8, 1 of 1 files at r9, 1 of 1 files at r10, all commit messages.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on @lykahb)

@NiLuJe
Copy link
Member

NiLuJe commented Oct 28, 2022

Okay, this looks ready from my end, give me the go-ahead once you've confirmed I haven't mangled anything too much and it still works for you, and I'll merge this ;).

Thanks! (and sorry it took me this long to review/test :s).

This is the reason behind the previous commit: onCloseWidget is called
on an instance that will have died by the time the UsbDevicePlugOut
event come in, which means those are handled by the *nex* instance.

This also means that without the always on setting, the keyboard is
disconnected on view swap.
@NiLuJe
Copy link
Member

NiLuJe commented Oct 28, 2022

I'm mildly torn about the whole CloseWIdget thing, but I'll think some more about it post-merge ;).

(Possibly seeing if onExit works, even if it'd be a bit of a hack).

@lykahb
Copy link
Contributor Author

lykahb commented Oct 28, 2022

Hmm, I misused onCloseWidget then. That handler should only fire on Exit or Restart.


local function analyze_key_capabilities(long_bitmap_arr)
-- The heuristic is that a keyboard has at least as many keys as there are alphabet letters and some more.
local keyboard_min_number_keys = 64
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may be too few. When developing this feature I assumed the use case of a user carrying an ereader and a compact keyboard. A 40% keyboard has ~45-50 keys. I agree that 28 is too few, though.

Can you post capabilities and modalias of the device that was detected as a keyboard?

Copy link
Member

@NiLuJe NiLuJe Oct 29, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It stood at 98, IIRC (or maybe that's my local keyboard, can't remember ^^).

While, yeah, it was a bit too low, It didn't really help anyway, as the extra evdev device created with my test keyboard also exposes a crapload of keys (slightly smaller that the main one, true, but hard to discriminate heuristically nonetheless).

So, basically, that 64 came from counting the amount of keys in the central "letters+numbers+spacebar" block of a standard keyboard (which tallies at ~62 w/o function keys) and calling it a day.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

┌─(ROOT@europa:pts/0)──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────(~)─┐
└─(130:2.07:12%:03:58:72%:#)── cat /sys/class/input/event4/device/modalias                                                                                                                                                                                                                                                                             ──(Sat, Oct 29)─┘
input:b0003v1532p0118e0111-e0,1,4,11,14,k71,72,73,74,75,77,79,7A,7B,7C,7D,7E,7F,80,81,82,83,84,85,86,87,88,89,8A,8C,8E,96,98,9E,9F,A1,A3,A4,A5,A6,AD,B0,B1,B2,B3,B4,B7,B8,B9,BA,BB,BC,BD,BE,BF,C0,C1,C2,F0,ram4,l0,1,2,sfw
┌─(ROOT@europa:pts/0)──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────(~)─┐
└─(2.07:12%:03:58:72%:#)── cat /sys/class/input/event4/device/capabilities/key                                                                                                                                                                                                                                                                         ──(Sat, Oct 29)─┘
10000 7 ff9f207a c14057ff febeffdf ffefffff ffffffff fffffffe
┌─(ROOT@europa:pts/0)──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────(~)─┐
└─(2.07:12%:03:58:72%:#)── cat /sys/class/input/event5/device/modalias                                                                                                                                                                                                                                                                                 ──(Sat, Oct 29)─┘
input:b0003v1532p0118e0111-e0,1,2,3,4,14,k71,72,73,74,75,77,79,7A,7B,7C,7D,7E,7F,80,81,82,83,84,85,86,87,88,89,8A,8B,8C,8E,8F,90,96,98,9B,9C,9E,9F,A1,A3,A4,A5,A6,A7,A8,A9,AB,AC,AD,AE,B0,B1,B2,B3,B4,B5,B7,B8,B9,BA,BB,BC,BD,BE,BF,C0,C1,C2,CE,CF,D0,D1,D2,D4,D8,D9,DB,E0,E1,E4,EA,EB,F0,F1,F4,100,161,162,166,16A,16E,172,174,176,178,179,17A,17B,17C,17D,17F,180,182,183,185,188,189,18C,18D,18E,18F,190,191,192,193,195,197,198,199,19A,19C,1A0,1A1,1A2,1A3,1A4,1A5,1A6,1A7,1A8,1A9,1AA,1AB,1AC,1AD,1AE,1AF,1B0,1B1,1B7,1BA,240,241,242,243,244,245,246,250,251,r6,a20,28,29,2A,2B,2C,2D,2E,2F,30,31,32,33,34,35,36,37,38,39,3A,3B,3C,3D,3E,m4,lsfw
┌─(ROOT@europa:pts/0)──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────(~)─┐
└─(2.06:12%:03:58:72%:#)── cat /sys/class/input/event5/device/capabilities/key                                                                                                                                                                                                                                                                         ──(Sat, Oct 29)─┘
3007f 0 0 0 0 483ffff 17aff32d bf544446 0 0 1 130c13 b17c007 ffbf7bfa d941dfff febeffdf ffefffff ffffffff fffffffe

event4 is the one that actually reports keypresses.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, is there any difference between /sys/class/input/event[45]/device/properties?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope:

┌─(ROOT@europa:pts/0)──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────(~)─┐
└─(2.13:13%:07:59:71%:#)── cat /sys/class/input/event5/device/properties                                                                                                                                                                                                                                                                               ──(Sat, Oct 29)─┘
0
┌─(ROOT@europa:pts/0)──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────(~)─┐
└─(2.12:13%:07:59:71%:#)── cat /sys/class/input/event4/device/properties                                                                                                                                                                                                                                                                               ──(Sat, Oct 29)─┘
0

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

event4 is the only one with LEDs, though...

┌─(ROOT@europa:pts/0)──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────(~)─┐
└─(2.13:13%:08:01:71%:#)── ls -lash /sys/class/input/event5/device/                                                                                                                                                                                                                                                                                    ──(Sat, Oct 29)─┘
total 0      
     0 drwxr-xr-x    6 admin    root           0 Oct 29 07:59 .
     0 drwxr-xr-x    3 admin    root           0 Oct 29 07:59 ..
     0 drwxr-xr-x    2 admin    root           0 Oct 29 07:59 capabilities
     0 lrwxrwxrwx    1 admin    root           0 Oct 29 07:59 device -> ../../../0003:1532:0118.0035
     0 drwxr-xr-x    3 admin    root           0 Oct 29 07:59 event5
     0 drwxr-xr-x    2 admin    root           0 Oct 29 07:59 id
     0 -r--r--r--    1 admin    root        4.0K Oct 29 07:59 modalias
     0 -r--r--r--    1 admin    root        4.0K Oct 29 07:59 name
     0 -r--r--r--    1 admin    root        4.0K Oct 29 07:59 phys
     0 drwxr-xr-x    2 admin    root           0 Oct 29 07:59 power
     0 -r--r--r--    1 admin    root        4.0K Oct 29 07:59 properties
     0 lrwxrwxrwx    1 admin    root           0 Oct 29 07:59 subsystem -> ../../../../../../../../../../class/input
     0 -rw-r--r--    1 admin    root        4.0K Oct 29 07:59 uevent
     0 -r--r--r--    1 admin    root        4.0K Oct 29 07:59 uniq
┌─(ROOT@europa:pts/0)──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────(~)─┐
└─(2.12:13%:08:01:71%:#)── ls -lash /sys/class/input/event4/device/                                                                                                                                                                                                                                                                                    ──(Sat, Oct 29)─┘
total 0      
     0 drwxr-xr-x    9 admin    root           0 Oct 29 07:59 .
     0 drwxr-xr-x    3 admin    root           0 Oct 29 07:59 ..
     0 drwxr-xr-x    2 admin    root           0 Oct 29 07:59 capabilities
     0 lrwxrwxrwx    1 admin    root           0 Oct 29 08:00 device -> ../../../0003:1532:0118.0034
     0 drwxr-xr-x    3 admin    root           0 Oct 29 07:59 event4
     0 drwxr-xr-x    2 admin    root           0 Oct 29 08:00 id
     0 drwxr-xr-x    3 admin    root           0 Oct 29 08:00 input55::capslock
     0 drwxr-xr-x    3 admin    root           0 Oct 29 08:00 input55::numlock
     0 drwxr-xr-x    3 admin    root           0 Oct 29 08:00 input55::scrolllock
     0 -r--r--r--    1 admin    root        4.0K Oct 29 08:00 modalias
     0 -r--r--r--    1 admin    root        4.0K Oct 29 08:00 name
     0 -r--r--r--    1 admin    root        4.0K Oct 29 08:00 phys
     0 drwxr-xr-x    2 admin    root           0 Oct 29 08:00 power
     0 -r--r--r--    1 admin    root        4.0K Oct 29 07:59 properties
     0 lrwxrwxrwx    1 admin    root           0 Oct 29 07:59 subsystem -> ../../../../../../../../../../class/input
     0 -rw-r--r--    1 admin    root        4.0K Oct 29 07:59 uevent
     0 -r--r--r--    1 admin    root        4.0K Oct 29 08:00 uniq
┌─(ROOT@europa:pts/0)──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────(~)─┐
└─(2.11:13%:08:01:71%:#)── cat /sys/class/input/event4/device/uevent                                                                                                                                                                                                                                                                                   ──(Sat, Oct 29)─┘
PRODUCT=3/1532/118/111
NAME="Razer Razer DeathStalker"
PHYS="usb-sunxi-ohci-1/input0"
UNIQ=""
PROP=0
EV=120013
KEY=10000 7 ff9f207a c14057ff febeffdf ffefffff ffffffff fffffffe
MSC=10
LED=7
MODALIAS=input:b0003v1532p0118e0111-e0,1,4,11,14,k71,72,73,74,75,77,79,7A,7B,7C,7D,7E,7F,80,81,82,83,84,85,86,87,88,89,8A,8C,8E,96,98,9E,9F,A1,A3,A4,A5,A6,AD,B0,B1,B2,B3,B4,B7,B8,B9,BA,BB,BC,BD,BE,BF,C0,C1,C2,F0,ram4,l0,1,2,sfw
┌─(ROOT@europa:pts/0)──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────(~)─┐
└─(2.09:13%:08:01:71%:#)── cat /sys/class/input/event5/device/uevent                                                                                                                                                                                                                                                                                   ──(Sat, Oct 29)─┘
PRODUCT=3/1532/118/111
NAME="Razer Razer DeathStalker"
PHYS="usb-sunxi-ohci-1/input1"
UNIQ=""
PROP=0
EV=10001f
KEY=3007f 0 0 0 0 483ffff 17aff32d bf544446 0 0 1 130c13 b17c007 ffbf7bfa d941dfff febeffdf ffefffff ffffffff fffffffe
REL=40
ABS=ffffff01 0
MSC=10
MODALIAS=input:b0003v1532p0118e0111-e0,1,2,3,4,14,k71,72,73,74,75,77,79,7A,7B,7C,7D,7E,7F,80,81,82,83,84,85,86,87,88,89,8A,8B,8C,8E,8F,90,96,98,9B,9C,9E,9F,A1,A3,A4,A5,A6,A7,A8,A9,AB,AC,AD,AE,B0,B1,B2,B3,B4,B5,B7,B8,B9,BA,BB,BC,BD,BE,BF,C0,C1,C2,CE,CF,D0,D1,D2,D4,D8,D9,DB,E0,E1,E4,EA,EB,F0,F1,F4,100,161,162,166,16A,16E,172,174,176,178,179,17A,17B,17C,17D,17F,180,182,183,185,188,189,18C,18D,18E,18F,190,191,192,193,195,197,198,199,19A,19C,1A0,1A1,1A2,1A3,1A4,1A5,1A6,1A7,1A8,1A9,1AA,1AB,1AC,1AD,1AE,1AF,1B0,1B1,1B7,1BA,240,241,242,243,244,245,246,250,251,r6,a20,28,29,2A,2B,2C,2D,2E,2F,30,31,32,33,34,35,36,37,38,39,3A,3B,3C,3D,3E,m4,lsfw

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That holds true on my desktop, too, FWIW:

┌─(niluje@illyria:pts/18)──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────(~)─┐
└─(0.12:30%:08:02:%)── ls -lash /sys/class/input/event{9..12}/device/                                                                                                                                                                                                                                                                                  ──(Sat, Oct 29)─┘
/sys/class/input/event10/device/:
total 0
0 drwxr-xr-x 6 root root    0 Oct 27 00:12 .
0 drwxr-xr-x 6 root root    0 Oct 27 00:05 ..
0 drwxr-xr-x 2 root root    0 Oct 28 04:33 capabilities
0 lrwxrwxrwx 1 root root    0 Oct 29 08:02 device -> ../../../0003:1B1C:1B55.0001
0 drwxr-xr-x 3 root root    0 Oct 27 00:12 event10
0 drwxr-xr-x 2 root root    0 Oct 29 08:02 id
0 -rw-r--r-- 1 root root 4.0K Oct 29 08:02 inhibited
0 -r--r--r-- 1 root root 4.0K Oct 29 08:02 modalias
0 -r--r--r-- 1 root root 4.0K Oct 29 08:02 name
0 -r--r--r-- 1 root root 4.0K Oct 29 08:02 phys
0 drwxr-xr-x 2 root root    0 Oct 29 08:02 power
0 -r--r--r-- 1 root root 4.0K Oct 29 08:02 properties
0 lrwxrwxrwx 1 root root    0 Oct 27 00:12 subsystem -> ../../../../../../../../../class/input
0 -rw-r--r-- 1 root root 4.0K Oct 27 00:12 uevent
0 -r--r--r-- 1 root root 4.0K Oct 29 08:02 uniq

/sys/class/input/event11/device/:
total 0
0 drwxr-xr-x 6 root root    0 Oct 27 00:12 .
0 drwxr-xr-x 6 root root    0 Oct 27 00:05 ..
0 drwxr-xr-x 2 root root    0 Oct 28 04:33 capabilities
0 lrwxrwxrwx 1 root root    0 Oct 29 08:02 device -> ../../../0003:1B1C:1B55.0001
0 drwxr-xr-x 3 root root    0 Oct 27 00:12 event11
0 drwxr-xr-x 2 root root    0 Oct 29 08:02 id
0 -rw-r--r-- 1 root root 4.0K Oct 29 08:02 inhibited
0 -r--r--r-- 1 root root 4.0K Oct 29 08:02 modalias
0 -r--r--r-- 1 root root 4.0K Oct 29 08:02 name
0 -r--r--r-- 1 root root 4.0K Oct 29 08:02 phys
0 drwxr-xr-x 2 root root    0 Oct 29 08:02 power
0 -r--r--r-- 1 root root 4.0K Oct 29 08:02 properties
0 lrwxrwxrwx 1 root root    0 Oct 27 00:12 subsystem -> ../../../../../../../../../class/input
0 -rw-r--r-- 1 root root 4.0K Oct 27 00:12 uevent
0 -r--r--r-- 1 root root 4.0K Oct 29 08:02 uniq

/sys/class/input/event12/device/:
total 0
0 drwxr-xr-x 8 root root    0 Oct 27 00:05 .
0 drwxr-xr-x 6 root root    0 Oct 27 00:05 ..
0 drwxr-xr-x 2 root root    0 Oct 29 08:02 capabilities
0 lrwxrwxrwx 1 root root    0 Oct 29 08:02 device -> ../../../0003:1B1C:1B55.0001
0 drwxr-xr-x 3 root root    0 Oct 27 00:05 event12
0 drwxr-xr-x 2 root root    0 Oct 29 08:02 id
0 -rw-r--r-- 1 root root 4.0K Oct 29 08:02 inhibited
0 drwxr-xr-x 3 root root    0 Oct 27 00:12 js0
0 -r--r--r-- 1 root root 4.0K Oct 29 08:02 modalias
0 drwxr-xr-x 3 root root    0 Oct 27 00:12 mouse0
0 -r--r--r-- 1 root root 4.0K Oct 29 08:02 name
0 -r--r--r-- 1 root root 4.0K Oct 29 08:02 phys
0 drwxr-xr-x 2 root root    0 Oct 29 08:02 power
0 -r--r--r-- 1 root root 4.0K Oct 29 08:02 properties
0 lrwxrwxrwx 1 root root    0 Oct 27 08:11 subsystem -> ../../../../../../../../../class/input
0 -rw-r--r-- 1 root root 4.0K Oct 27 00:12 uevent
0 -r--r--r-- 1 root root 4.0K Oct 29 08:02 uniq

/sys/class/input/event9/device/:
total 0
0 drwxr-xr-x 9 root root    0 Oct 27 00:05 .
0 drwxr-xr-x 6 root root    0 Oct 27 00:05 ..
0 drwxr-xr-x 2 root root    0 Oct 28 23:14 capabilities
0 lrwxrwxrwx 1 root root    0 Oct 28 23:14 device -> ../../../0003:1B1C:1B55.0001
0 drwxr-xr-x 3 root root    0 Oct 27 00:05 event9
0 drwxr-xr-x 2 root root    0 Oct 28 23:14 id
0 -rw-r--r-- 1 root root 4.0K Oct 28 23:14 inhibited
0 drwxr-xr-x 3 root root    0 Oct 28 23:14 input9::capslock
0 drwxr-xr-x 3 root root    0 Oct 28 23:14 input9::numlock
0 drwxr-xr-x 3 root root    0 Oct 28 23:14 input9::scrolllock
0 -r--r--r-- 1 root root 4.0K Oct 28 23:14 modalias
0 -r--r--r-- 1 root root 4.0K Oct 28 23:14 name
0 -r--r--r-- 1 root root 4.0K Oct 28 23:14 phys
0 drwxr-xr-x 2 root root    0 Oct 28 23:14 power
0 -r--r--r-- 1 root root 4.0K Oct 28 23:14 properties
0 lrwxrwxrwx 1 root root    0 Oct 27 08:11 subsystem -> ../../../../../../../../../class/input
0 -rw-r--r-- 1 root root 4.0K Oct 27 00:12 uevent
0 -r--r--r-- 1 root root 4.0K Oct 28 23:14 uniq
┌─(niluje@illyria:pts/18)──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────(~)─┐
└─(0.34:30%:08:03:%)── cat /sys/class/input/event{9..12}/device/uevent                                                                                                                                                                                                                                                                                 ──(Sat, Oct 29)─┘
PRODUCT=3/1b1c/1b55/111
NAME="Corsair CORSAIR K70 RGB MK.2 LOW PROFILE Mechanical Gaming Keyboard"
PHYS="usb-0000:00:14.0-3/input0"
UNIQ="1001701DAF1E1C455A6FC297F5001BC5"
PROP=0
EV=12001f
KEY=3f000307ff 0 0 483ffff17aff32d bfd4444600000000 1 130ff38b17d007 ffe77bfad9415fff ffbeffdfffefffff fffffffffffffffe
REL=1040
ABS=100000000
MSC=10
LED=7
MODALIAS=input:b0003v1B1Cp1B55e0111-e0,1,2,3,4,11,14,k71,72,73,74,75,77,78,79,7A,7B,7C,7D,7E,7F,80,81,82,83,84,85,86,87,88,89,8A,8B,8C,8E,90,96,98,9B,9C,9E,9F,A1,A3,A4,A5,A6,A7,A8,A9,AB,AC,AD,AE,B0,B1,B2,B5,B6,B7,B8,B9,BA,BB,BC,BD,BE,BF,C0,C1,C2,CC,CE,CF,D0,D1,D2,D4,D8,D9,DB,DF,E0,E1,E4,E5,E6,E7,E8,E9,EA,EB,F0,F1,F4,100,161,162,166,16A,16E,172,174,176,177,178,179,17A,17B,17C,17D,17F,180,182,183,185,188,189,18C,18D,18E,18F,190,191,192,193,195,197,198,199,19A,19C,1A0,1A1,1A2,1A3,1A4,1A5,1A6,1A7,1A8,1A9,1AA,1AB,1AC,1AD,1AE,1AF,1B0,1B1,1B7,1BA,240,241,242,243,244,245,246,247,248,249,24A,250,251,260,261,262,263,264,265,r6,C,a20,m4,l0,1,2,sfw
PRODUCT=3/1b1c/1b55/111
NAME="Corsair CORSAIR K70 RGB MK.2 LOW PROFILE Mechanical Gaming Keyboard"
PHYS="usb-0000:00:14.0-3/input0"
UNIQ="1001701DAF1E1C455A6FC297F5001BC5"
PROP=0
EV=9
ABS=10000000000
MODALIAS=input:b0003v1B1Cp1B55e0111-e0,3,kra28,mlsfw
PRODUCT=3/1b1c/1b55/111
NAME="Corsair CORSAIR K70 RGB MK.2 LOW PROFILE Mechanical Gaming Keyboard"
PHYS="usb-0000:00:14.0-3/input0"
UNIQ="1001701DAF1E1C455A6FC297F5001BC5"
PROP=0
EV=9
ABS=10000000000
MODALIAS=input:b0003v1B1Cp1B55e0111-e0,3,kra28,mlsfw
PRODUCT=3/1b1c/1b55/111
NAME="Corsair CORSAIR K70 RGB MK.2 LOW PROFILE Mechanical Gaming Keyboard Mouse"
PHYS="usb-0000:00:14.0-3/input0"
UNIQ="1001701DAF1E1C455A6FC297F5001BC5"
PROP=0
EV=17
KEY=ffffffff0000 0 0 0 0
REL=903
MSC=10
MODALIAS=input:b0003v1B1Cp1B55e0111-e0,1,2,4,k110,111,112,113,114,115,116,117,118,119,11A,11B,11C,11D,11E,11F,120,121,122,123,124,125,126,127,128,129,12A,12B,12C,12D,12E,12F,r0,1,8,B,am4,lsfw

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto with the aforementioned old Logitech:

┌─(ROOT@europa:pts/0)──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────(~)─┐
└─(2.01:14%:08:07:70%:#)── cat /sys/class/input/event{4..5}/device/uevent                                                                                                                                                                                                                                                                              ──(Sat, Oct 29)─┘
PRODUCT=3/46d/c30e/110
NAME="Logitech HID compliant keyboard"
PHYS="usb-sunxi-ohci-1/input0"
UNIQ=""
PROP=0
EV=120013
KEY=10000 7 ff800000 7ff febeffdf f3cfffff ffffffff fffffffe
MSC=10
LED=7
MODALIAS=input:b0003v046DpC30Ee0110-e0,1,4,11,14,k71,72,73,74,75,77,79,7A,7B,7C,7D,7E,7F,80,81,82,83,84,85,86,87,88,89,8A,B7,B8,B9,BA,BB,BC,BD,BE,BF,C0,C1,C2,F0,ram4,l0,1,2,sfw
PRODUCT=3/46d/c30e/110
NAME="Logitech HID compliant keyboard"
PHYS="usb-sunxi-ohci-1/input1"
UNIQ=""
PROP=0
EV=13
KEY=fff ffffffff ffffffff 0 2000000 387a d800d001 1e0000 0 0 0
MSC=10
MODALIAS=input:b0003v046DpC30Ee0110-e0,1,4,k71,72,73,74,80,8C,8E,8F,9B,9C,9E,9F,A1,A3,A4,A5,A6,AB,AC,AD,D9,100,101,102,103,104,105,106,107,108,109,10A,10B,10C,10D,10E,10F,110,111,112,113,114,115,116,117,118,119,11A,11B,11C,11D,11E,11F,120,121,122,123,124,125,126,127,128,129,12A,12B,12C,12D,12E,12F,130,131,132,133,134,135,136,137,138,139,13A,13B,13C,13D,13E,13F,140,141,142,143,144,145,146,147,148,149,14A,14B,ram4,lsfw
┌─(ROOT@europa:pts/0)──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────(~)─┐
└─(2.01:14%:08:07:70%:#)── ls -lash /sys/class/input/event{4..5}/device/                                                                                                                                                                                                                                                                               ──(Sat, Oct 29)─┘
/sys/class/input/event4/device/:
total 0      
     0 drwxr-xr-x    9 admin    root           0 Oct 29 08:07 .
     0 drwxr-xr-x    3 admin    root           0 Oct 29 08:07 ..
     0 drwxr-xr-x    2 admin    root           0 Oct 29 08:07 capabilities
     0 lrwxrwxrwx    1 admin    root           0 Oct 29 08:08 device -> ../../../0003:046D:C30E.0039
     0 drwxr-xr-x    3 admin    root           0 Oct 29 08:07 event4
     0 drwxr-xr-x    2 admin    root           0 Oct 29 08:08 id
     0 drwxr-xr-x    3 admin    root           0 Oct 29 08:08 input60::capslock
     0 drwxr-xr-x    3 admin    root           0 Oct 29 08:08 input60::numlock
     0 drwxr-xr-x    3 admin    root           0 Oct 29 08:08 input60::scrolllock
     0 -r--r--r--    1 admin    root        4.0K Oct 29 08:08 modalias
     0 -r--r--r--    1 admin    root        4.0K Oct 29 08:08 name
     0 -r--r--r--    1 admin    root        4.0K Oct 29 08:08 phys
     0 drwxr-xr-x    2 admin    root           0 Oct 29 08:08 power
     0 -r--r--r--    1 admin    root        4.0K Oct 29 08:08 properties
     0 lrwxrwxrwx    1 admin    root           0 Oct 29 08:07 subsystem -> ../../../../../../../../../../class/input
     0 -rw-r--r--    1 admin    root        4.0K Oct 29 08:07 uevent
     0 -r--r--r--    1 admin    root        4.0K Oct 29 08:08 uniq

/sys/class/input/event5/device/:
total 0      
     0 drwxr-xr-x    6 admin    root           0 Oct 29 08:07 .
     0 drwxr-xr-x    3 admin    root           0 Oct 29 08:07 ..
     0 drwxr-xr-x    2 admin    root           0 Oct 29 08:07 capabilities
     0 lrwxrwxrwx    1 admin    root           0 Oct 29 08:08 device -> ../../../0003:046D:C30E.003A
     0 drwxr-xr-x    3 admin    root           0 Oct 29 08:07 event5
     0 drwxr-xr-x    2 admin    root           0 Oct 29 08:08 id
     0 -r--r--r--    1 admin    root        4.0K Oct 29 08:08 modalias
     0 -r--r--r--    1 admin    root        4.0K Oct 29 08:08 name
     0 -r--r--r--    1 admin    root        4.0K Oct 29 08:08 phys
     0 drwxr-xr-x    2 admin    root           0 Oct 29 08:08 power
     0 -r--r--r--    1 admin    root        4.0K Oct 29 08:08 properties
     0 lrwxrwxrwx    1 admin    root           0 Oct 29 08:07 subsystem -> ../../../../../../../../../../class/input
     0 -rw-r--r--    1 admin    root        4.0K Oct 29 08:07 uevent
     0 -r--r--r--    1 admin    root        4.0K Oct 29 08:08 uniq

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ev seems to differ significantly. I'll see if it can be used for classification.

@NiLuJe
Copy link
Member

NiLuJe commented Oct 29, 2022

Hmm, I misused onCloseWidget then. That handler should only fire on Exit or Restart.

Yeah, I'll look into it tomorrow; I want to merge the first version as-is, because it works regardless ;).

Copy link
Member

@NiLuJe NiLuJe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 3 of 4 files at r11, 2 of 2 files at r12, all commit messages.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @lykahb)

This reverts commit 5837412.
@NiLuJe
Copy link
Member

NiLuJe commented Oct 29, 2022

I'll merge this as-is, to make working on further tweaks easier (and dealing with git annoyances easier, too ;p).

Thanks!

@NiLuJe NiLuJe merged commit 9b2201a into koreader:master Oct 29, 2022
@poire-z
Copy link
Contributor

poire-z commented Nov 3, 2022

Seeing this on my emulator, dunno if it is expected:

11/03/22-18:04:46 DEBUG Plugin plugins/autostandby.koplugin/main.lua has been disabled.
mount: /sys/kernel/debug: must be superuser to use mount.
11/03/22-18:04:46 WARN  ExternalKeyboard: Failed to mount debugfs
11/03/22-18:04:46 DEBUG Plugin plugins/externalkeyboard.koplugin/main.lua has been disabled.

@NiLuJe
Copy link
Member

NiLuJe commented Nov 3, 2022

That is expected, yes, it gets disabled automatically if debugfs can't be mounted, so the check is done at require time (well, at dofile via pluginloader, but same result ;p).

That just made me realize that we could just silently fail if not root, though ;).

@hius07
Copy link
Member

hius07 commented Nov 11, 2022

Can this be limited to dbg only? Kindle Voyage, on every restart:

mount: none already mounted or /sys/kernel/debug busy
mount: according to mtab, debugfs is already mounted on /sys/kernel/debug
11/11/22-15:02:18 WARN  ExternalKeyboard: Failed to mount debugfs 

@NiLuJe
Copy link
Member

NiLuJe commented Nov 11, 2022

Oops, completely forgot about that one ;o).

Also, that test really shouldn't fail on an already mounted warning, that's weird.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants