diff --git a/arch/sim/Kconfig b/arch/sim/Kconfig index 64f034e94f..5f8f4e6e93 100644 --- a/arch/sim/Kconfig +++ b/arch/sim/Kconfig @@ -302,6 +302,13 @@ config SIM_AJOYSTICK ---help--- Support an X11 mouse-based analog joystick emulation. Also needs INPUT=y +config SIM_BUTTONS + bool "X11 mouse-based button emulation" + depends on SIM_X11FB + ---help--- + Support an X11 mouse-based button emulation + (left-click mapped to button press). Also needs INPUT=y + config SIM_NOINPUT bool "No input device" diff --git a/arch/sim/src/Makefile b/arch/sim/src/Makefile index 9f9fa87bba..a6935effe2 100644 --- a/arch/sim/src/Makefile +++ b/arch/sim/src/Makefile @@ -148,6 +148,9 @@ else ifeq ($(CONFIG_SIM_AJOYSTICK),y) CSRCS += up_ajoystick.c HOSTCFLAGS += -DCONFIG_SIM_AJOYSTICK=1 HOSTSRCS += up_x11eventloop.c +else ifeq ($(CONFIG_SIM_BUTTONS),y) + HOSTCFLAGS += -DCONFIG_SIM_BUTTONS=1 + HOSTSRCS += up_x11eventloop.c endif endif diff --git a/arch/sim/src/sim/up_idle.c b/arch/sim/src/sim/up_idle.c index eacffeb660..a17d8d3eda 100644 --- a/arch/sim/src/sim/up_idle.c +++ b/arch/sim/src/sim/up_idle.c @@ -93,7 +93,8 @@ void up_idle(void) up_uartloop(); -#if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK) +#if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK) || \ + defined(CONFIG_SIM_BUTTONS) /* Drive the X11 event loop */ up_x11events(); diff --git a/arch/sim/src/sim/up_internal.h b/arch/sim/src/sim/up_internal.h index 8c1f77b44a..c35630897b 100644 --- a/arch/sim/src/sim/up_internal.h +++ b/arch/sim/src/sim/up_internal.h @@ -301,7 +301,8 @@ int sim_tsc_uninitialize(void); /* up_eventloop.c ***********************************************************/ -#if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK) +#if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK) || \ + defined(CONFIG_ARCH_BUTTONS) void up_x11events(void); void up_buttonevent(int x, int y, int buttons); #endif diff --git a/arch/sim/src/sim/up_x11eventloop.c b/arch/sim/src/sim/up_x11eventloop.c index 12c290548b..4f6e5bc321 100644 --- a/arch/sim/src/sim/up_x11eventloop.c +++ b/arch/sim/src/sim/up_x11eventloop.c @@ -85,7 +85,7 @@ static int up_buttonmap(int state, int button) * corresponding bit now */ - switch(button) + switch (button) { case Button1: buttons ^= 1; diff --git a/arch/sim/src/sim/up_x11framebuffer.c b/arch/sim/src/sim/up_x11framebuffer.c index 4e50c6cfb2..1dad5d2032 100644 --- a/arch/sim/src/sim/up_x11framebuffer.c +++ b/arch/sim/src/sim/up_x11framebuffer.c @@ -136,7 +136,8 @@ static inline int up_x11createframe(void) /* Release queued events on the display */ -#if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK) +#if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK) || \ + defined(CONFIG_SIM_BUTTONS) XAllowEvents(g_display, AsyncBoth, CurrentTime); /* Grab mouse button 1, enabling mouse-related events */ @@ -219,7 +220,8 @@ static void up_x11uninitX(void) /* Un-grab the mouse buttons */ -#if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK) +#if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK) || \ + defined(CONFIG_SIM_BUTTONS) XUngrabButton(g_display, Button1, AnyModifier, g_window); #endif diff --git a/boards/Kconfig b/boards/Kconfig index d013b8bbd2..457f4ddbc9 100644 --- a/boards/Kconfig +++ b/boards/Kconfig @@ -2068,6 +2068,8 @@ config ARCH_BOARD_SPRESENSE config ARCH_BOARD_SIM bool "User mode simulation" + select ARCH_HAVE_BUTTONS + select ARCH_HAVE_IRQBUTTONS depends on ARCH_SIM ---help--- A user-mode port of NuttX to the x86 Linux/Cygwin platform is available. diff --git a/boards/sim/sim/sim/src/Makefile b/boards/sim/sim/sim/src/Makefile index f609733c5a..06754fff7b 100644 --- a/boards/sim/sim/sim/src/Makefile +++ b/boards/sim/sim/sim/src/Makefile @@ -80,4 +80,8 @@ ifneq ($(CONFIG_NSH_CUSTOMROMFS),y) endif endif +ifeq ($(CONFIG_ARCH_BUTTONS),y) + CSRCS += sim_buttons.c +endif + include $(TOPDIR)/boards/Board.mk diff --git a/boards/sim/sim/sim/src/sim_bringup.c b/boards/sim/sim/sim/src/sim_bringup.c index 852cf0b13c..589a7791c3 100644 --- a/boards/sim/sim/sim/src/sim_bringup.c +++ b/boards/sim/sim/sim/src/sim_bringup.c @@ -47,6 +47,10 @@ #include #endif +#if defined(CONFIG_BUTTONS_LOWER) && defined(CONFIG_SIM_BUTTONS) +#include +#endif + #include "up_internal.h" #include "sim.h" @@ -380,5 +384,13 @@ int sim_bringup(void) #endif #endif +#if defined(CONFIG_BUTTONS_LOWER) && defined(CONFIG_SIM_BUTTONS) + ret = btn_lower_initialize("/dev/buttons"); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: btn_lower_initialize() failed: %d\n", ret); + } +#endif + return ret; } diff --git a/boards/sim/sim/sim/src/sim_buttons.c b/boards/sim/sim/sim/src/sim_buttons.c new file mode 100644 index 0000000000..a38f93fb36 --- /dev/null +++ b/boards/sim/sim/sim/src/sim_buttons.c @@ -0,0 +1,143 @@ +/**************************************************************************** + * boards/sim/sim/sim/scripts/sim_buttons.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +uint32_t g_buttons = 0; +xcpt_t g_handler = NULL; +FAR void *g_arg = 0; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_button_initialize + * + * Description: + * board_button_initialize() must be called to initialize button resources. + * After that, board_buttons() may be called to collect the current state + * of all buttons or board_button_irq() may be called to register button + * interrupt handlers. + * + ****************************************************************************/ + +uint32_t board_button_initialize(void) +{ + /* For now this just supports the mouse click */ + + return 1; +} + +/**************************************************************************** + * Name: board_buttons + ****************************************************************************/ + +uint32_t board_buttons(void) +{ + return g_buttons; +} + +/**************************************************************************** + * Button support. + * + * Description: + * board_button_initialize() must be called to initialize button resources. + * After that, board_buttons() may be called to collect the current + * state of all buttons or board_button_irq() may be called to register + * button interrupt handlers. + * + * After board_button_initialize() has been called, board_buttons() + * may be called to collect the state of all buttons. board_buttons() + * returns an 32-bit bit set with each bit associated with a button. + * See the BUTTON_*_BIT definitions in board.h for the meaning of each + * bit. + * + * board_button_irq() may be called to register an interrupt handler that + * will be called when a button is depressed or released. The ID value + * is a button enumeration value that uniquely identifies a button + * resource. See the BUTTON_* definitions in board.h for the meaning of + * enumeration value. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQBUTTONS +int board_button_irq(int id, xcpt_t irqhandler, FAR void *arg) +{ + int ret = -EINVAL; + + if (id == 0) + { + g_handler = irqhandler; + g_arg = arg; + } + + return ret; +} +#endif + +/**************************************************************************** + * Name: up_buttonevent + ****************************************************************************/ + +void up_buttonevent(int x, int y, int buttons) +{ + bool changed = g_buttons != buttons; + g_buttons = buttons; + + if (changed && g_handler) + { + /* Emulate the interrupt */ + + g_handler(0, NULL, g_arg); + } +}