diff --git a/arch/sim/src/up_internal.h b/arch/sim/src/up_internal.h index 2a1d9372a1d46368693525359e13a9d80c8ac0c1..fdb798fc2391a7e60322f47102c6d030a47ffee9 100644 --- a/arch/sim/src/up_internal.h +++ b/arch/sim/src/up_internal.h @@ -114,12 +114,16 @@ * Public Variables **************************************************************************/ +#ifndef __ASSEMBLY__ + +#if defined(CONFIG_SIM_X11FB) && defined(CONFIG_SIM_TOUCHSCREEN) +extern volatile int g_evloopactive; +#endif + /************************************************************************** * Public Function Prototypes **************************************************************************/ -#ifndef __ASSEMBLY__ - /* up_setjmp.S ************************************************************/ extern int up_setjmp(int *jb); @@ -160,20 +164,16 @@ extern int up_x11cmap(unsigned short first, unsigned short len, /* up_eventloop.c ***********************************************************/ -#ifdef CONFIG_SIM_X11FB -#ifdef CONFIG_SIM_TOUCHSCREEN +#if defined(CONFIG_SIM_X11FB) && defined(CONFIG_SIM_TOUCHSCREEN) extern int up_x11eventloop(void); #endif -#endif /* up_eventloop.c ***********************************************************/ -#ifdef CONFIG_SIM_X11FB -#ifdef CONFIG_SIM_TOUCHSCREEN +#if defined(CONFIG_SIM_X11FB) && defined(CONFIG_SIM_TOUCHSCREEN) extern int up_tcenter(int x, int y, int buttons); extern int up_tcleave(int x, int y, int buttons); #endif -#endif /* up_tapdev.c ************************************************************/ diff --git a/arch/sim/src/up_touchscreen.c b/arch/sim/src/up_touchscreen.c index 277bfb73994c1592ba14147190cc986ac05c4b75..b012ff5b24af8040c2817bdbcde05caaaef43762 100644 --- a/arch/sim/src/up_touchscreen.c +++ b/arch/sim/src/up_touchscreen.c @@ -103,6 +103,7 @@ struct up_dev_s { uint8_t nwaiters; /* Number of threads waiting for touchscreen data */ uint8_t id; /* Current touch point ID */ + uint8_t minor; /* Minor device number */ bool penchange; /* An unreported event is buffered */ sem_t devsem; /* Manages exclusive access to this structure */ sem_t waitsem; /* Used to wait for the availability of data */ @@ -601,7 +602,7 @@ errout: ****************************************************************************/ /**************************************************************************** - * Name: up_simtouchscreen + * Name: sim_tcinitialize * * Description: * Configure the simulated touchscreen. This will register the driver as @@ -616,13 +617,13 @@ errout: * ****************************************************************************/ -int up_simtouchscreen(int minor) +int sim_tcinitialize(int minor) { FAR struct up_dev_s *priv = ( FAR struct up_dev_s *)&g_simtouchscreen; char devname[DEV_NAMELEN]; int ret; - ivdbg("dev: %p minor: %d\n", dev, minor); + ivdbg("minor: %d\n", minor); /* Debug-only sanity checks */ @@ -634,6 +635,8 @@ int up_simtouchscreen(int minor) sem_init(&priv->devsem, 0, 1); /* Initialize device structure semaphore */ sem_init(&priv->waitsem, 0, 0); /* Initialize pen event wait semaphore */ + priv->minor = minor; + /* Start the X11 event loop */ ret = up_x11eventloop(); @@ -655,7 +658,7 @@ int up_simtouchscreen(int minor) goto errout_with_priv; } - /* And return success (?) */ + /* And return success */ return OK; @@ -665,6 +668,64 @@ errout_with_priv: return ret; } +/**************************************************************************** + * Name: sim_tcuninitialize + * + * Description: + * Uninitialized the simulated touchscreen + * + * Input Parameters: + * None + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void sim_tcuninitialize(void) +{ + FAR struct up_dev_s *priv = ( FAR struct up_dev_s *)&g_simtouchscreen; + char devname[DEV_NAMELEN]; + int ret; + + /* Get exclusive access */ + + do + { + ret = sem_wait(&priv->devsem); + if (ret < 0) + { + /* This should only happen if the wait was canceled by an signal */ + + DEBUGASSERT(errno == EINTR); + } + } + while (ret != OK); + + /* Stop the event loop (Hmm.. the caller must be sure that there are no + * open references to the touchscreen driver. This might better be + * done in close() using a reference count). + */ + + g_evloopactive = 0; + + /* Un-register the device*/ + + (void)snprintf(devname, DEV_NAMELEN, DEV_FORMAT, priv->minor); + ivdbg("Un-registering %s\n", devname); + + ret = runegister_driver(devname); + if (ret < 0) + { + idbg("uregister_driver() failed: %d\n", ret); + } + + /* Clean up any resources. Ouch! While we are holding the semaphore? */ + + sem_destroy(&priv->waitsem); + sem_destroy(&priv->devsem); +} + /**************************************************************************** * Name: up_tcenter ****************************************************************************/ @@ -672,7 +733,9 @@ errout_with_priv: int up_tcenter(int x, int y, int buttons) { FAR struct up_dev_s *priv = (FAR struct up_dev_s *)&g_simtouchscreen; - bool pendown; /* true: pend is down */ + bool pendown; /* true: pen is down */ + + ivdbg("x=%d y=%d buttons=%02x\n", x, y, buttons); /* Any button press will count as pendown. */ @@ -735,6 +798,8 @@ int up_tcleave(int x, int y, int buttons) { FAR struct up_dev_s *priv = (FAR struct up_dev_s *)&g_simtouchscreen; + ivdbg("x=%d y=%d buttons=%02x\n", x, y, buttons); + /* Treat leaving as penup */ /* Ignore the pen up if the pen was already up (CONTACT_NONE == pen up and diff --git a/arch/sim/src/up_x11eventloop.c b/arch/sim/src/up_x11eventloop.c index 6020433c44fec49d7928f2716a45e7ba82c3f6b1..4973508ea82c298de327eb96559dd3ed3173cde4 100644 --- a/arch/sim/src/up_x11eventloop.c +++ b/arch/sim/src/up_x11eventloop.c @@ -71,6 +71,7 @@ extern Display *g_display; extern Window g_window; pthread_t g_eventloop; +volatile int g_evloopactive; /**************************************************************************** * Private Variables @@ -147,7 +148,7 @@ static void *up_x11eventthread(void *arg) * within the following loop. */ - for (;;) + while (g_evloopactive) { XNextEvent(g_display, &event); switch (event.type) @@ -196,6 +197,7 @@ int up_x11eventloop(void) { /* Start the X11 event loop */ + g_evloopactive = 1; return pthread_create(&g_eventloop, 0, up_x11eventthread, 0); } diff --git a/configs/sim/README.txt b/configs/sim/README.txt index 3a9348d1ce8d938dac5515dd2754172fa257d5e8..592fb3a471e281071f975a7183c2a2edf3d524bc 100644 --- a/configs/sim/README.txt +++ b/configs/sim/README.txt @@ -267,16 +267,23 @@ nx11 CONFIG_SIM_TOUCHSCREEN=y Then you must also have some application logic that will call - up_simtouchscreen(0) to register the touchscreen driver. + sim_tcinitializ(0) to register the touchscreen driver. NOTES: - 1. If you do not have this call, the build will mysteriously - fail claiming that is can't find up_tcenter(0 and up_tcleave(). - That is a consequence of the crazy way that the simulation is - built and can only be eliminated by call up_simtouchscreen(0) - from your application. - 2. You must first call + 1. If you do not have the call to sim_tcinitializE(0), the build + will mysteriously fail claiming that is can't find up_tcenter() + and up_tcleave(). That is a consequence of the crazy way that + the simulation is built and can only be eliminated by calling + up_simtouchscreen(0) from your application. + + 2. You must first up_fbinitialize() before calling up_simtouchscreen() + or you will get a crash. + + 3. Call sim_tcuninintialize() when you are finished with the + simulated touchscreen. + + 4. Enable CONFIG_DEBUG_INPUT=y for touchscreen debug output. X11 Build Issues ---------------- diff --git a/include/nuttx/input/touchscreen.h b/include/nuttx/input/touchscreen.h index 35fdf346962f126b8a862f595a21d231b5d81e26..33d5c5282ffe2812e7da8f246e21fd5edc69e93f 100644 --- a/include/nuttx/input/touchscreen.h +++ b/include/nuttx/input/touchscreen.h @@ -128,11 +128,11 @@ extern "C" { #endif /**************************************************************************** - * Name: up_simtouchscreen + * Name: sim_tcinitialize * * Description: * Configure the simulated touchscreen. This will register the driver as - * /dev/inputN where N is the minor device number + * /dev/inputN where N is the minor device number. * * Input Parameters: * minor - The input device minor number @@ -144,7 +144,25 @@ extern "C" { ****************************************************************************/ #if defined(CONFIG_SIM_X11FB) && defined(CONFIG_SIM_TOUCHSCREEN) -EXTERN int up_simtouchscreen(int minor); +EXTERN int sim_tcinitialize(int minor); +#endif + +/**************************************************************************** + * Name: sim_tcuninitialize + * + * Description: + * Uninitialized the simulated touchscreen + * + * Input Parameters: + * None + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#if defined(CONFIG_SIM_X11FB) && defined(CONFIG_SIM_TOUCHSCREEN) +EXTERN void sim_tcuninitialize(void); #endif #undef EXTERN