README.md in device_input-0.0.3.1 vs README.md in device_input-0.1.0.1
- old
+ new
@@ -26,18 +26,18 @@
To determine the message size, we need to know the data structure. For a
long time, it was pretty simple: events are 16 bytes:
* timestamp - 8 bytes
-* type - 1 byte
-* code - 1 byte
-* value - 2 bytes
+* type - 2 bytes
+* code - 2 bytes
+* value - 4 bytes
However, this is only true for 32-bit platforms. On 64-bit platforms, event
-timestamps became 16 bytes, increasing events from 16 to 24 bytes. This is
-because a timestamp is defined as two `long`s, and `long`s are bigger on
-64-bit platforms. It's easy to remember:
+timestamps became 16 bytes, increasing the size of events from 16 to 24 bytes.
+This is because a timestamp is defined (ultimately) as two `long`s, and
+`long`s are bigger on 64-bit platforms. It's easy to remember:
* 32-bit platform: 32-bit `long` (4 bytes)
* 64-bit platform: 64-bit `long` (8 bytes)
`read(/dev/input/event0, 16)` will fail on a 64-bit machine.
@@ -48,18 +48,20 @@
encoded values to friendly strings for display, and provides both library and
executable code to assist in examining kernel input events.
# Installation
-Install the gem:
+Requirements: Ruby >= 2.0
+Dependencies: none
+
+Install the gem:
```
$ gem install device_input # sudo as necessary
```
Or, if using [Bundler](http://bundler.io/), add to your `Gemfile`:
-
```
gem 'device_input', '~> 0.0'
```
# Usage
@@ -69,42 +71,51 @@
```
$ sudo devsniff /dev/input/event0
```
When the `f` key is pressed:
-
```
Misc:ScanCode:33
Key:F:1
Sync:Sync:0
```
And released:
```
Misc:ScanCode:33
+Key:F:1
+Sync:Sync:0
+Misc:ScanCode:33
Key:F:0
Sync:Sync:0
```
## Library
```
require 'device_input'
+# this loops forever and blocks waiting for input
DeviceInput.read_from('/dev/input/event0') do |event|
puts event
+ # break if event.time > start + 30
end
```
An event has:
-* `#data` - a Struct of ints (class name Data)
-* `#time` - a Time, accurate to usecs
-* `#type` - a String, possibly UNK-X where X is the integer from `#data`
-* `#code` - a String, possibly UNK-X-Y where X and Y are from `#data`
-* `#value` - a Fixnum (signed)
+* `#data`: Struct of ints (class name Data)
+* `#time`: Time, accurate to usecs
+* `#type`: String label, possibly `UNK-X` where X is the integer from `#data`
+* `#code`: String label, possibly `UNK-X-Y` where X and Y are from `#data`
+* `#value`: Fixnum (signed) from `#data`
+You will probably want to write your own read loop for your own project.
+[`DeviceInput.read_from`](lib/device_input.rb#L111) is very simple and can
+easily be rewritten outside of this project's namespace and adapted for your
+needs.
+
# Research
## Kernel docs
* https://www.kernel.org/doc/Documentation/input/input.txt
@@ -114,11 +125,10 @@
about these structs towards the end of this document.
## Kernel structs
from https://www.kernel.org/doc/Documentation/input/input.txt
-
```
struct input_event {
struct timeval time;
unsigned short type;
unsigned short code;
@@ -126,31 +136,28 @@
};
```
from
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/input.h#n25
-
```
struct input_event {
struct timeval time;
__u16 type;
__u16 code;
__s32 value;
};
```
What's a [`timeval`](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/time.h#n15)?
-
```
struct timeval {
__kernel_time_t tv_sec; /* seconds */
__kernel_suseconds_t tv_usec; /* microseconds */
};
```
What's a [`__kernel_time_t`](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/uapi/asm-generic/posix_types.h#n88)?
-
```
typedef long __kernel_long_t;
# ...
typedef __kernel_long_t __kernel_suseconds_t;
# ...
@@ -158,11 +165,10 @@
```
What's a [`__u16`](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/uapi/asm-generic/int-l64.h#n23)?
We're pretty sure it's an unsigned 16 bit integer. Likewise `__s32` should
be a signed 32-bit integer:
-
```
typedef unsigned short __u16;
typedef __signed__ int __s32;
```
@@ -188,13 +194,13 @@
(8 bytes). This means that the event is 16 bytes on a 32-bit machine and
24 bytes on a 64-bit machine. Software will need to accommodate.
## Ruby tools
-We can use `RbConfig` and `Array#pack`/`String#unpack` to help us read these
-binary structs:
-
+We can use
+[`RbConfig::SIZEOF`](http://idiosyncratic-ruby.com/42-ruby-config.html#rbconfigsizeof)
+and `Array#pack`/`String#unpack` to help us read these binary structs:
```
FIELD C RbConfig Pack
--- --- --- ---
tv_sec long long l!
tv_usec long long l!
@@ -204,7 +210,8 @@
```
# Acknowledgments
* Inspired by https://github.com/prullmann/libdevinput (don't use it)
- - also the source of the [event code labels](lib/device_input/codes.rb)
+ - also the source of an early version of the
+ [event code labels](lib/device_input/codes.rb)
* Thanks to al2o3-cr from #ruby on Freenode for feedback