From eaf142837ca2b85afa7037292dc5a08c34ff8367 Mon Sep 17 00:00:00 2001 From: patacongo Date: Thu, 29 Sep 2011 21:13:49 +0000 Subject: 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 --- nuttx/arch/sim/src/up_idle.c | 12 +++++++ nuttx/arch/sim/src/up_internal.h | 4 +-- nuttx/arch/sim/src/up_touchscreen.c | 15 +++------ nuttx/arch/sim/src/up_x11eventloop.c | 58 +++++++++++----------------------- nuttx/arch/sim/src/up_x11framebuffer.c | 18 +++++++++++ 5 files changed, 56 insertions(+), 51 deletions(-) diff --git a/nuttx/arch/sim/src/up_idle.c b/nuttx/arch/sim/src/up_idle.c index f1d9974d2..70d25f1d6 100644 --- a/nuttx/arch/sim/src/up_idle.c +++ b/nuttx/arch/sim/src/up_idle.c @@ -130,7 +130,19 @@ void up_idle(void) #if defined(CONFIG_SIM_WALLTIME) || defined(CONFIG_SIM_X11FB) (void)up_hostusleep(1000000 / CLK_TCK); + + /* Handle X11-related events */ + #ifdef CONFIG_SIM_X11FB +#ifdef CONFIG_SIM_TOUCHSCREEN + if (g_eventloop) + { + up_x11events(); + } +#endif + + /* Update the display periodically */ + g_x11refresh += 1000000 / CLK_TCK; if (g_x11refresh > 500000) { diff --git a/nuttx/arch/sim/src/up_internal.h b/nuttx/arch/sim/src/up_internal.h index 1b06dae21..b0a365b4b 100644 --- a/nuttx/arch/sim/src/up_internal.h +++ b/nuttx/arch/sim/src/up_internal.h @@ -117,7 +117,7 @@ #ifndef __ASSEMBLY__ #if defined(CONFIG_SIM_X11FB) && defined(CONFIG_SIM_TOUCHSCREEN) -extern volatile int g_evloopactive; +extern volatile int g_eventloop; #endif /************************************************************************** @@ -165,7 +165,7 @@ extern int up_x11cmap(unsigned short first, unsigned short len, /* up_eventloop.c ***********************************************************/ #if defined(CONFIG_SIM_X11FB) && defined(CONFIG_SIM_TOUCHSCREEN) -extern int up_x11eventloop(void); +extern void up_x11events(void); #endif /* up_eventloop.c ***********************************************************/ diff --git a/nuttx/arch/sim/src/up_touchscreen.c b/nuttx/arch/sim/src/up_touchscreen.c index 3765d9e6e..bc94d6056 100644 --- a/nuttx/arch/sim/src/up_touchscreen.c +++ b/nuttx/arch/sim/src/up_touchscreen.c @@ -661,15 +661,6 @@ int sim_tcinitialize(int 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 */ (void)snprintf(devname, DEV_NAMELEN, DEV_FORMAT, minor); @@ -682,6 +673,10 @@ int sim_tcinitialize(int minor) goto errout_with_priv; } + /* Enable X11 event processing from the IDLE loop */ + + g_eventloop = 1; + /* And return success */ return OK; @@ -731,7 +726,7 @@ void sim_tcuninitialize(void) * done in close() using a reference count). */ - g_evloopactive = 0; + g_eventloop = 0; /* Un-register the device*/ diff --git a/nuttx/arch/sim/src/up_x11eventloop.c b/nuttx/arch/sim/src/up_x11eventloop.c index 4e35d25ab..478388065 100644 --- a/nuttx/arch/sim/src/up_x11eventloop.c +++ b/nuttx/arch/sim/src/up_x11eventloop.c @@ -38,7 +38,6 @@ ****************************************************************************/ #include -#include #include @@ -59,7 +58,6 @@ ****************************************************************************/ extern int up_buttonevent(int x, int y, int buttons); -extern int up_tcleave(int x, int y, int buttons); /**************************************************************************** * Public Variables @@ -68,10 +66,8 @@ extern int up_tcleave(int x, int y, int buttons); /* Defined in up_x11framebuffer.c */ extern Display *g_display; -extern Window g_window; -pthread_t g_eventloop; -volatile int g_evloopactive; +volatile int g_eventloop; /**************************************************************************** * 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; - /* 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) + { + /* Yes, get the event (this should not block since we know there are + * pending events) + */ - /* Grab mouse button 1, enabling mouse-related events */ + XNextEvent(g_display, &event); - window = DefaultRootWindow(g_display); - (void)XGrabButton(g_display, Button1, AnyModifier, window, 1, - ButtonPressMask|ButtonReleaseMask|ButtonMotionMask, - GrabModeAsync, GrabModeAsync, None, None); + /* Then process the event */ - /* 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) - { - XNextEvent(g_display, &event); switch (event.type) { case MotionNotify : /* Enabled by ButtonMotionMask */ @@ -140,21 +137,4 @@ static void *up_x11eventthread(void *arg) 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); -} - - diff --git a/nuttx/arch/sim/src/up_x11framebuffer.c b/nuttx/arch/sim/src/up_x11framebuffer.c index 7b1a0a2c8..4d8c9b9a5 100644 --- a/nuttx/arch/sim/src/up_x11framebuffer.c +++ b/nuttx/arch/sim/src/up_x11framebuffer.c @@ -133,6 +133,18 @@ static inline int up_x11createframe(void) XSelectInput(g_display, g_window, 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; g_gc = XCreateGC(g_display, g_window, GCGraphicsExposures, &gcval); return 0; @@ -203,6 +215,12 @@ static void up_x11uninitX(void) { XDestroyImage(g_image); } + + /* Un-grab the mouse buttons */ + +#ifdef CONFIG_SIM_TOUCHSCREEN + XUngrabButton(g_display, Button1, AnyModifier, g_window); +#endif XCloseDisplay(g_display); } -- cgit v1.2.3