mirror of
https://github.com/troglobit/libuev.git
synced 2026-10-23 11:24:34 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c7a6f1163 | ||
|
|
618480140c | ||
|
|
55f92d25ba | ||
|
|
82d0b0dcb8 | ||
|
|
b0aec77056 | ||
|
|
64f32c9086 | ||
|
|
5065440f52 | ||
|
|
8e1f384c38 | ||
|
|
3094ef2887 | ||
|
|
e50f8aee94 | ||
|
|
0bf22de8e0 | ||
|
|
78d140f310 | ||
|
|
e681657ca7 | ||
|
|
e707d24290 | ||
|
|
7f10528d80 | ||
|
|
d352e176dc | ||
|
|
93d9d06802 | ||
|
|
23935c248a | ||
|
|
59afe57995 | ||
|
|
1dfdc875d7 |
No files matched your search
+22
@@ -0,0 +1,22 @@
|
||||
# Travis CI integration -- https://travis-ci.org/troglobit/libuev
|
||||
language: c
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
|
||||
env:
|
||||
global:
|
||||
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
|
||||
# via the "travis encrypt" command using the project repo's public key
|
||||
- secure: "ikQcWMCLFoxq0+wMiqrNT5HRn0d4e3AxuF8VzNUNFrk6jUvHIufC/OKvr8VWPTjCaAQXZjWfdQAAARUXzJV10WZ7xpiv5qt4bt26Qih2AwMPMJeUOYrqXgQqhTPBp05iLYpo4ybICteXRI3zKKUA1wkdDC0jyu3rl+Fbveekbe0="
|
||||
|
||||
addons:
|
||||
coverity_scan:
|
||||
project:
|
||||
name: "troglobit/libuev"
|
||||
description: "libuEv | Simple asynchronous event loop for Linux."
|
||||
notification_email: troglobit@gmail.com
|
||||
build_command: "make"
|
||||
branch_pattern: master
|
||||
|
||||
script: make
|
||||
@@ -1,4 +1,4 @@
|
||||
Current maintainer of libuev:
|
||||
Current maintainer of libuEv:
|
||||
Joachim Nilsson <troglobit()gmail!com>
|
||||
|
||||
Original LibUEvent author:
|
||||
|
||||
@@ -1,24 +1,20 @@
|
||||
Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
||||
Copyright (c) 2013 Joachim Nilsson <troglobit()gmail!com>
|
||||
Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
||||
Copyright (c) 2013-2015 Joachim Nilsson <troglobit()gmail!com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For an explanation and background of the MIT license, see the Wikipedia
|
||||
article https://en.wikipedia.org/wiki/MIT_License
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -1,7 +1,7 @@
|
||||
# -*-Makefile-*- for libuev
|
||||
# -*-Makefile-*- for libuEv
|
||||
#
|
||||
# Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
||||
# Copyright (c) 2013 Joachim Nilsson <troglobit()gmail!com>
|
||||
# Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
||||
# Copyright (c) 2013-2015 Joachim Nilsson <troglobit()gmail!com>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
@@ -25,7 +25,7 @@
|
||||
.PHONY: all test clean
|
||||
|
||||
#VERSION = $(shell git tag -l | tail -1)
|
||||
VERSION ?= 1.0.0
|
||||
VERSION ?= 1.0.3
|
||||
NAME = libuev
|
||||
PKG = $(NAME)-$(VERSION)
|
||||
ARCHIVE = $(PKG).tar.xz
|
||||
@@ -33,13 +33,9 @@ ARCHIVE = $(PKG).tar.xz
|
||||
CC ?= $(CROSS)gcc
|
||||
AR ?= $(CROSS)ar
|
||||
STRIP ?= $(CROSS)strip
|
||||
CHECK ?= sparse
|
||||
CFLAGS += -fPIC -Os
|
||||
CPPFLAGS += -W -Wall -Werror
|
||||
ARFLAGS = crus
|
||||
CHECK_FLAGS = -Wcast-to-as -Wdefault-bitfield-sign -Wdo-while -Wparen-string \
|
||||
-Wptr-subtraction-blows -Wreturn-void -Wshadow -Wtypesign -Wbitwise \
|
||||
-std=gnu99 -D__x86_64__ -D__LP64__ -I/usr/include/x86_64-linux-gnu
|
||||
JUNK = *~ *.bak *.map .*.d DEADJOE *.gdb *.elf core core.*
|
||||
|
||||
LIBNAME = $(NAME)
|
||||
@@ -111,18 +107,23 @@ bench: Makefile bench.o $(STATICLIB)
|
||||
@printf " BENCH %s\n" $(STATICLIB)
|
||||
@$(CC) $(CPPFLAGS) -g -o bench bench.c $(STATICLIB) && ./bench
|
||||
|
||||
check:
|
||||
@$(CHECK) $(CHECK_FLAGS) $(CPPFLAGS) $(SRCS) bench.c
|
||||
joystick: Makefile joystick.o $(STATICLIB)
|
||||
@printf " JOTST %s\n" $(STATICLIB)
|
||||
@$(CC) $(CPPFLAGS) -g -o joystick joystick.c $(STATICLIB) && ./joystick
|
||||
|
||||
# Runs Clang scan-build on the whole tree
|
||||
check: clean
|
||||
@scan-build $(MAKE) all
|
||||
|
||||
clean:
|
||||
-@$(RM) $(TARGET) *.o test
|
||||
-@$(RM) $(TARGET) *.o test joystick bench
|
||||
|
||||
distclean: clean
|
||||
-@$(RM) $(DEPS) $(JUNK)
|
||||
|
||||
dist:
|
||||
@echo "Building .xz tarball of $(PKG) in parent dir..."
|
||||
git archive --format=tar --prefix=$(PKG)/ $(VERSION) | xz >../$(ARCHIVE)
|
||||
git archive --format=tar --prefix=$(PKG)/ v$(VERSION) | xz >../$(ARCHIVE)
|
||||
@(cd ..; md5sum $(ARCHIVE) | tee $(ARCHIVE).md5)
|
||||
|
||||
# Include automatically generated rules
|
||||
|
||||
@@ -1,68 +1,233 @@
|
||||
libuev - Micro event loop library
|
||||
=================================
|
||||
libuEv | Simple event loop for Linux
|
||||
====================================
|
||||
[](https://travis-ci.org/troglobit/libuev)
|
||||
[](https://scan.coverity.com/projects/3846)
|
||||
|
||||
The libuev library is a small event library in the style of libevent,
|
||||
the excellent libev and the venerable Xt(3) event loop.
|
||||
> “Why an event loop, why not use threads?”
|
||||
|
||||
It is heavily modelled after the libev API, but will never be as
|
||||
portable to other UNIX systems. The primary target of this project is
|
||||
modern embedded Linux systems. You will need kernel and C-library
|
||||
support for epoll(7), timerfd and signalfd.
|
||||
With the advent of light-weight processes (threads) programmers these
|
||||
days have a [golden hammer](http://c2.com/cgi/wiki?GoldenHammer) they
|
||||
often swing without consideration. Event loops and non-blocking I/O is
|
||||
often a far easier approach, as well as less error prone.
|
||||
|
||||
The purpose of many applications is, with a little logic sprinkled on
|
||||
top, to act upon: network packets entering an interface, timeouts
|
||||
expiring, mouse clicks, or other types of events. Such applications are
|
||||
often very well suited to use an event loop.
|
||||
|
||||
Applications that need to churn massively parallel algorithms are more
|
||||
suitable for running multiple (independent) threads on several CPU
|
||||
cores. However, threaded applications must deal with the side effects
|
||||
of concurrency, like: race conditions, deadlocks, live locks, etc.
|
||||
Writing error free threaded applications is hard, debugging them can be
|
||||
even harder.
|
||||
|
||||
Sometimes the combination of multiple threads *and* an event loop per
|
||||
thread can be the best approach, but each application of course needs to
|
||||
be broken down individually to find the most optimal approach. Do keep
|
||||
in mind, however, that not all systems your application will run on have
|
||||
multiple CPU cores -- some small embedded systems still use a single CPU
|
||||
core, even though they run Linux, with multiple threads a program may
|
||||
actually run slower! Always profile your program, and if possible, test
|
||||
it on different architectures.
|
||||
|
||||
LibuEv is a simple event loop in the style of the more established
|
||||
[libevent](http://libevent.org/),
|
||||
[libev](http://software.schmorp.de/pkg/libev.html) and the venerable
|
||||
[Xt(3)](http://unix.com/man-page/All/3x/XtDispatchEvent) event loop.
|
||||
The *u* (micro) in the name refers to both the small feature set and the
|
||||
small size overhead impact of the library. The primary target of libuEv
|
||||
is a modern Linux system.
|
||||
|
||||
Experienced developers may appreciate that libuEv is built on top of
|
||||
modern Linux APIs: epoll, timerfd and signalfd.
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
API
|
||||
---
|
||||
|
||||
The user initializes an event context to which timer and I/O stream
|
||||
watchers are registered. A typical application then enters the event
|
||||
loop that will only return at program termination.
|
||||
Here is the interface to libuEv. It handles three different types of
|
||||
events: I/O (files, sockets, message queues, etc.), timers, and
|
||||
signals.
|
||||
|
||||
```C
|
||||
/* Callback example, arg is passed from watcher's *_init()
|
||||
* w->fd holds the file descriptor, events is set by libuEv
|
||||
* to indicate if any of UEV_READ and/or UEV_WRITE is ready.
|
||||
*/
|
||||
void callback(uev_ctx_t *ctx, uev_t *w, void *arg, int events);
|
||||
|
||||
/* Event loop functions, notice use of flags! */
|
||||
int uev_init (uev_ctx_t *ctx);
|
||||
int uev_exit (uev_ctx_t *ctx);
|
||||
int uev_run (uev_ctx_t *ctx, int flags); /* UEV_NONE, UEV_ONCE, and/or UEV_NONBLOCK */
|
||||
|
||||
/* I/O watcher: fd is non-blocking, events is UEV_READ and/or UEV_WRITE */
|
||||
int uev_io_init (uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, int fd, int events);
|
||||
int uev_io_set (uev_t *w, int fd, int events);
|
||||
int uev_io_stop (uev_t *w);
|
||||
|
||||
/* Timer watcher: timeout and period in milliseconds */
|
||||
int uev_timer_init (uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, int timeout, int period);
|
||||
int uev_timer_set (uev_t *w, int timeout, int period); /* Change timeout or period */
|
||||
int uev_timer_stop (uev_t *w); /* Stop a timer */
|
||||
|
||||
/* Signal watcher: signo is the signal to wait for, e.g., SIGTERM */
|
||||
int uev_signal_init(uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, int signo);
|
||||
int uev_signal_set (uev_t *w, int signo); /* Change signal to wait for */
|
||||
int uev_signal_stop(uev_t *w); /* Stop signal watcher */
|
||||
```
|
||||
|
||||
To be able to set up callbacks to events the developer first need to
|
||||
create an *event context*, achieved by calling `uev_init()` with a
|
||||
pointer to a local `uev_ctx_t` variable.
|
||||
|
||||
Events are monitored by watchers in libuEV. A watcher is nothing more
|
||||
than a mechnism that polls a file descriptor. Register a watcher with a
|
||||
callback to the event context by passing the `uev_ctx_t` variable, along
|
||||
with an `uev_t` variable to each event's `_init()` function.
|
||||
|
||||
When all watchers are registered call the event loop with `uev_run()`
|
||||
and the argument to the event context. The `flags` parameter is slightly
|
||||
mysterious, but can be used to integrate libuEv into another event loop.
|
||||
With `flags` set to `UEV_ONCE` the event loop returns after having
|
||||
served the first event. If `flags` is set to `UEV_ONCE | UEV_NONBLOCK`
|
||||
the event loop returns immediately if no event is available.
|
||||
|
||||
Summary:
|
||||
|
||||
1. Prepare an event context with `uev_init()`
|
||||
2. Register event callbacks with `uev_io_init()`, `uev_signal_init()`
|
||||
or `uev_timer_init()`
|
||||
3. Enter the event loop with `uev_run()`
|
||||
4. Leave the event loop with `uev_exit()`, possibly from a callback
|
||||
|
||||
**Note:** Make sure to use non-blocking stream I/O! Most hard to find
|
||||
bugs in event driven applications are due to sockets and files being
|
||||
opened in blocking mode. Be careful out there!
|
||||
|
||||
|
||||
The C API
|
||||
---------
|
||||
Example
|
||||
-------
|
||||
|
||||
The typical application will do the following steps
|
||||
Here follows a very brief example to illustrate how one can use libuEv
|
||||
to act upon joystick input.
|
||||
|
||||
1. Prepare an event context with `uev_init()`
|
||||
2. Register callbacks with `uev_io_init()` and `uev_timer_init()`
|
||||
3. Enter the event loop with `uev_run()`
|
||||
```C
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
**Note:** Make sure to use non-blocking stream I/O!
|
||||
#include "uev.h"
|
||||
|
||||
struct js_event {
|
||||
uint32_t time; /* event timestamp in milliseconds */
|
||||
int16_t value; /* value */
|
||||
uint8_t type; /* event type */
|
||||
uint8_t number; /* axis/button number */
|
||||
} e;
|
||||
|
||||
static void joystick_cb(uev_ctx_t *ctx, uev_t *w, void *arg, int events)
|
||||
{
|
||||
read (w->fd, &e, sizeof(e));
|
||||
|
||||
switch (e.type) {
|
||||
case 1:
|
||||
if (e.value) printf("Button %d pressed\n", e.number);
|
||||
else printf("Button %d released\n", e.number);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
printf("Joystick axis %d moved, value %d!\n", e.number, e.value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fd = open("/dev/input/js1", O_RDONLY, O_NONBLOCK);
|
||||
uev_t js1_watcher;
|
||||
uev_ctx_t ctx;
|
||||
|
||||
if (fd < 0)
|
||||
errx(errno, "Cannot find a joystick attached.");
|
||||
|
||||
uev_init(&ctx);
|
||||
uev_io_init(&ctx, &js1_watcher, joystick_cb, NULL, fd, UEV_READ);
|
||||
|
||||
puts("Starting, press Ctrl-C to exit.");
|
||||
|
||||
return uev_run(&ctx, 0);
|
||||
}
|
||||
```
|
||||
|
||||
To compile the program, save the code as `joystick.c` and call GCC with
|
||||
`gcc -o joystick joystick.c io.c timer.c signal.c main.c` from this
|
||||
directory, skips using a Makefile altogether. Alternatively, call the
|
||||
`Makefile` with `make joystick` from this directory.
|
||||
|
||||
For a more complete, and perhaps more relevant example, see the code for
|
||||
the TFTP/FTP server [uftpd](https://github.com/troglobit/uftpd). It
|
||||
uses libuEv as a GIT submodule.
|
||||
|
||||
Also, see the `bench.c` program (`make bench` from within the library)
|
||||
for [reference benchmarks](http://libev.schmorp.de/bench.html) against
|
||||
libevent and libev.
|
||||
|
||||
|
||||
Build & Install
|
||||
---------------
|
||||
|
||||
The library is built and developed for GNU/Linux systems, as such it may
|
||||
use GNU GCC and GNU Make specific features. Patches to support *BSD
|
||||
kqueue are most welcome.
|
||||
The library is built for and developed on GNU/Linux systems, so it may
|
||||
use GCC and GNU Make specific extensions here and there. This is not on
|
||||
purpose and patches to correct this are most welcome. Particularly
|
||||
patches to support *BSD and its kqueue interface.
|
||||
|
||||
* `make all`: The library
|
||||
* `make test`: Test and showcase
|
||||
* `make install`: Honors $prefix and $DESTDIR environment variables
|
||||
* `make all`: The library
|
||||
* `make test`: Test and showcase
|
||||
* `make install`: Honors `$prefix` and `$DESTDIR` environment variables
|
||||
|
||||
Size of libuEv:
|
||||
|
||||
$ make strip
|
||||
CC main.o
|
||||
CC io.o
|
||||
CC timer.o
|
||||
CC signal.o
|
||||
ARCHIVE libuev.a
|
||||
LINK libuev.so.1
|
||||
STRIP libuev.a
|
||||
STRIP libuev.so.1
|
||||
text data bss dec hex filename
|
||||
1177 0 0 1177 499 main.o (ex libuev.a)
|
||||
308 0 0 308 134 io.o (ex libuev.a)
|
||||
682 0 0 682 2aa timer.o (ex libuev.a)
|
||||
563 0 0 563 233 signal.o (ex libuev.a)
|
||||
6306 768 8 7082 1baa libuev.so.1
|
||||
|
||||
|
||||
Warning
|
||||
-------
|
||||
Origin & References
|
||||
--------------------
|
||||
|
||||
Please be advised, libuev is not thread safe! It is primarily intended
|
||||
for use-cases where the engineer wants to avoid the use of threads. To
|
||||
support threads the signal handling needs to be patched first, other
|
||||
than that an event context per thread should be sufficient.
|
||||
LibuEv (this library) was originally based on
|
||||
[LibUEvent](http://code.google.com/p/libuevent/) by
|
||||
[Flemming Madsen](http://www.madsensoft.dk/) but has been completely
|
||||
rewritten with a much clearer API. Now more similar to the famous
|
||||
[libev](http://software.schmorp.de/pkg/libev.html) by Mark Lehmann.
|
||||
Another small event library used for inspiration is the very small
|
||||
[Picoev](https://github.com/kazuho/picoev) by
|
||||
[Oku Kazuho](https://github.com/kazuho).
|
||||
|
||||
* http://code.google.com/p/libuevent/
|
||||
* http://software.schmorp.de/pkg/libev.html
|
||||
* http://libev.schmorp.de/bench.html
|
||||
* http://libevent.org/
|
||||
* http://developer.cybozu.co.jp/archives/kazuho/2009/08/picoev-a-tiny-e.html
|
||||
* http://coderepos.org/share/browser/lang/c/picoev/
|
||||
|
||||
History and References
|
||||
----------------------
|
||||
|
||||
Libuev is a fork of the original LibUEvent by Flemming Madsen but has
|
||||
been completely rewritten and is now more similar to the famous libev by
|
||||
Mark Lehmann. Another small event library used for inspiration is the
|
||||
very small Picoev by Oku Kazuho.
|
||||
|
||||
* http://code.google.com/p/libuevent/
|
||||
* http://software.schmorp.de/pkg/libev.html
|
||||
* http://libev.schmorp.de/bench.html
|
||||
* http://libevent.org/
|
||||
* http://developer.cybozu.co.jp/archives/kazuho/2009/08/picoev-a-tiny-e.html
|
||||
* http://coderepos.org/share/browser/lang/c/picoev/
|
||||
LibuEv is maintained by [Joachim Nilsson](mailto:troglobit@gmail.com) at
|
||||
[GitHub](https://github.com/troglobit/libuev)
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
*
|
||||
* Sun 04/08/2013 - Modified by Joachim Nilsson <troglobit@gmail.com>
|
||||
*
|
||||
* Adaptations for libuev, no libev/libevent API wrappers available.
|
||||
* Adaptations for libuEv, no libev/libevent API wrappers available.
|
||||
* Reindent to Linux coding style
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* libuev - Micro event loop library
|
||||
/* libuEv - Micro event loop library
|
||||
*
|
||||
* Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
||||
* Copyright (c) 2013 Joachim Nilsson <troglobit()gmail!com>
|
||||
* Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
||||
* Copyright (c) 2013-2015 Joachim Nilsson <troglobit()gmail!com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
/**
|
||||
* Create an I/O watcher
|
||||
* @param ctx A valid libuev context
|
||||
* @param ctx A valid libuEv context
|
||||
* @param w Pointer to an uev_t watcher
|
||||
* @param cb I/O callback
|
||||
* @param arg Optional callback argument
|
||||
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/* Simple example of how to use libuEv with Linux joystick API
|
||||
*
|
||||
* Copyright (c) 2014-2015 Joachim Nilsson <troglobit()gmail!com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "uev.h"
|
||||
|
||||
#define UNUSED(arg) arg __attribute__ ((unused))
|
||||
|
||||
struct js_event {
|
||||
uint32_t time; /* event timestamp in milliseconds */
|
||||
int16_t value; /* value */
|
||||
uint8_t type; /* event type */
|
||||
uint8_t number; /* axis/button number */
|
||||
} e;
|
||||
|
||||
static void joystick_cb(uev_ctx_t *UNUSED(ctx), uev_t *w, void *UNUSED(arg), int UNUSED(events))
|
||||
{
|
||||
if (read (w->fd, &e, sizeof(e)) < 0)
|
||||
errx(errno, "Failed reading joystick event");
|
||||
|
||||
switch (e.type) {
|
||||
case 1:
|
||||
if (e.value) printf("Button %d pressed\n", e.number);
|
||||
else printf("Button %d released\n", e.number);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
printf("Joystick axis %d moved, value %d!\n", e.number, e.value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fd = open("/dev/input/js1", O_RDONLY, O_NONBLOCK);
|
||||
uev_t js1_watcher;
|
||||
uev_ctx_t ctx;
|
||||
|
||||
if (fd < 0)
|
||||
errx(errno, "Cannot find a joystick attached.");
|
||||
|
||||
uev_init(&ctx);
|
||||
uev_io_init(&ctx, &js1_watcher, joystick_cb, NULL, fd, UEV_READ);
|
||||
|
||||
puts("Starting, press Ctrl-C to exit.");
|
||||
|
||||
return uev_run(&ctx, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Local Variables:
|
||||
* compile-command: "gcc -o joystick joystick.c io.o timer.o signal.o main.o"
|
||||
* version-control: t
|
||||
* indent-tabs-mode: t
|
||||
* c-file-style: "linux"
|
||||
* End:
|
||||
*/
|
||||
@@ -1,7 +1,7 @@
|
||||
/* libuev - Micro event loop library
|
||||
/* libuEv - Micro event loop library
|
||||
*
|
||||
* Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
||||
* Copyright (c) 2013 Joachim Nilsson <troglobit()gmail!com>
|
||||
* Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
||||
* Copyright (c) 2013-2015 Joachim Nilsson <troglobit()gmail!com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
#define UNUSED(arg) arg __attribute__ ((unused))
|
||||
|
||||
/* Private to libuev, do not use directly! */
|
||||
/* Private to libuEv, do not use directly! */
|
||||
int uev_watcher_init(uev_ctx_t *ctx, uev_t *w, uev_type_t type, uev_cb_t *cb, void *arg, int fd, int events)
|
||||
{
|
||||
if (!ctx || !w) {
|
||||
@@ -54,7 +54,7 @@ int uev_watcher_init(uev_ctx_t *ctx, uev_t *w, uev_type_t type, uev_cb_t *cb, vo
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Private to libuev, do not use directly! */
|
||||
/* Private to libuEv, do not use directly! */
|
||||
int uev_watcher_start(uev_t *w)
|
||||
{
|
||||
struct epoll_event ev;
|
||||
@@ -77,7 +77,7 @@ int uev_watcher_start(uev_t *w)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Private to libuev, do not use directly! */
|
||||
/* Private to libuEv, do not use directly! */
|
||||
int uev_watcher_stop(uev_t *w)
|
||||
{
|
||||
if (!w) {
|
||||
@@ -118,7 +118,7 @@ int uev_init(uev_ctx_t *ctx)
|
||||
|
||||
/**
|
||||
* Terminate the event loop
|
||||
* @param ctx A valid libuev context
|
||||
* @param ctx A valid libuEv context
|
||||
*
|
||||
* @return POSIX OK(0) or non-zero with @param errno set on error.
|
||||
*/
|
||||
@@ -162,10 +162,17 @@ int uev_exit(uev_ctx_t *ctx)
|
||||
|
||||
/**
|
||||
* Start the event loop
|
||||
* @param ctx A valid libuev context
|
||||
* @param ctx A valid libuEv context
|
||||
* @param flags A mask of %UEV_ONCE and %UEV_NONBLOCK, or zero
|
||||
*
|
||||
* @return POSIX OK(0) upon successful termination of the event loop, or non-zero on error.
|
||||
* With @flags set to %UEV_ONCE the event loop returns after the first
|
||||
* event has been served, useful for instance to set a timeout on a file
|
||||
* descriptor. If @flags also has the %UEV_NONBLOCK flag set the event
|
||||
* loop will return immediately if no event is pending, useful when run
|
||||
* inside another event loop.
|
||||
*
|
||||
* @return POSIX OK(0) upon successful termination of the event loop, or
|
||||
* non-zero on error.
|
||||
*/
|
||||
int uev_run(uev_ctx_t *ctx, int flags)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* libuev - Micro event loop library
|
||||
/* libuEv - Micro event loop library
|
||||
*
|
||||
* Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
||||
* Copyright (c) 2013 Joachim Nilsson <troglobit()gmail!com>
|
||||
* Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
||||
* Copyright (c) 2013-2015 Joachim Nilsson <troglobit()gmail!com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
/**
|
||||
* Create a signal watcher
|
||||
* @param ctx A valid libuev context
|
||||
* @param ctx A valid libuEv context
|
||||
* @param w Pointer to an uev_t watcher
|
||||
* @param cb Timer callback
|
||||
* @param arg Optional callback argument
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Test libuev event library
|
||||
/* Test libuEv event library
|
||||
*
|
||||
* Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
||||
* Copyright (c) 2013 Joachim Nilsson <troglobit()gmail!com>
|
||||
* Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
||||
* Copyright (c) 2013-2015 Joachim Nilsson <troglobit()gmail!com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* libuev - Micro event loop library
|
||||
/* libuEv - Micro event loop library
|
||||
*
|
||||
* Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
||||
* Copyright (c) 2013 Joachim Nilsson <troglobit()gmail!com>
|
||||
* Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
||||
* Copyright (c) 2013-2015 Joachim Nilsson <troglobit()gmail!com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@@ -43,7 +43,7 @@ static void msec2tspec(int msec, struct timespec *ts)
|
||||
|
||||
/**
|
||||
* Create and start a timer watcher
|
||||
* @param ctx A valid libuev context
|
||||
* @param ctx A valid libuEv context
|
||||
* @param w Pointer to an uev_t watcher
|
||||
* @param cb Callback function
|
||||
* @param arg Optional callback argument
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* libuev - Micro event loop library
|
||||
/* libuEv - Micro event loop library
|
||||
*
|
||||
* Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
||||
* Copyright (c) 2013 Joachim Nilsson <troglobit()gmail!com>
|
||||
* Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
||||
* Copyright (c) 2013-2015 Joachim Nilsson <troglobit()gmail!com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@@ -52,7 +52,7 @@ typedef enum {
|
||||
/* Forward declare due to dependencys, don't try this at home kids. */
|
||||
struct uev;
|
||||
|
||||
/* Main libuev context type */
|
||||
/* Main libuEv context type */
|
||||
typedef struct {
|
||||
int running;
|
||||
int fd; /* For epoll() */
|
||||
|
||||
Reference in new issue
Block a user