summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2007-08-23 16:38:09 +0800
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2007-08-23 10:45:48 +0200
commit6ede3a8b0842a07c97af0f5d0f86ec62af2f0966 (patch)
tree5a3df89498f0aa953d4f176c10aee295dd7d19e6
parentd8a0a0845572dc2a7427bd57b851df7f766a11ab (diff)
twin: add Linux joystick support
Add a simple event layer for joystick devices. Signed-off-by: Jeremy Kerr <jk@ozlabs.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--Makefile.am5
-rw-r--r--configure.ac8
-rw-r--r--libtwin/twin.h10
-rw-r--r--libtwin/twin_linux_js.c144
-rw-r--r--libtwin/twin_linux_js.h37
5 files changed, 204 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am
index 3a471ff..10144a0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -56,6 +56,11 @@ pkginclude_HEADERS += libtwin/twin_linux_mouse.h
libtwin_libtwin_la_SOURCES += libtwin/twin_linux_mouse.c
endif
+if TWIN_JOYSTICK
+pkginclude_HEADERS += libtwin/twin_linux_js.h
+libtwin_libtwin_la_SOURCES += libtwin/twin_linux_js.c
+endif
+
if TWIN_PNG
pkginclude_HEADERS += libtwin/twin_png.h
libtwin_libtwin_la_SOURCES += libtwin/twin_png.c
diff --git a/configure.ac b/configure.ac
index 5552694..024e93c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -81,6 +81,12 @@ AC_ARG_ENABLE(linux-mouse,
[Disable linux mouse support (default=enabled)]),
twin_mouse="$enableval", twin_mouse="yes")
+# linux joystick
+AC_ARG_ENABLE(linux-joystick,
+ AC_HELP_STRING([--disable-linux-joystick],
+ [Disable linux joystick support (default=enabled)]),
+ twin_joystick="$enableval", twin_joystick="yes")
+
# zlib
AC_ARG_ENABLE(zlib,
AC_HELP_STRING([--disable-zlib],
@@ -186,6 +192,7 @@ AM_CONDITIONAL(TWIN_PNG, test x$twin_png = xyes)
AM_CONDITIONAL(TWIN_JPEG, test x$twin_jpeg = xyes)
AM_CONDITIONAL(TWIN_TTF, test x$twin_ttf = xyes)
AM_CONDITIONAL(TWIN_MOUSE, test x$twin_mouse = xyes)
+AM_CONDITIONAL(TWIN_JOYSTICK, test x$twin_joystick = xyes)
AC_MSG_NOTICE([x11 support: $twin_x11])
AC_MSG_NOTICE([fbdev support: $twin_fb])
@@ -194,6 +201,7 @@ AC_MSG_NOTICE([png support: $twin_png])
AC_MSG_NOTICE([jpeg support: $twin_jpeg])
AC_MSG_NOTICE([twin_ttf tool: $twin_ttf])
AC_MSG_NOTICE([linux mouse: $twin_mouse])
+AC_MSG_NOTICE([linux joystick: $twin_joystick])
AC_MSG_NOTICE([altivec: $twin_altivec])
AC_OUTPUT([Makefile
diff --git a/libtwin/twin.h b/libtwin/twin.h
index 04a9ac6..1114bc5 100644
--- a/libtwin/twin.h
+++ b/libtwin/twin.h
@@ -35,6 +35,8 @@ typedef int16_t twin_coord_t;
typedef int16_t twin_style_t;
typedef int16_t twin_count_t;
typedef int16_t twin_keysym_t;
+typedef uint8_t twin_js_number_t;
+typedef int16_t twin_js_value_t;
typedef int32_t twin_area_t;
typedef int32_t twin_time_t;
typedef int16_t twin_stretch_t;
@@ -120,6 +122,10 @@ typedef enum _twin_event_kind {
TwinEventActivate = 0x0201,
TwinEventDeactivate = 0x0202,
+ /* Joystick */
+ TwinEventJoyButton = 0x0401,
+ TwinEventJoyAxis = 0x0402,
+
/* Widgets */
TwinEventPaint = 0x1001,
TwinEventQueryGeometry = 0x1002,
@@ -139,6 +145,10 @@ typedef struct _twin_event {
twin_keysym_t key;
} key;
struct {
+ twin_js_number_t control;
+ twin_js_value_t value;
+ } js;
+ struct {
twin_ucs4_t ucs4;
} ucs4;
struct {
diff --git a/libtwin/twin_linux_js.c b/libtwin/twin_linux_js.c
new file mode 100644
index 0000000..3108cb8
--- /dev/null
+++ b/libtwin/twin_linux_js.c
@@ -0,0 +1,144 @@
+/*
+ * Linux joystick driver for Twin
+ *
+ * Copyright 2007 Jeremy Kerr <jk@ozlabs.org>
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Twin Library; see the file COPYING. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <dirent.h>
+#include <linux/joystick.h>
+
+#include "twin.h"
+#include "twin_linux_js.h"
+
+#define DEBUG(fmt...) printf(fmt)
+
+struct twin_js_dev {
+ int fd;
+ twin_screen_t *screen;
+};
+
+static twin_bool_t twin_linux_js_events(int file, twin_file_op_t ops,
+ void *closure)
+{
+ struct twin_js_dev *js = closure;
+ struct js_event js_event;
+ int rc;
+ twin_event_t tev;
+
+ for (;;) {
+
+ rc = read(js->fd, &js_event, sizeof(js_event));
+ if (rc < 0 && errno == EAGAIN)
+ break;
+
+ if (rc < 0) {
+ DEBUG("Error reading from joystick device: %s\n",
+ strerror(errno));
+ return TWIN_FALSE;
+ }
+
+ if (rc != sizeof(js_event))
+ break;
+
+ if (js_event.type == JS_EVENT_BUTTON)
+ tev.kind = TwinEventJoyButton;
+ else if (js_event.type == JS_EVENT_AXIS)
+ tev.kind = TwinEventJoyAxis;
+ else
+ continue;
+
+ tev.u.js.control = js_event.number;
+ tev.u.js.value = js_event.value;
+ twin_screen_dispatch(js->screen, &tev);
+ }
+
+ return TWIN_TRUE;
+}
+
+
+static int nr_devs;
+struct twin_js_dev *js_devs;
+
+int twin_linux_js_create(twin_screen_t *screen)
+{
+ struct dirent *dirent;
+ DIR *dir;
+
+ dir = opendir("/dev/input");
+ if (dir == NULL) {
+ perror("opendir(/dev/input)");
+ return -1;
+ }
+
+ while ((dirent = readdir(dir))) {
+ /* buffer to hold dir.d_name, plus "/dev/input/" */
+ char dev_name[sizeof(dirent->d_name) + 12];
+ int dev_fd;
+ struct twin_js_dev *js_dev, *tmp;
+
+
+ if (strncmp(dirent->d_name, "js", 2))
+ continue;
+
+ strcpy(dev_name, "/dev/input/");
+ strcat(dev_name, dirent->d_name);
+
+ dev_fd = open(dev_name, O_RDONLY | O_NONBLOCK);
+ if (dev_fd < 0) {
+ perror("open");
+ continue;
+ }
+ DEBUG("Adding joystick device %s\n", dev_name);
+
+ tmp = realloc(js_devs, ++nr_devs * sizeof(*js_devs));
+ if (!tmp) {
+ close(dev_fd);
+ continue;
+ }
+ js_devs = tmp;
+
+ js_dev = js_devs + nr_devs - 1;
+ js_dev->fd = dev_fd;
+ js_dev->screen = screen;
+
+ twin_set_file(twin_linux_js_events, dev_fd, TWIN_READ, js_dev);
+ }
+ closedir(dir);
+
+ return 0;
+}
+
+void twin_linux_js_destroy()
+{
+ int i;
+
+ for (i = 0; i < nr_devs; i++)
+ close(js_devs[i].fd);
+
+ free(js_devs);
+ js_devs = NULL;
+}
+
diff --git a/libtwin/twin_linux_js.h b/libtwin/twin_linux_js.h
new file mode 100644
index 0000000..0fa301d
--- /dev/null
+++ b/libtwin/twin_linux_js.h
@@ -0,0 +1,37 @@
+/*
+ * Linux joystick driver for Twin
+ *
+ * Copyright 2007 Jeremy Kerr <jk@ozlabs.org>
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Twin Library; see the file COPYING. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _TWIN_LINUX_JS_H_
+#define _TWIN_LINUX_JS_H_
+
+#include <libtwin/twin.h>
+
+/**
+ * twin_linux_js_create - create the linux joystick driver
+ * @file: device file to open, pass NULL for default
+ */
+int twin_linux_js_create(twin_screen_t *screen);
+
+/**
+ * twin_linux_js_destroy - destroy the linux js driver
+ */
+void twin_linux_js_destroy(void);
+
+#endif /* _TWIN_LINUX_JS_H_ */