Don't run X11 event loop on a pthread; X11 is not thread-safe.

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4001 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2011-09-29 21:13:49 +00:00
parent 398d60ede7
commit 97f7f3d630
5 changed files with 57 additions and 52 deletions

View File

@ -130,7 +130,19 @@ void up_idle(void)
#if defined(CONFIG_SIM_WALLTIME) || defined(CONFIG_SIM_X11FB) #if defined(CONFIG_SIM_WALLTIME) || defined(CONFIG_SIM_X11FB)
(void)up_hostusleep(1000000 / CLK_TCK); (void)up_hostusleep(1000000 / CLK_TCK);
/* Handle X11-related events */
#ifdef CONFIG_SIM_X11FB #ifdef CONFIG_SIM_X11FB
#ifdef CONFIG_SIM_TOUCHSCREEN
if (g_eventloop)
{
up_x11events();
}
#endif
/* Update the display periodically */
g_x11refresh += 1000000 / CLK_TCK; g_x11refresh += 1000000 / CLK_TCK;
if (g_x11refresh > 500000) if (g_x11refresh > 500000)
{ {

View File

@ -117,7 +117,7 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#if defined(CONFIG_SIM_X11FB) && defined(CONFIG_SIM_TOUCHSCREEN) #if defined(CONFIG_SIM_X11FB) && defined(CONFIG_SIM_TOUCHSCREEN)
extern volatile int g_evloopactive; extern volatile int g_eventloop;
#endif #endif
/************************************************************************** /**************************************************************************
@ -165,7 +165,7 @@ extern int up_x11cmap(unsigned short first, unsigned short len,
/* up_eventloop.c ***********************************************************/ /* up_eventloop.c ***********************************************************/
#if defined(CONFIG_SIM_X11FB) && defined(CONFIG_SIM_TOUCHSCREEN) #if defined(CONFIG_SIM_X11FB) && defined(CONFIG_SIM_TOUCHSCREEN)
extern int up_x11eventloop(void); extern void up_x11events(void);
#endif #endif
/* up_eventloop.c ***********************************************************/ /* up_eventloop.c ***********************************************************/

View File

@ -661,15 +661,6 @@ int sim_tcinitialize(int minor)
priv->minor = minor; priv->minor = minor;
/* Start the X11 event loop */
ret = up_x11eventloop();
if (ret < 0)
{
idbg("Failed to start event loop: %d\n", ret);
goto errout_with_priv;
}
/* Register the device as an input device */ /* Register the device as an input device */
(void)snprintf(devname, DEV_NAMELEN, DEV_FORMAT, minor); (void)snprintf(devname, DEV_NAMELEN, DEV_FORMAT, minor);
@ -682,6 +673,10 @@ int sim_tcinitialize(int minor)
goto errout_with_priv; goto errout_with_priv;
} }
/* Enable X11 event processing from the IDLE loop */
g_eventloop = 1;
/* And return success */ /* And return success */
return OK; return OK;
@ -731,7 +726,7 @@ void sim_tcuninitialize(void)
* done in close() using a reference count). * done in close() using a reference count).
*/ */
g_evloopactive = 0; g_eventloop = 0;
/* Un-register the device*/ /* Un-register the device*/

View File

@ -38,7 +38,6 @@
****************************************************************************/ ****************************************************************************/
#include <stdio.h> #include <stdio.h>
#include <pthread.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -59,7 +58,6 @@
****************************************************************************/ ****************************************************************************/
extern int up_buttonevent(int x, int y, int buttons); extern int up_buttonevent(int x, int y, int buttons);
extern int up_tcleave(int x, int y, int buttons);
/**************************************************************************** /****************************************************************************
* Public Variables * Public Variables
@ -68,10 +66,8 @@ extern int up_tcleave(int x, int y, int buttons);
/* Defined in up_x11framebuffer.c */ /* Defined in up_x11framebuffer.c */
extern Display *g_display; extern Display *g_display;
extern Window g_window;
pthread_t g_eventloop; volatile int g_eventloop;
volatile int g_evloopactive;
/**************************************************************************** /****************************************************************************
* Private Variables * Private Variables
@ -93,32 +89,33 @@ static int up_buttonmap(int state)
} }
/**************************************************************************** /****************************************************************************
* Name: up_x11eventthread * Public Functions
***************************************************************************/ ***************************************************************************/
static void *up_x11eventthread(void *arg) /****************************************************************************
* Name: up_x11events
*
* Description:
* Called periodically from the IDLE loop to check for queued X11 events.
*
***************************************************************************/
void up_x11events(void)
{ {
Window window;
XEvent event; XEvent event;
/* Release queued events on the display */ /* Check if there are any pending, queue X11 events. */
(void)XAllowEvents(g_display, AsyncBoth, CurrentTime); if (XPending(g_display) > 0)
/* Grab mouse button 1, enabling mouse-related events */
window = DefaultRootWindow(g_display);
(void)XGrabButton(g_display, Button1, AnyModifier, window, 1,
ButtonPressMask|ButtonReleaseMask|ButtonMotionMask,
GrabModeAsync, GrabModeAsync, None, None);
/* Then loop until we are commanded to stop (when g_evloopactive becomes zero),
* waiting for events and processing events as they are received.
*/
while ( g_evloopactive)
{ {
/* Yes, get the event (this should not block since we know there are
* pending events)
*/
XNextEvent(g_display, &event); XNextEvent(g_display, &event);
/* Then process the event */
switch (event.type) switch (event.type)
{ {
case MotionNotify : /* Enabled by ButtonMotionMask */ case MotionNotify : /* Enabled by ButtonMotionMask */
@ -140,21 +137,4 @@ static void *up_x11eventthread(void *arg)
break; break;
} }
} }
XUngrabButton(g_display, Button1, AnyModifier, window);
return NULL;
} }
/****************************************************************************
* Name: up_x11eventloop
***************************************************************************/
int up_x11eventloop(void)
{
/* Start the X11 event loop */
g_evloopactive = 1;
return pthread_create(&g_eventloop, 0, up_x11eventthread, 0);
}

View File

@ -133,6 +133,18 @@ static inline int up_x11createframe(void)
XSelectInput(g_display, g_window, XSelectInput(g_display, g_window,
ButtonPressMask|ButtonReleaseMask|ButtonMotionMask|KeyPressMask); ButtonPressMask|ButtonReleaseMask|ButtonMotionMask|KeyPressMask);
/* Release queued events on the display */
#ifdef CONFIG_SIM_TOUCHSCREEN
(void)XAllowEvents(g_display, AsyncBoth, CurrentTime);
/* Grab mouse button 1, enabling mouse-related events */
(void)XGrabButton(g_display, Button1, AnyModifier, g_window, 1,
ButtonPressMask|ButtonReleaseMask|ButtonMotionMask,
GrabModeAsync, GrabModeAsync, None, None);
#endif
gcval.graphics_exposures = 0; gcval.graphics_exposures = 0;
g_gc = XCreateGC(g_display, g_window, GCGraphicsExposures, &gcval); g_gc = XCreateGC(g_display, g_window, GCGraphicsExposures, &gcval);
return 0; return 0;
@ -203,6 +215,12 @@ static void up_x11uninitX(void)
{ {
XDestroyImage(g_image); XDestroyImage(g_image);
} }
/* Un-grab the mouse buttons */
#ifdef CONFIG_SIM_TOUCHSCREEN
XUngrabButton(g_display, Button1, AnyModifier, g_window);
#endif
XCloseDisplay(g_display); XCloseDisplay(g_display);
} }