Add ncurses joystick support
authorGeoff Levand <geoffrey.levand@am.sony.com>
Thu, 9 Jul 2009 17:40:44 +0000 (10:40 -0700)
committerGeoff Levand <geoffrey.levand@am.sony.com>
Thu, 9 Jul 2009 17:40:44 +0000 (10:40 -0700)
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
rules.mk
ui/common/joystick.c [new file with mode: 0644]
ui/common/joystick.h [new file with mode: 0644]
ui/ncurses/nc-cui.c
ui/ncurses/nc-cui.h
ui/ncurses/nc-ked.h
ui/ncurses/nc-menu.c
ui/ncurses/nc-menu.h
ui/ncurses/nc-scr.h
ui/ncurses/pb-cui.c
ui/ncurses/ps3-cui.c

index 32b0733b795851b46d46768c6ffd8ef49888dbf2..436d0338f70eedf5e4660117123d9546c890ad42 100644 (file)
--- a/rules.mk
+++ b/rules.mk
@@ -48,10 +48,11 @@ discover_objs = discover/event.o discover/user-event.o discover/udev.o \
        discover/parser-utils.o
 
 # client objs
-ui_common_objs = ui/common/discover-client.o ui/common/loader.o \
-       ui/common/ui-system.o ui/common/timer.o ui/common/url.o
-ncurses_objs = ui/ncurses/nc-scr.o ui/ncurses/nc-menu.o \
-        ui/ncurses/nc-ked.o ui/ncurses/nc-cui.o
+ui_common_objs = ui/common/discover-client.o ui/common/joystick.o \
+       ui/common/loader.o ui/common/ui-system.o ui/common/timer.o \
+       ui/common/url.o
+ncurses_objs = ui/ncurses/nc-scr.o ui/ncurses/nc-menu.o ui/ncurses/nc-ked.o \
+       ui/ncurses/nc-cui.o
 twin_objs = ui/twin/pb-twin.o
 
 # Makefiles
diff --git a/ui/common/joystick.c b/ui/common/joystick.c
new file mode 100644 (file)
index 0000000..94c85fe
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ *  Copyright (C) 2009 Sony Computer Entertainment Inc.
+ *  Copyright 2009 Sony Corp.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#define _GNU_SOURCE
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "log/log.h"
+#include "talloc/talloc.h"
+#include "joystick.h"
+
+/**
+ * pjs_process_event - Read joystick event and map to UI key code.
+ *
+ * Returns a map routine UI key code or zero.
+ */
+
+int pjs_process_event(const struct pjs *pjs)
+{
+       int result;
+       struct js_event e;
+
+       assert(pjs->fd);
+
+       result = read(pjs->fd, &e, sizeof(e));
+
+       if (result != sizeof(e)) {
+               pb_log("%s: read failed: %s\n", __func__, strerror(errno));
+               return 0;
+       }
+
+       return pjs->map(&e);
+}
+
+/**
+ * pjs_destructor - The talloc destructor for a joystick handler.
+ */
+
+static int pjs_destructor(void *arg)
+{
+       struct pjs *pjs = pjs_from_arg(arg);
+
+       close(pjs->fd);
+       pjs->fd = 0;
+
+       return 0;
+}
+
+/**
+ * pjs_init - Initialize the joystick event handler.
+ */
+
+struct pjs *pjs_init(void *ctx, int (*map)(const struct js_event *))
+{
+       static const char dev_name[] = "/dev/input/js0";
+       struct pjs *pjs;
+
+       pjs = talloc_zero(ctx, struct pjs);
+
+       if (!pjs)
+               return NULL;
+
+       pjs->map = map;
+       pjs->fd = open(dev_name, O_RDONLY | O_NONBLOCK);
+
+       if (pjs->fd < 0) {
+               pb_log("%s: open %s failed: %s\n", __func__, dev_name,
+                       strerror(errno));
+               goto out_err;
+       }
+
+       talloc_set_destructor(pjs, pjs_destructor);
+
+       pb_log("%s: using %s\n", __func__, dev_name);
+
+       return pjs;
+
+out_err:
+       close(pjs->fd);
+       pjs->fd = 0;
+       talloc_free(pjs);
+       return NULL;
+}
diff --git a/ui/common/joystick.h b/ui/common/joystick.h
new file mode 100644 (file)
index 0000000..cf3fc45
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *  Copyright (C) 2009 Sony Computer Entertainment Inc.
+ *  Copyright 2009 Sony Corp.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#if !defined(_PB_JOYSTICK_H)
+#define _PB_JOYSTICK_H
+
+#include <linux/joystick.h>
+
+/**
+ * struct pjs - Petitboot joystick event handler.
+ * @map: Routine to map from a Linux struct js_event to a ui key code.
+ */
+
+struct pjs {
+       int fd;
+       int (*map)(const struct js_event *e);
+};
+
+struct pjs *pjs_init(void *ctx, int (*map)(const struct js_event *));
+int pjs_process_event(const struct pjs *pjs);
+
+static inline struct pjs *pjs_from_arg(void *arg)
+{
+       return arg;
+}
+
+static inline int pjs_get_fd(const struct pjs *pjs)
+{
+       return pjs->fd;
+}
+
+#endif
index 9951df3a4116416168270c90af1ad58b4a36432d..aed5ff7befdcbdec665b3cfea0f344ea00321e94 100644 (file)
@@ -230,6 +230,10 @@ struct nc_scr *cui_set_current(struct cui *cui, struct nc_scr *scr)
        return old;
 }
 
