diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-12-14 10:19:07 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-12-14 10:19:07 -0600 |
commit | c4c14b4ea44e798b79b039bd597da6881956a34b (patch) | |
tree | f02b3d8c7cd98b1b8e24cd43a0724d832300a900 /nuttx | |
parent | c627d15288f61aa2cbb4d1484cf06f497fd5a9c2 (diff) | |
download | nuttx-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/Kconfig | 19 | ||||
-rw-r--r-- | nuttx/arch/sim/src/Makefile | 5 | ||||
-rw-r--r-- | nuttx/arch/sim/src/up_ajoystick.c | 274 | ||||
-rw-r--r-- | nuttx/arch/sim/src/up_idle.c | 2 | ||||
-rw-r--r-- | nuttx/arch/sim/src/up_internal.h | 22 | ||||
-rw-r--r-- | nuttx/arch/sim/src/up_x11eventloop.c | 21 | ||||
-rw-r--r-- | nuttx/arch/sim/src/up_x11framebuffer.c | 4 | ||||
-rw-r--r-- | nuttx/configs/sim/src/Makefile | 1 | ||||
-rw-r--r-- | nuttx/configs/sim/src/sim_boot.c | 8 | ||||
-rw-r--r-- | nuttx/configs/sim/traveler/defconfig | 2 |
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 # |