At least for the test suite, I'll need something that allows me to look at an
event without removing it from the event queue. Just the event type isn't
enough, I need things like "what are the caps on the device". Simplest way to
allow this is a peek function that doesn't remove the event from the queue.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Now that the backend is more of an implementation detail, namespace for
eis_setup_backend_foo()
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
The sink dispatch() loop gets the source from the epollfd data pointer, so
unref'ing the source would cause it to be destroyed when we may try to access
it later. Fix the whole source ownership properly, the first ref is owned by
the epollfd and moves to the list of removed sources, the caller gets the
second ref.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
The main reason for having different functions to create the initial context
was so we can nest the eis struct inside the context-specific struct. That
shouldn't leak into the API though.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
For the case where someone else opens the sockets for us - like a test suite
or eventually the portal.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
We're removing it from our own list when returning the event, so increasing
the refcount isn't required.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Refcounting error means we never hit this code, so let's fix it before we fix
the refcounting.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
We're removing it from our own list when returning the event, so increasing
the refcount isn't required.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Now that the backend is more of an implementation detail, namespace for
ei_setup_backend_foo()
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
The main reason for having different functions to create the initial context
was so we can nest the ei struct inside the context-specific struct. That
shouldn't leak into the API though and our use-case is probably one where we
create one context, then iterate through possible backends until one succeds -
having different contexts here doesn't help then.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Similar in style to Rust where the unit tests are in the same file. Let's see
how far we can get with that in C. Auto-discovery of tests by forcing the
respective suites into a special test section so we can collect it later from
our unit runner.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
protobuf relies on external framing and exact buffer lengths to parse things
correctly. So let's provide that by sending a fixed-length Frame message
before every real message.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
We're in a library here, so expecting the caller to handle SIGPIPE just in
case we get it is a bit demanding. Let's use send() instead so we can just
prevent that altogether.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
We may get more than one message per dispatch so let's make sure we iterate
through all the available data.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Plain-text was useful for the initial implementation where the counterpart was
netcat but now that both parts are in place, protobuf is a much more
convenient system to handle a frequently-changing protocol.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
buf is the iobuf pointer, we need to check whether we read sizeof(data) bytes
before looping around to fetch more.
And fix the return value for a zero read, because that could either be EAGAIN
or EOF.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
The iobuf treats this as binary data but then we're using it as strings in the
message parsing code. So make sure all messages have a trailing null byte.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Better than the current "myclient". Lacks safety and whatnot so long-term it
will have to get replaced with something else.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This is the minimum framework to support connecting to a libeis server, adding
a device and sending relative pointer motion events.It's missing a bunch of
checks and verifications, many of the hooks are still missing, etc.
See the tools/ directory for an example. The protocol is as outlined in
commit f7a24b2fbd.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Aparently the compiler is not smart enough to handle the case correctly where
a cleanup variable is introduced after a goto statement.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This is the minimum framework to support new clients, added devices and
pointer relative motion events. It's missing a bunch of checks and
verification, most of the server hooks aren't there yet, the only
implementation is a UNIX socket and the protocol is plain text (but at least
the last two makes it netcat-compatible).
Protocol is plain text for now and interaction is like this (S is server, C is client):
S: hello
C: connect myclientname
S: connected
C: add 2 4
S: accept 2
C: rel 2 -1 1
C: rel 2 5 4
Where the last two lines are: add device with id 2 and capability mask 0x4,
send a relative pointer motion event for device 2 with coordinates -1/1, then
5/4.
The implementation relies heavily on some abstraction and macros galore, see
the various util-* files. These are largely copied from libinput, with a few
parts removed and a few other parts added.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This allows for some negotiation - server sends hello with some magic auth
data, client sends connect with the reply to the hello. Not sure yet how or
whether this makes sense, but at least it makes testing easy.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
keymap handling is difficult because a lot of it relies on specific server
implementation details. So let's provide the API for a client to assign a
specific keymap to the device and for the server to accept/refuse/override
that keymap.
Where the server refuses, it's up to the client to figure out the rest.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
The use-case of suspending individual capabilities is niche - where a client
needs to rely on this it should create multiple devices with different
capabilities so they can be suspended separately.
Also clarify that the server *must* process events even from a suspended
device. This works around a race condition where a client has sent several
events already before the suspend comes in - it has to assume that any event
sent before the server event is handled updates the state in the server.
Implementation-wise, libei will start filting events once ei_dispatch()
returned the suspend event to the client.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Only allow changing or querying for a single capability at a time.
More verbose but less ambiguous and it removes any bugs resulting from bitmask
errors. There is no supported use-case where the server *adds* a
capability to a client-requested device, so has_capability and
disable_capability is enough.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>