+/**
+ * cui_process_key - Process input on stdin.
+ */
+
 static int cui_process_key(void *arg)
 {
        struct cui *cui = cui_from_arg(arg);
@@ -242,6 +246,24 @@ static int cui_process_key(void *arg)
        return 0;
 }
 
+/**
+ * cui_process_js - Process joystick events.
+ */
+
+static int cui_process_js(void *arg)
+{
+       struct cui *cui = cui_from_arg(arg);
+       int c;
+
+       c = pjs_process_event(cui->pjs);
+
+       if (c) {
+               ungetch(c);
+               cui_process_key(arg);
+       }
+
+       return 0;
+}
 /**
  * cui_client_process_socket - Process a socket event from the discover server.
  */
@@ -511,7 +533,8 @@ static struct discover_client_ops cui_client_ops = {
  */
 
 struct cui *cui_init(void* platform_info,
-       int (*on_kexec)(struct cui *, struct cui_opt_data *))
+       int (*on_kexec)(struct cui *, struct cui_opt_data *),
+       int (*js_map)(const struct js_event *e))
 {
        struct cui *cui;
        struct discover_client *client;
@@ -557,6 +580,15 @@ struct cui *cui_init(void* platform_info,
 
        waiter_register(STDIN_FILENO, WAIT_IN, cui_process_key, cui);
 
+       if (js_map) {
+
+               cui->pjs = pjs_init(cui, js_map);
+
+               if (cui->pjs)
+                       waiter_register(pjs_get_fd(cui->pjs), WAIT_IN,
+                               cui_process_js, cui);
+       }
+
        return cui;
 
 fail_client_init:
index b225caa05bac77d689fd5d16798a2ab929e0b716..94fef6b90bf489b3e0abe15b34f88b8e0be97f0a 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <signal.h>
 
+#include "ui/common/joystick.h"
 #include "ui/common/timer.h"
 #include "nc-menu.h"
 #include "nc-ked.h"
@@ -53,13 +54,15 @@ struct cui {
        struct nc_scr *current;
        struct pmenu *main;
        struct ui_timer timer;
+       struct pjs *pjs;
        void *platform_info;
        unsigned int default_item;
        int (*on_kexec)(struct cui *cui, struct cui_opt_data *cod);
 };
 
 struct cui *cui_init(void* platform_info,
-       int (*on_kexec)(struct cui *, struct cui_opt_data *));
+       int (*on_kexec)(struct cui *, struct cui_opt_data *),
+       int (*js_map)(const struct js_event *e));
 struct nc_scr *cui_set_current(struct cui *cui, struct nc_scr *scr);
 int cui_run(struct cui *cui, struct pmenu *main, unsigned int default_item);
 int cui_ked_run(struct pmenu_item *item);
index 759c006f0770d9beb6b4d3775dfd0ae7eadc617e..62fddd66f52cc2d5e4ace20e7086578b152039aa 100644 (file)
@@ -20,6 +20,7 @@
 #define _PB_NC_KED_H
 
 #include <assert.h>
+#include <linux/input.h> /* This must be included before ncurses.h */
 #include <form.h>
 
 #include "pb-protocol/pb-protocol.h"
index 00a7d47a60ea93807849fac134cd293082b0c3e5..f96eb82525d9aca63f0fe42eec9e189f02f2a6bb 100644 (file)
@@ -204,7 +204,7 @@ static void pmenu_process_key(struct nc_scr *scr)
                if (c == ERR)
                        return;
 
-               /* DBGS("%d (%o)\n", c, c); */
+               if (1) DBGS("%d (%o)\n", c, c);
 
                if (menu->hot_key)
                        c = menu->hot_key(menu, item, c);
index 4fca99f94f1ccc4a60b5011e7bbd437c191a844f..4abec6fffe258cb8d1306a83e23127654e8d38d0 100644 (file)
@@ -20,6 +20,7 @@
 #define _PB_NC_MENU_H
 
 #include <assert.h>
+#include <linux/input.h> /* This must be included before ncurses.h */
 #include <menu.h>
 
 #include "log/log.h"
index c08fcd49792f5636566eea43347b3a3039769302..2374c208f26a9c26c1d3bda958dd2eaf278111b3 100644 (file)
@@ -19,6 +19,7 @@
 #if !defined(_PB_NC_SCR_H)
 #define _PB_NC_SCR_H
 
+#include <linux/input.h> /* This must be included before ncurses.h */
 #include <ncurses.h>
 
 #define DBG(fmt, args...) pb_log("DBG: " fmt, ## args)
index 860d55de5cf370f1b257c81c0496de32936e7189..972490acef49d2bb8e2ee0ecc4974cbbc3f52f15 100644 (file)
@@ -269,7 +269,7 @@ int main(int argc, char *argv[])
                return EXIT_FAILURE;
        }
 
