summaryrefslogtreecommitdiff
path: root/nuttx
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-12-14 10:19:07 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-12-14 10:19:07 -0600
commitc4c14b4ea44e798b79b039bd597da6881956a34b (patch)
treef02b3d8c7cd98b1b8e24cd43a0724d832300a900 /nuttx
parentc627d15288f61aa2cbb4d1484cf06f497fd5a9c2 (diff)
downloadnuttx-c4c14b4ea44e798b79b039bd597da6881956a34b.tar.gz
nuttx-c4c14b4ea44e798b79b039bd597da6881956a34b.tar.bz2
nuttx-c4c14b4ea44e798b79b039bd597da6881956a34b.zip
SIM: Add an X11 mouse-based simulation of an analog joystick device
Diffstat (limited to 'nuttx')
-rw-r--r--nuttx/arch/sim/Kconfig19
-rw-r--r--nuttx/arch/sim/src/Makefile5
-rw-r--r--nuttx/arch/sim/src/up_ajoystick.c274
-rw-r--r--nuttx/arch/sim/src/up_idle.c2
-rw-r--r--nuttx/arch/sim/src/up_internal.h22
-rw-r--r--nuttx/arch/sim/src/up_x11eventloop.c21
-rw-r--r--nuttx/arch/sim/src/up_x11framebuffer.c4
-rw-r--r--nuttx/configs/sim/src/Makefile1
-rw-r--r--nuttx/configs/sim/src/sim_boot.c8
-rw-r--r--nuttx/configs/sim/traveler/defconfig2
10 files changed, 348 insertions, 10 deletions
diff --git a/nuttx/arch/sim/Kconfig b/nuttx/arch/sim/Kconfig
index 4fda868f1..e5fcad556 100644
--- a/nuttx/arch/sim/Kconfig
+++ b/nuttx/arch/sim/Kconfig
@@ -98,13 +98,28 @@ config SIM_FBBPP
endif # SIM_FRAMEBUFFER
+if SIM_X11FB && INPUT
+choice
+ prompt "X11 Simulated Input Device"
+ default SIM_NOINPUT
+
config SIM_TOUCHSCREEN
- bool "Support an X11 mouse-based touchscreen emulation"
+ bool "X11 mouse-based touchscreen emulation"
default n
- depends on SIM_X11FB && INPUT
---help---
Support an X11 mouse-based touchscreen emulation. Also needs INPUT=y
+config SIM_AJOYSTICK
+ bool "X11 mouse-based analog joystick emulation"
+ ---help---
+ Support an X11 mouse-based anallog joystick emulation. Also needs INPUT=y`
+
+config SIM_NOINPUT
+ bool "No input device"
+
+endchoice # X11 Simulated Input Device
+endif # SIM_X11FB && INPUT
+
config SIM_TCNWAITERS
bool "Maximum number poll() waiters"
default 4
diff --git a/nuttx/arch/sim/src/Makefile b/nuttx/arch/sim/src/Makefile
index ae537c173..4507ce60d 100644
--- a/nuttx/arch/sim/src/Makefile
+++ b/nuttx/arch/sim/src/Makefile
@@ -77,6 +77,11 @@ ifeq ($(CONFIG_SIM_X11FB),y)
ifeq ($(CONFIG_SIM_TOUCHSCREEN),y)
CSRCS += up_touchscreen.c
HOSTSRCS += up_x11eventloop.c
+else
+ifeq ($(CONFIG_SIM_AJOYSTICK),y)
+ CSRCS += up_ajoystick.c
+ HOSTSRCS += up_x11eventloop.c
+endif
endif
endif
endif
diff --git a/nuttx/arch/sim/src/up_ajoystick.c b/nuttx/arch/sim/src/up_ajoystick.c
new file mode 100644
index 000000000..69dd149e8
--- /dev/null
+++ b/nuttx/arch/sim/src/up_ajoystick.c
@@ -0,0 +1,274 @@
+/****************************************************************************
+ * arch/sim/src/up_ajoystick.c
+ *
+ * Copyright (C) 2014 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/input/ajoystick.h>
+
+#include "up_internal.h"
+
+#ifdef CONFIG_AJOYSTICK
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+# define AJOY_SUPPORTED (AJOY_BUTTON_1_BIT | AJOY_BUTTON_2_BIT | \
+ AJOY_BUTTON_3_BIT)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ajoy_buttonset_t ajoy_supported(FAR const struct ajoy_lowerhalf_s *lower);
+static int ajoy_sample(FAR const struct ajoy_lowerhalf_s *lower,
+ FAR struct ajoy_sample_s *sample);
+static ajoy_buttonset_t ajoy_buttons(FAR const struct ajoy_lowerhalf_s *lower);
+static void ajoy_enable(FAR const struct ajoy_lowerhalf_s *lower,
+ ajoy_buttonset_t press, ajoy_buttonset_t release,
+ ajoy_handler_t handler, FAR void *arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* This is the button joystick lower half driver interface */
+
+static const struct ajoy_lowerhalf_s g_ajoylower =
+{
+ .al_supported = ajoy_supported,
+ .al_sample = ajoy_sample,
+ .al_buttons = ajoy_buttons,
+ .al_enable = ajoy_enable,
+};
+
+/* Driver state data */
+
+static volatile bool g_ajoy_valid; /* True: Sample data is valid */
+static volatile bool g_ajoy_waiting; /* True: Waiting for button data */
+static sem_t g_ajoy_waitsem; /* Semaphore used to support waiting */
+static struct ajoy_sample_s g_ajoy_sample; /* Last sample data */
+static ajoy_buttonset_t g_ajoy_buttons; /* Last buttons set */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: ajoy_supported
+ *
+ * Description:
+ * Return the set of buttons supported on the button joystick device
+ *
+ ****************************************************************************/
+
+static ajoy_buttonset_t ajoy_supported(FAR const struct ajoy_lowerhalf_s *lower)
+{
+ return (ajoy_buttonset_t)AJOY_SUPPORTED;
+}
+
+/****************************************************************************
+ * Name: ajoy_sample
+ *
+ * Description:
+ * Return the current state of all button joystick buttons
+ *
+ ****************************************************************************/
+
+static int ajoy_sample(FAR const struct ajoy_lowerhalf_s *lower,
+ FAR struct ajoy_sample_s *sample)
+{
+ memcpy(sample, &g_ajoy_sample, sizeof(struct ajoy_sample_s));
+ g_ajoy_buttons = g_ajoy_sample.as_buttons;
+ g_ajoy_valid = false;
+ return OK;
+}
+
+/****************************************************************************
+ * Name: ajoy_buttons
+ *
+ * Description:
+ * Return the current state of button data (only)
+ *
+ ****************************************************************************/
+
+static ajoy_buttonset_t ajoy_buttons(FAR const struct ajoy_lowerhalf_s *lower)
+{
+ g_ajoy_valid = false;
+ g_ajoy_buttons = g_ajoy_sample.as_buttons;
+ return g_ajoy_buttons;
+}
+
+/****************************************************************************
+ * Name: ajoy_enable
+ *
+ * Description:
+ * Enable interrupts on the selected set of joystick buttons. And empty
+ * set will disable all interrupts.
+ *
+ ****************************************************************************/
+
+static void ajoy_enable(FAR const struct ajoy_lowerhalf_s *lower,
+ ajoy_buttonset_t pressset, ajoy_buttonset_t releaseset,
+ ajoy_handler_t handler, FAR void *arg)
+{
+ if (handler)
+ {
+ ajoy_buttonset_t changed;
+ ajoy_buttonset_t pressed;
+ ajoy_buttonset_t released;
+
+ g_ajoy_waiting = true;
+ while (!g_ajoy_valid)
+ {
+ (void)sem_wait(&g_ajoy_waitsem);
+
+ if (g_ajoy_valid)
+ {
+ g_ajoy_valid = false;
+ changed = g_ajoy_buttons ^ g_ajoy_sample.as_buttons;
+
+ pressed = changed & (AJOY_SUPPORTED & g_ajoy_buttons);
+ if ((pressed & pressset) != 0 )
+ {
+ break;
+ }
+
+ released = changed & (AJOY_SUPPORTED & ~g_ajoy_buttons);
+ if ((released & releaseset) != 0)
+ {
+ break;
+ }
+ }
+ }
+
+ g_ajoy_waiting = false;
+
+ /* Call the interrupt handler */
+
+ handler(&g_ajoylower, arg);
+ }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sim_ajoy_initialize
+ *
+ * Description:
+ * Initialize and register the button joystick driver
+ *
+ ****************************************************************************/
+
+int sim_ajoy_initialize(void)
+{
+ int ret;
+
+ /* Initialize the wait semaphore */
+
+ sem_init(&g_ajoy_waitsem, 0, 0);
+
+ /* Register the joystick device as /dev/ajoy0 */
+
+ ret = ajoy_register("/dev/ajoy0", &g_ajoylower);
+ if (ret == OK)
+ {
+ /* Enable X11 event processing from the IDLE loop */
+
+ g_eventloop = 1;
+ }
+}
+
+/****************************************************************************
+ * Name: up_buttonevent
+ ****************************************************************************/
+
+int up_buttonevent(int x, int y, int buttons)
+{
+ /* Same the positional data */
+
+ g_ajoy_sample.as_x = x;
+ g_ajoy_sample.as_y = y;
+
+ /* Map X11 buttons to joystick buttons */
+
+ g_ajoy_sample.as_buttons = 0;
+ if ((buttons & 1) != 0)
+ {
+ g_ajoy_sample.as_buttons |= AJOY_BUTTON_1_BIT;
+ }
+
+ if ((buttons & 1) != 0)
+ {
+ g_ajoy_sample.as_buttons |= AJOY_BUTTON_2_BIT;
+ }
+
+ if ((buttons & 1) != 0)
+ {
+ g_ajoy_sample.as_buttons |= AJOY_BUTTON_3_BIT;
+ }
+
+ /* Sample data is valid */
+
+ g_ajoy_valid = true;
+
+ /* Is there a task waiting for joystick input? */
+
+ if (g_ajoy_waiting)
+ {
+ sem_post(&g_ajoy_waitsem);
+ }
+
+ return OK;
+}
+
+#endif /* CONFIG_AJOYSTICK */
diff --git a/nuttx/arch/sim/src/up_idle.c b/nuttx/arch/sim/src/up_idle.c
index cfe4a7d6d..ae7c2d704 100644
--- a/nuttx/arch/sim/src/up_idle.c
+++ b/nuttx/arch/sim/src/up_idle.c
@@ -153,7 +153,7 @@ void up_idle(void)
#ifdef CONFIG_SIM_X11FB
if (g_x11initialized)
{
-#ifdef CONFIG_SIM_TOUCHSCREEN
+#if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK)
/* Drive the X11 event loop */
if (g_eventloop)
diff --git a/nuttx/arch/sim/src/up_internal.h b/nuttx/arch/sim/src/up_internal.h
index c2fac55d2..80c9cc81a 100644
--- a/nuttx/arch/sim/src/up_internal.h
+++ b/nuttx/arch/sim/src/up_internal.h
@@ -61,6 +61,10 @@
# error "CONFIG_SIM_TOUCHSCREEN depends on CONFIG_SIM_X11FB"
# undef CONFIG_SIM_TOUCHSCREEN
# endif
+# ifdef CONFIG_SIM_AJOYSTICK
+# error "CONFIG_SIM_AJOYSTICK depends on CONFIG_SIM_X11FB"
+# undef CONFIG_SIM_AJOYSTICK
+# endif
#endif
#ifndef CONFIG_INPUT
@@ -68,6 +72,10 @@
# error "CONFIG_SIM_TOUCHSCREEN depends on CONFIG_INPUT"
# undef CONFIG_SIM_TOUCHSCREEN
# endif
+# ifdef CONFIG_SIM_AJOYSTICK
+# error "CONFIG_SIM_AJOYSTICK depends on CONFIG_INPUT"
+# undef CONFIG_SIM_AJOYSTICK
+# endif
#endif
/* Determine which (if any) console driver to use */
@@ -184,7 +192,7 @@
#ifdef CONFIG_SIM_X11FB
extern int g_x11initialized;
-#ifdef CONFIG_SIM_TOUCHSCREEN
+#if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK)
extern volatile int g_eventloop;
#endif
#endif
@@ -251,16 +259,24 @@ int up_x11cmap(unsigned short first, unsigned short len,
/* up_eventloop.c *********************************************************/
-#if defined(CONFIG_SIM_X11FB) && defined(CONFIG_SIM_TOUCHSCREEN)
+#if defined(CONFIG_SIM_X11FB) && \
+ (defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK))
void up_x11events(void);
#endif
/* up_eventloop.c *********************************************************/
-#if defined(CONFIG_SIM_X11FB) && defined(CONFIG_SIM_TOUCHSCREEN)
+#if defined(CONFIG_SIM_X11FB) && \
+ (defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK))
int up_buttonevent(int x, int y, int buttons);
#endif
+/* up_ajoystick.c *********************************************************/
+
+#ifdef CONFIG_SIM_AJOYSTICK
+int sim_ajoy_initialize(void);
+#endif
+
/* up_tapdev.c ************************************************************/
#if defined(CONFIG_NET) && !defined(__CYGWIN__)
diff --git a/nuttx/arch/sim/src/up_x11eventloop.c b/nuttx/arch/sim/src/up_x11eventloop.c
index 630bc80e1..a7c29e1ec 100644
--- a/nuttx/arch/sim/src/up_x11eventloop.c
+++ b/nuttx/arch/sim/src/up_x11eventloop.c
@@ -83,9 +83,26 @@ volatile int g_eventloop;
static int up_buttonmap(int state)
{
- /* Remove any X11 dependencies. Just maps Button1Mask to bit 0. */
+ int buttons = 0;
- return ((state & Button1Mask) != 0) ? 1 : 0;
+ /* Remove any X11 dependencies. Just maps ButtonNMask to bit N. */
+
+ if ((state & Button1Mask) != 0)
+ {
+ buttons |= 1;
+ }
+
+ if ((state & Button2Mask) != 0)
+ {
+ buttons |= 2;
+ }
+
+ if ((state & Button3Mask) != 0)
+ {
+ buttons |= 4;
+ }
+
+ return buttons;
}
/****************************************************************************
diff --git a/nuttx/arch/sim/src/up_x11framebuffer.c b/nuttx/arch/sim/src/up_x11framebuffer.c
index 39bd3647e..5eb3b2a23 100644
--- a/nuttx/arch/sim/src/up_x11framebuffer.c
+++ b/nuttx/arch/sim/src/up_x11framebuffer.c
@@ -136,7 +136,7 @@ static inline int up_x11createframe(void)
/* Release queued events on the display */
-#ifdef CONFIG_SIM_TOUCHSCREEN
+#if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK)
(void)XAllowEvents(g_display, AsyncBoth, CurrentTime);
/* Grab mouse button 1, enabling mouse-related events */
@@ -222,7 +222,7 @@ static void up_x11uninitX(void)
/* Un-grab the mouse buttons */
-#ifdef CONFIG_SIM_TOUCHSCREEN
+#if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK)
XUngrabButton(g_display, Button1, AnyModifier, g_window);
#endif
g_x11initialized = 0;
diff --git a/nuttx/configs/sim/src/Makefile b/nuttx/configs/sim/src/Makefile
index 73de2f5b5..c07947f97 100644
--- a/nuttx/configs/sim/src/Makefile
+++ b/nuttx/configs/sim/src/Makefile
@@ -36,6 +36,7 @@
include $(TOPDIR)/Make.defs
CFLAGS += -I$(TOPDIR)/sched
+CFLAGS += -I$(TOPDIR)/arch/sim/src
ASRCS =
AOBJS = $(ASRCS:.S=$(OBJEXT))
diff --git a/nuttx/configs/sim/src/sim_boot.c b/nuttx/configs/sim/src/sim_boot.c
index ef84a689e..e4e282c78 100644
--- a/nuttx/configs/sim/src/sim_boot.c
+++ b/nuttx/configs/sim/src/sim_boot.c
@@ -40,6 +40,8 @@
#include <nuttx/config.h>
#include <nuttx/compiler.h>
+#include "up_internal.h"
+
#ifdef CONFIG_GRAPHICS_TRAVELER_ROMFSDEMO
int trv_mount_world(int minor, FAR const char *mountpoint);
#endif
@@ -80,6 +82,12 @@ int trv_mount_world(int minor, FAR const char *mountpoint);
#ifdef CONFIG_BOARD_INITIALIZE
void board_initialize(void)
{
+#ifdef CONFIG_AJOYSTICK
+ /* Initialize the simulated analog joystick input device */
+
+ sim_ajoy_initialize();
+#endif
+
#ifdef CONFIG_GRAPHICS_TRAVELER_ROMFSDEMO
/* Special initialization for the Traveler game simulation */
diff --git a/nuttx/configs/sim/traveler/defconfig b/nuttx/configs/sim/traveler/defconfig
index 4f4f2d63a..f12eb8df7 100644
--- a/nuttx/configs/sim/traveler/defconfig
+++ b/nuttx/configs/sim/traveler/defconfig
@@ -102,6 +102,8 @@ CONFIG_SIM_FBHEIGHT=400
CONFIG_SIM_FBWIDTH=640
CONFIG_SIM_FBBPP=32
# CONFIG_SIM_TOUCHSCREEN is not set
+CONFIG_SIM_AJOYSTICK=y
+# CONFIG_SIM_NOINPUT is not set
# CONFIG_SIM_SPIFLASH is not set
#