Capturing Global Keyboard Events On Linux With NodeJS - linux

I have a headless Debian ARM machine that I'm running Node on. The device has hard buttons that are mapped to normal keyboard events using gpio-keys.
My goal is to capture the global events from both the hard buttons as well as any attached keyboards in Node. I need a solution that can capture the keydown/keyup events independently of the terminal that it's run in (it will be run over an SSH session). It doesn't have to be cross-platform, as long as it works on ARM Debian I'll accept it.
I am imagining something reading directly from whatever sysfs attributes are necessary, but that's not a requirement.
Can anyone help me on this? I've been stuck for a while.

One of the device files /dev/input/event* will represent the gpio-keys device. You can figure out which one in a number of ways; one easy one is to look at the contents of the uevent file for the device, e.g. /sys/class/input/event0/device/uevent. It'll contain a number of useful key-value properties.
Once you've figured out which device you want, you can open and read from it. It'll return a stream of struct input_events, as defined in <linux/input.h>. These events will correspond to presses and releases for each of your buttons.
You may also want to take a look for existing solutions for at least part of the problem, such as node-keyboard: https://github.com/Bornholm/node-keyboard

Related

Not visible/refreshed objects or part of screen

Do You know the situation when on screen in application you have not fully refreshed view? You need to hover the mouse on the object to make it visible/refreshed? Or You need to open close page/screen to refresh all objects?
I have PC-box with Win10. PC has only one DVI port, so extended the screens with USB to DVI adapter (3x VGA2725) and desktop is extended to 4 monitors. Each monitor is used to show the same software (SCADA) 4 different 'windows'. On the screens with adapters there is problem with view/screen refresh, like a 'artefacts' or part of screen not updated. In that situation the page needs to be closed/opened again. The CPU and disk is not overloaded.
Could You help me if above is more software issue or more hardware issue? Shell I look for bad drivers? What shall I check?
EDIT: sorry, missed the fact that the adaptor is multiplying the signal to all monitors.
Nevertheless, check with only one monitor at a time and different combinations to isolate is my suggestion.
PLEASE DISCARD THE FIRST ANSWER BELLOW..
Has the adaptor been tested on one of the other monitors?
If it has been tested on all monitors and the error is only on one
of them, checking that monitor's specs, and the adaptor's specs; to
see if there are any incompatibilities, is probably the best approach.
If no testing on a different monitor has been done, I would definitely
try to isolate the issue by connecting the adaptor to all external
monitors.
If you encounter the same error on a different monitor, we know it is
most likely the adaptor, or it's drivers.

Manipulation of the backlight in a embedded linux device is unstable

I want to control the backlight value of a LCD monitor in a embedded linux device. Doing researches throughout the internet I found a couple of references saying that the file called backlight inside the backlight's driver folder in sys/classes holds the key: it's just a matter of changing the value inside (such as using the echo command in Terminal) that one would get this results. References saying that includes this link, this and this one. In my specific case, the file is located inside /sys/devices/platform/pwm-backlight/backlight/pwm-backlight and there all the relevant, mentioned files are located: actual_brightness, brightness, max_brightness.
Using the echo command, I did managed to control de backlight, but the problem is that this command is unstable. Sometimes I change the value inside the file and the backlight reacts accordingly; other times nothing happens. I couldn't find any particularity that would justify why sometimes it works and others don't, and that's why I'm here. What could be happening that makes this works sometimes and others not? Is there something lacking in programming or would it be a driver or even hardware problem? And what should I do to correct this instability?
It's worth mentioning that I did compile the Linux kernel in accordance to what seems needed (see this link). Given the instructions in this page, the driver being used is called "Generic PWM based Backlight Driver". I'm using a Texas Instruments OMAP L138 processor.
By the way, it's worth mentioning that a "counter" solution that doesn't involve changing that file is accepted (such as for example what is shown in this link).

Create a Wacom-like Linux uinput device for work with touchscreen and pen