-       pb.cui = cui_init(&pb, pb_kexec_cb);
+       pb.cui = cui_init(&pb, pb_kexec_cb, NULL);
 
        if (!pb.cui)
                return EXIT_FAILURE;
index dd5b25503e635927090871b0409240559bc1c35d..2973f5dbb219e308090e7266719a30beba00a1d0 100644 (file)
@@ -156,6 +156,83 @@ static struct ps3_cui *ps3_from_item(struct pmenu_item *item)
        return ps3_from_cui(cui_from_item(item));
 }
 
+/**
+ * ps3_sixaxis_map - Map a Linux joystick event to an ncurses key code.
+ *
+ */
+
+static int ps3_sixaxis_map(const struct js_event *e)
+{
+#if 0
+       static const int axis_map[] = {
+               0,              /*   0  Left thumb X    */
+               0,              /*   1  Left thumb Y    */
+               0,              /*   2  Right thumb X   */
+               0,              /*   3  Right thumb Y   */
+               0,              /*   4  nothing         */
+               0,              /*   5  nothing         */
+               0,              /*   6  nothing         */
+               0,              /*   7  nothing         */
+               0,              /*   8  Dpad Up         */
+               0,              /*   9  Dpad Right      */
+               0,              /*  10  Dpad Down       */
+               0,              /*  11  Dpad Left       */
+               0,              /*  12  L2              */
+               0,              /*  13  R2              */
+               0,              /*  14  L1              */
+               0,              /*  15  R1              */
+               0,              /*  16  Triangle        */
+               0,              /*  17  Circle          */
+               0,              /*  18  Cross           */
+               0,              /*  19  Square          */
+               0,              /*  20  nothing         */
+               0,              /*  21  nothing         */
+               0,              /*  22  nothing         */
+               0,              /*  23  nothing         */
+               0,              /*  24  nothing         */
+               0,              /*  25  nothing         */
+               0,              /*  26  nothing         */
+               0,              /*  27  nothing         */
+       };
+#endif
+       static const int button_map[] = {
+               0,              /*   0  Select          */
+               0,              /*   1  L3              */
+               0,              /*   2  R3              */
+               0,              /*   3  Start           */
+               KEY_UP,         /*   4  Dpad Up         */
+               0,              /*   5  Dpad Right      */
+               KEY_DOWN,       /*   6  Dpad Down       */
+               0,              /*   7  Dpad Left       */
+               KEY_UP,         /*   8  L2              */
+               KEY_DOWN,       /*   9  R2              */
+               KEY_HOME,       /*  10  L1              */
+               KEY_END,        /*  11  R1              */
+               0,              /*  12  Triangle        */
+               0,              /*  13  Circle          */
+               13,             /*  14  Cross           */
+               0,              /*  15  Square          */
+               0,              /*  16  PS Button       */
+               0,              /*  17  nothing         */
+               0,              /*  18  nothing         */
+       };
+
+       if (!e->value)
+               return 0;
+
+       if (e->type == JS_EVENT_BUTTON
+               && e->number < sizeof(button_map) / sizeof(button_map[0]))
+               return button_map[e->number];
+
+#if 0
+       if (e->type == JS_EVENT_AXIS
+               && e->number < sizeof(axis_map) / sizeof(axis_map[0]))
+               return axis_map[e->number];
+#endif
+
+       return 0;
+}
+
 /**
  * ps3_set_mode - Set video mode helper.
  *
@@ -550,7 +627,7 @@ int main(int argc, char *argv[])
        if (!result && (ps3.values.video_mode != (uint16_t)mode))
                ps3_set_video_mode(ps3.values.video_mode);
 
-       ps3.cui = cui_init(&ps3, ps3_kexec_cb);
+       ps3.cui = cui_init(&ps3, ps3_kexec_cb, ps3_sixaxis_map);
 
        if (!ps3.cui)
                return EXIT_FAILURE;