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:
parent
398d60ede7
commit
97f7f3d630
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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 ***********************************************************/
|
||||||
|
@ -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*/
|
||||||
|
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user