This is a fairly broad question, so I will try to keep it as focused as I can.
I currently own a Lenovo laptop with Ubuntu installed and touchscreen functionality and own a pressure-sensitive Bluetooth pen, and been trying to make the two work together as a cheap Cintiq-like tablet.
The pen has, unfortunately, support for only specific apps for iOS phones and tablets.
So after lots of research, I've managed to interface with the pen and create a uinput device for it, so I can register button clicks and pressure changes on the pen and even see them routed to GIMP when configuring the device through the Input Controllers menu.
The code I have so far for that interface is available here.
The trouble starts when trying to test it out with GIMP.
From what I gather, this is because GIMP assumes Wacom devices report their own position, treats touchscreen touches as mouse movements and only allows input from a single device at a time.
My question is, how can I work around this?
More specifically, how can I create a uinput device that would behave as a Wacom tablet and supersede/block the behavior I described?
Or if there's a different solution, such as patching GIMP or writing a plugin for it.
Update (2014-06-07)
The code mentioned above now works.
I have written a blog post on the process of getting this to work: http://gerev.github.io/laptop-cintiq
As you said, Gimp expects you to provide ABS_X and ABS_Y along with ABS_PRESSURE in your driver - which is not strange, because you are using you virtual device as input, so it wouldn't make much sense to pick ABS_X and ABS_Y coordinates from one device and ABS_PRESSURE from another (although they will always be the same in this case). Maybe you can just read the current coordinates of the mouse and copy them as your own device coordinates.
As an example, the project GfxTablet does something similar to what you are trying, they have an Android application for tablets with pen and use uinput to create virtual device that works like pressure-sensitive pen on Linux. I have used it and it worked like a charm in Gimp and mypaint on my laptop, and I had no problem with having a mouse (or the touchpad) active at the same time as the uinput device (I think that Krita added support for generic pressure-sensitive devices recently). You can take a look at the source code of the driver here (surprinsingly simple, to be fair).
Note that this is not a faulty behavior of Gimp, because this is what is expected from a tablet-like device. Take a look at the event codes kernel documentation page, in the last section (Guidelines), it is said that tablets must report ABS_X and ABS_Y. Moreover, they should use BTN_STYLUS and BTN_STYLUS2 to report the tool buttons and some BTN_TOOL_* (e.g. BTN_TOOL_PEN) to report activity (you can find all the available codes in input.h); however, these last does not seem that important, as GfxTablet does not implement them and worked without problem.

Map stdin from second keyboard to a specific program / tty

I have a program (a bash script actually - console only) that scans or makes copies, etc based on user input. It asks questions such as how many copies would you like to make, etc and then scans the document, and prints it to another printer. The program runs in a loop so it's always there when a user passes by, and using a keyboard or number pad you can easily operate it. It basically makes a simple scanner/printer combo into a complex multifunction device.
I can leave it running on a dedicated system just fine, but to save electricity and resources, I would love to have it run on a computer someone else is already using. There is a user who has a laptop on the same desk as the scanner, and I was wanting to have her be able to do her thing in Xorg, as per usual, but have this little program running on an external monitor. That part is easy, but separating input is not. First of all the window has to be in focus, and then any input from the laptop keyboard OR usb keyboard is sent to the program, obviously.
I can think of one way to do this: using virtualbox, I can run a virtual machine without X, have it permanently ssh into the host OS (to which the usb scanner is connected) and I have virtualbox grab the usb keyboard input. But that seems excessive.
Does anyone know of a way to map input from a specific keyboard to a specific program or tty?

How is keyboard auto-repeat implemented on a Windows PC?

I want to be able to intercept (and do arbitrary processing on) auto-repeating key presses on Windows. I'd like to know how keyboard auto-repeat is implemented so that I know what options I have. i.e. can I intercept at the:
application,
device driver and/or
hardware level
?
Update: It looks like auto-repeat is (poorly?) generated at the hardware level and then overridden by device drivers (see here).
To modify or filter behavior, you can intercept keys using a hook:
SetWindowsHookEx using WH_KEYBOARD
The hook procedure receives, among others, the repeat count (due to holding down the key)
Note that the low level keyboard hook (WH_KEYBOARD_LL) does not receive the repeat count.
If all your windows are created in the same trhead, you can use a thread-specific hook, and avoid moving the hook procedure to a DLL.
I dimly remember that repeat counts are generated by the keyboard itself and the LL hook sends repeated keydown events - I may be mistaken, though. Under DOS, the key repeat rate and time that was set in BIOS or through a BIOS call did return to default values when a DIN or PS/2 keyboard was unplugged and replugged. I am not sure WHY you need to know exactly.
I suggest that you might want to edit your question... your actual question is "How to suppress auto-repeat on Windows in ${yourLangauge}"...
To which my response is, I haven't got a clue, I've only ever done it in assembler (MASM 80286)... and even then I found a solution on a BBS (does anyone remember them) and just used it. From memory, the intercept has to be done at the device-driver level.
The implementation of autorepeat ($100 says it's assembler) problably won't shed any light on supressing it... that and Microsoft plays those cards very close to it's chest.
Cheers. Keith.
EDIT: I've just thought... techniques may now differ between versions of windows and the plethora of various devices... Oh goodie!
Sounds likes this is "Not programming related", however.
Go to "Accessibility Options" in control panel.
Select "Settings" under "Filter Keys" group, in here, you can switch off repeating keys for that user on that machine.
Hope this is what your looking for.
P.S. Above instructions given for Windows XP.

Resources