diff --git a/configs/sim/nx/defconfig b/configs/sim/nx/defconfig
index 8218088bb11ffc251365bbb5606ee6ede8b1bacf..27c5baf60f7494689901e1525ee8f6e0f9aec5b8 100644
--- a/configs/sim/nx/defconfig
+++ b/configs/sim/nx/defconfig
@@ -123,9 +123,9 @@ CONFIG_DEV_LOWCONSOLE=n
 #
 CONFIG_DISABLE_CLOCK=n
 CONFIG_DISABLE_POSIX_TIMERS=y
-CONFIG_DISABLE_PTHREAD=y
+CONFIG_DISABLE_PTHREAD=n
 CONFIG_DISABLE_SIGNALS=n
-CONFIG_DISABLE_MQUEUE=y
+CONFIG_DISABLE_MQUEUE=n
 CONFIG_DISABLE_MOUNTPOINT=y
 CONFIG_DISABLE_ENVIRON=y
 CONFIG_DISABLE_POLL=y
@@ -343,7 +343,7 @@ CONFIG_NXGLIB_DISABLE_32BPP=y
 CONFIG_NXGL_PACKEDMSFIRST=n
 CONFIG_NX_MOUSE=y
 CONFIG_NX_KBD=n
-CONFIG_NX_BLOCKING=n
+CONFIG_NX_BLOCKING=y
 CONFIG_NX_MXSERVERMSGS=32
 CONFIG_NX_MXCLIENTMSGS=16
 
diff --git a/configs/sim/nx/defconfig-x11 b/configs/sim/nx/defconfig-x11
index 5c95f8eabc701ba8da6ea91a01569892fc4866ad..397159148a78b004f9ed90e076ef5877fbad95d3 100644
--- a/configs/sim/nx/defconfig-x11
+++ b/configs/sim/nx/defconfig-x11
@@ -123,9 +123,9 @@ CONFIG_DEV_LOWCONSOLE=n
 #
 CONFIG_DISABLE_CLOCK=n
 CONFIG_DISABLE_POSIX_TIMERS=y
-CONFIG_DISABLE_PTHREAD=y
+CONFIG_DISABLE_PTHREAD=n
 CONFIG_DISABLE_SIGNALS=n
-CONFIG_DISABLE_MQUEUE=y
+CONFIG_DISABLE_MQUEUE=n
 CONFIG_DISABLE_MOUNTPOINT=y
 CONFIG_DISABLE_ENVIRON=y
 CONFIG_DISABLE_POLL=y
@@ -343,7 +343,7 @@ CONFIG_NXGLIB_DISABLE_32BPP=n
 CONFIG_NXGL_PACKEDMSFIRST=n
 CONFIG_NX_MOUSE=y
 CONFIG_NX_KBD=n
-CONFIG_NX_BLOCKING=n
+CONFIG_NX_BLOCKING=y
 CONFIG_NX_MXSERVERMSGS=32
 CONFIG_NX_MXCLIENTMSGS=16
 
diff --git a/examples/README.txt b/examples/README.txt
index 2fbb54e8f76f61c339b98fcce4a158d22f099d0c..f3b7aba5cbfb4b54bc959c4354cc37f535647d08 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -74,11 +74,21 @@ examples/nx
 
     CONFIG_EXAMPLES_NX_STACKSIZE -- The stacksize to use when creating
       the NX server.  Default 2048
-    CONFIG_EXAMPLES_NX_CLIENTPRIO -- The client priority.  Default: 80
+    CONFIG_EXAMPLES_NX_CLIENTPRIO -- The client priority.  Default: 100
     CONFIG_EXAMPLES_NX_SERVERPRIO -- The server priority.  Default: 120
+    CONFIG_EXAMPLES_NX_LISTENERPRIO -- The priority of the event listener
+      thread. Default 80.
     CONFIG_EXAMPLES_NX_NOTIFYSIGNO -- The signal number to use with
       nx_eventnotify().  Default: 4
 
+  If CONFIG_NX_MULTIUSER is defined, then the example also expects the
+  following settings and will generate an error if they are not as expected:
+
+    CONFIG_DISABLE_MQUEUE=n
+    CONFIG_DISABLE_SIGNALS=n
+    CONFIG_DISABLE_PTHREAD=n
+    CONFIG_NX_BLOCKING=y
+
 examples/null
 ^^^^^^^^^^^^^
 
diff --git a/examples/nx/Makefile b/examples/nx/Makefile
index d15d17ae3d8ae1cfd5d2b633da5d1364d0648215..2447ae5754d4d399a35ec9d7b4b7e3bf6a87a318 100644
--- a/examples/nx/Makefile
+++ b/examples/nx/Makefile
@@ -39,7 +39,7 @@
 ASRCS	= 
 AOBJS	= $(ASRCS:.S=$(OBJEXT))
 
-CSRCS	= nx_main.c
+CSRCS	= nx_main.c nx_events.c
 ifeq ($(CONFIG_NX_MULTIUSER),y)
 CSRCS	+= nx_server.c
 endif
diff --git a/examples/nx/nx_events.c b/examples/nx/nx_events.c
new file mode 100644
index 0000000000000000000000000000000000000000..9d6b2f055fab87d4822366b20cddd1d5e85466a1
--- /dev/null
+++ b/examples/nx/nx_events.c
@@ -0,0 +1,319 @@
+/****************************************************************************
+ * examples/nx/nx_events.c
+ *
+ *   Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <semaphore.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/nx.h>
+#include "nx_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void nxeg_redraw1(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect,
+                         boolean morem, FAR void *arg);
+static void nxeg_redraw2(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect,
+                         boolean more, FAR void *arg);
+static void nxeg_position1(NXWINDOW hwnd, FAR const struct nxgl_rect_s *size,
+                           FAR const struct nxgl_point_s *pos,
+                           FAR const struct nxgl_rect_s *bounds,
+                           FAR void *arg);
+static void nxeg_position2(NXWINDOW hwnd, FAR const struct nxgl_rect_s *size,
+                           FAR const struct nxgl_point_s *pos,
+                           FAR const struct nxgl_rect_s *bounds,
+                           FAR void *arg);
+#ifdef CONFIG_NX_MOUSE
+static void nxeg_mousein1(NXWINDOW hwnd, FAR const struct nxgl_point_s *pos,
+                          ubyte buttons, FAR void *arg);
+static void nxeg_mousein2(NXWINDOW hwnd, FAR const struct nxgl_point_s *pos,
+                          ubyte buttons, FAR void *arg);
+#endif
+#ifdef CONFIG_NX_KBD
+static void nxeg_kbdin(NXWINDOW hwnd, ubyte nch, const ubyte *ch);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+const struct nx_callback_s g_nxcb1 =
+{
+  nxeg_redraw1,   /* redraw */
+  nxeg_position1  /* position */
+#ifdef CONFIG_NX_MOUSE
+  , nxeg_mousein1 /* mousein */
+#endif
+#ifdef CONFIG_NX_KBD
+  , nxeg_kbdin1   /* my kbdin */
+#endif
+};
+
+const struct nx_callback_s g_nxcb2 =
+{
+  nxeg_redraw2,   /* redraw */
+  nxeg_position2  /* position */
+#ifdef CONFIG_NX_MOUSE
+  , nxeg_mousein2 /* mousein */
+#endif
+#ifdef CONFIG_NX_KBD
+  , nxeg_kbdin2   /* my kbdin */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxeg_redraw1
+ ****************************************************************************/
+
+static void nxeg_redraw1(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect,
+                         boolean more, FAR void *arg)
+{
+  message("nxeg_redraw%d: hwnd=%p rect={(%d,%d),(%d,%d)} more=%s\n",
+           (int)arg, hwnd,
+           rect->pt1.x, rect->pt1.y, rect->pt2.x, rect->pt2.y,
+           more ? "TRUE" : "FALSE");
+  nx_fill(hwnd, rect, g_color1);
+}
+
+/****************************************************************************
+ * Name: nxeg_redraw2
+ ****************************************************************************/
+
+static void nxeg_redraw2(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect,
+                         boolean more, FAR void *arg)
+{
+  message("nxeg_redraw%d: hwnd=%p rect={(%d,%d),(%d,%d)} more=%s\n",
+           (int)arg, hwnd,
+           rect->pt1.x, rect->pt1.y, rect->pt2.x, rect->pt2.y,
+           more ? "TRUE" : "FALSE");
+  nx_fill(hwnd, rect, g_color2);
+}
+
+/****************************************************************************
+ * Name: nxeg_position1
+ ****************************************************************************/
+
+static void nxeg_position1(NXWINDOW hwnd, FAR const struct nxgl_rect_s *size,
+                           FAR const struct nxgl_point_s *pos,
+                           FAR const struct nxgl_rect_s *bounds,
+                           FAR void *arg)
+{
+  /* Report the position */
+
+  message("nxeg_position%d: hwnd=%p size={(%d,%d),(%d,%d)} pos=(%d,%d) bounds={(%d,%d),(%d,%d)}\n",
+           arg, hwnd,
+           size->pt1.x, size->pt1.y, size->pt2.x, size->pt2.y,
+           pos->x, pos->y,
+           bounds->pt1.x, bounds->pt1.y, bounds->pt2.x, bounds->pt2.y);
+
+  /* Have we picked off the window bounds yet? */
+
+  if (!b_haveresolution)
+    {
+      /* Save the window limits (these should be the same for all places and all windows */
+
+      g_xres = bounds->pt2.x;
+      g_yres = bounds->pt2.y;
+
+      b_haveresolution = TRUE;
+      sem_post(&g_semevent);
+      message("nxeg_position2: Have xres=%d yres=%d\n", g_xres, g_yres);
+    }
+}
+
+/****************************************************************************
+ * Name: nxeg_position2
+ ****************************************************************************/
+
+static void nxeg_position2(NXWINDOW hwnd, FAR const struct nxgl_rect_s *size,
+                           FAR const struct nxgl_point_s *pos,
+                           FAR const struct nxgl_rect_s *bounds,
+                           FAR void *arg)
+{
+  /* Report the position */
+
+  message("nxeg_position%d: hwnd=%p size={(%d,%d),(%d,%d)} pos=(%d,%d) bounds={(%d,%d),(%d,%d)}\n",
+           arg, hwnd,
+           size->pt1.x, size->pt1.y, size->pt2.x, size->pt2.y,
+           pos->x, pos->y,
+           bounds->pt1.x, bounds->pt1.y, bounds->pt2.x, bounds->pt2.y);
+}
+
+/****************************************************************************
+ * Name: nxeg_mousein1
+ ****************************************************************************/
+
+#ifdef CONFIG_NX_MOUSE
+static void nxeg_mousein1(NXWINDOW hwnd, FAR const struct nxgl_point_s *pos,
+                          ubyte buttons, FAR void *arg)
+{
+  message("nxeg_mousein%d: hwnd=%p pos=(%d,%d) button=%02x\n",
+           (int)arg, hwnd,  pos->x, pos->y, buttons);
+}
+#endif
+
+/****************************************************************************
+ * Name: nxeg_mousein2
+ ****************************************************************************/
+
+#ifdef CONFIG_NX_MOUSE
+static void nxeg_mousein2(NXWINDOW hwnd, FAR const struct nxgl_point_s *pos,
+                          ubyte buttons, FAR void *arg)
+{
+  message("nxeg_mousein%d: hwnd=%p pos=(%d,%d) button=%02x\n",
+          (int)arg, hwnd,  pos->x, pos->y, buttons);
+}
+#endif
+
+/****************************************************************************
+ * Name: nxeg_kbdinfo
+ ****************************************************************************/
+
+#ifdef CONFIG_NX_KBD
+static void nxeg_kbdinfo(ubyte nch, const ubyte *ch)
+{
+  int i;
+  for (i = 0; i < nch; i++)
+    {
+      if (isprint(ch[i]))
+        {
+          message("          ch[%d]=  (%02x)", i, ch[i]);
+        }
+      else
+        {
+          message("          ch[%d]=%c (%02x)", i, ch[i], ch[i]);
+        }
+    }
+}
+#endif
+
+/****************************************************************************
+ * Name: nxeg_kbdin1
+ ****************************************************************************/
+
+#ifdef CONFIG_NX_KBD
+static void nxeg_kbdin1(NXWINDOW hwnd, ubyte nch, const ubyte *ch)
+{
+  message("nxeg_kbdin1: hwnd=%p nch=%d\n", hwnd, nch);
+  nxeg_kbdinfo(nch, ch);
+}
+#endif
+
+/****************************************************************************
+ * Name: nxeg_kbdin2
+ ****************************************************************************/
+
+#ifdef CONFIG_NX_KBD
+static void nxeg_kbdin2(NXWINDOW hwnd, ubyte nch, const ubyte *ch)
+{
+  message("nxeg_kbdin2: hwnd=%p nch=%d\n", hwnd, nch);
+  nxeg_kbdinfo(nch, ch);
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nx_listenerthread
+ ****************************************************************************/
+
+#ifdef CONFIG_NX_MULTIUSER
+FAR void *nx_listenerthread(FAR void *arg)
+{
+  int ret;
+
+  /* Set up to catch a signal */
+
+  /* Process events forever */
+
+  for (;;)
+    {
+      /* Handle the next event.  If we were configured blocking, then
+       * we will stay right here until the next event is received.  Since
+       * we have dedicated a while thread to servicing events, it would
+       * be most natural to also select CONFIG_NX_BLOCKING -- if not, the
+       * following would be a tight infinite loop (unless we added addition
+       * logic with nx_eventnotify and sigwait to pace it).
+       */
+
+      ret = nx_eventhandler(g_hnx);
+      if (ret < 0)
+        {
+          /* An error occurred... assume that we have lost connection with
+           * the server.
+           */
+
+          message("nx_listenerthread: Lost server connection: %d\n", errno);
+          exit(NXEXIT_LOSTSERVERCONN);
+        }
+
+      /* If we received a message, we must be connected */
+
+      if (!g_connected)
+        {
+          g_connected = TRUE;
+          sem_post(&g_semevent);
+          message("nx_listenerthread: Connected\n");
+        }
+    }
+}
+#endif
diff --git a/examples/nx/nx_internal.h b/examples/nx/nx_internal.h
index 60ec466e2e1936f675db91ac007732c101c9726e..32164eac3e727be148af010d2377525ecb73e834 100644
--- a/examples/nx/nx_internal.h
+++ b/examples/nx/nx_internal.h
@@ -42,6 +42,7 @@
 
 #include <nuttx/config.h>
 #include <sys/types.h>
+#include <semaphore.h>
 
 /****************************************************************************
  * Definitions
@@ -94,11 +95,20 @@
 #  ifdef CONFIG_DISABLE_SIGNALS
 #    error "This example requires signal support (CONFIG_DISABLE_SIGNALS=n)"
 #  endif
+#  ifdef CONFIG_DISABLE_PTHREAD
+#    error "This example requires pthread support (CONFIG_DISABLE_PTHREAD=n)"
+#  endif
+#  ifndef CONFIG_NX_BLOCKING
+#    error "This example depends on CONFIG_NX_BLOCKING"
+#  endif
 #  ifndef CONFIG_EXAMPLES_NX_STACKSIZE
 #    define CONFIG_EXAMPLES_NX_STACKSIZE 2048
 #  endif
+#  ifndef CONFIG_EXAMPLES_NX_LISTENERPRIO
+#    define CONFIG_EXAMPLES_NX_LISTENERPRIO 100
+#  endif
 #  ifndef CONFIG_EXAMPLES_NX_CLIENTPRIO
-#    define CONFIG_EXAMPLES_NX_CLIENTPRIO 80
+#    define CONFIG_EXAMPLES_NX_CLIENTPRIO 100
 #  endif
 #  ifndef CONFIG_EXAMPLES_NX_SERVERPRIO
 #    define CONFIG_EXAMPLES_NX_SERVERPRIO 120
@@ -132,16 +142,62 @@
  * Public Types
  ****************************************************************************/
 
+enum exitcode_e
+{
+  NXEXIT_SUCCESS = 0,
+  NXEXIT_SIGPROCMASK,
+  NXEXIT_SCHEDSETPARAM,
+  NXEXIT_EVENTNOTIFY,
+  NXEXIT_TASKCREATE,
+  NXEXIT_PTHREADCREATE,
+  NXEXIT_FBINITIALIZE,
+  NXEXIT_FBGETVPLANE,
+  NXEXIT_NXOPEN,
+  NXEXIT_NXCONNECT,
+  NXEXIT_NXSETBGCOLOR,
+  NXEXIT_NXOPENWINDOW,
+  NXEXIT_NXSETSIZE,
+  NXEXIT_NXSETPOSITION,
+  NXEXIT_NXCLOSEWINDOW,
+  NXEXIT_LOSTSERVERCONN
+};
+
 /****************************************************************************
  * Public Variables
  ****************************************************************************/
 
+/* The connecton handler */
+
+extern NXHANDLE g_hnx;
+
+/* NX callback vtables */
+
+extern const struct nx_callback_s g_nxcb1;
+extern const struct nx_callback_s g_nxcb2;
+
+/* The screen resolution */
+
+nxgl_coord_t g_xres;
+nxgl_coord_t g_yres;
+
+extern boolean b_haveresolution;
+#ifdef CONFIG_NX_MULTIUSER
+extern boolean g_connected;
+#endif
+extern sem_t g_semevent;
+
+/* Colors used to fill window 1 & 2 */
+
+extern nxgl_mxpixel_t g_color1[CONFIG_NX_NPLANES];
+extern nxgl_mxpixel_t g_color2[CONFIG_NX_NPLANES];
+
 /****************************************************************************
  * Public Function Prototypes
  ****************************************************************************/
 
 #if defined(CONFIG_NXGRAPHICS) && defined(CONFIG_NX_MULTIUSER)
 extern int nx_servertask(int argc, char *argv[]);
+extern FAR void *nx_listenerthread(FAR void *arg);
 #endif
 
 #endif /* __EXAMPLES_NX_NX_INTERNAL_H */
diff --git a/examples/nx/nx_main.c b/examples/nx/nx_main.c
index f30fef1192425d2a4f1400ff624da2b5bba83cec..d8b7811b0d870f95390493c455c13a5b7106fb52 100644
--- a/examples/nx/nx_main.c
+++ b/examples/nx/nx_main.c
@@ -44,7 +44,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <sched.h>
-#include <signal.h>
+#include <pthread.h>
 #include <errno.h>
 #include <debug.h>
 
@@ -61,209 +61,44 @@
  * Private Types
  ****************************************************************************/
 
-enum exitcode_e
-{
-  NXEXIT_SUCCESS = 0,
-  NXEXIT_SIGPROCMASK,
-  NXEXIT_SIGACTION,
-  NXEXIT_EVENTNOTIFY,
-  NXEXIT_TASKCREATE,
-  NXEXIT_FBINITIALIZE,
-  NXEXIT_FBGETVPLANE,
-  NXEXIT_NXOPEN,
-  NXEXIT_NXCONNECT,
-  NXEXIT_NXSETBGCOLOR,
-  NXEXIT_NXOPENWINDOW,
-  NXEXIT_NXSETSIZE,
-  NXEXIT_NXSETPOSITION,
-  NXEXIT_NXCLOSEWINDOW
-};
-
 /****************************************************************************
  * Private Function Prototypes
  ****************************************************************************/
 
-static void nxeg_redraw1(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect,
-                         boolean morem, FAR void *arg);
-static void nxeg_redraw2(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect,
-                         boolean more, FAR void *arg);
-static void nxeg_position1(NXWINDOW hwnd, FAR const struct nxgl_rect_s *size,
-                           FAR const struct nxgl_point_s *pos,
-                           FAR const struct nxgl_rect_s *bounds,
-                           FAR void *arg);
-static void nxeg_position2(NXWINDOW hwnd, FAR const struct nxgl_rect_s *size,
-                           FAR const struct nxgl_point_s *pos,
-                           FAR const struct nxgl_rect_s *bounds,
-                           FAR void *arg);
-#ifdef CONFIG_NX_MOUSE
-static void nxeg_mousein1(NXWINDOW hwnd, FAR const struct nxgl_point_s *pos,
-                          ubyte buttons, FAR void *arg);
-static void nxeg_mousein2(NXWINDOW hwnd, FAR const struct nxgl_point_s *pos,
-                          ubyte buttons, FAR void *arg);
-#endif
-#ifdef CONFIG_NX_KBD
-static void nxeg_kbdin(NXWINDOW hwnd, ubyte nch, const ubyte *ch);
-#endif
-
 /****************************************************************************
  * Private Data
  ****************************************************************************/
 
-static const struct nx_callback_s g_nxcb1 =
-{
-  nxeg_redraw1,   /* redraw */
-  nxeg_position1  /* position */
-#ifdef CONFIG_NX_MOUSE
-  , nxeg_mousein1 /* mousein */
-#endif
-#ifdef CONFIG_NX_KBD
-  , nxeg_kbdin1   /* my kbdin */
-#endif
-};
+static int g_exitcode = NXEXIT_SUCCESS;
 
-static const struct nx_callback_s g_nxcb2 =
-{
-  nxeg_redraw2,   /* redraw */
-  nxeg_position2  /* position */
-#ifdef CONFIG_NX_MOUSE
-  , nxeg_mousein2 /* mousein */
-#endif
-#ifdef CONFIG_NX_KBD
-  , nxeg_kbdin2   /* my kbdin */
-#endif
-};
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
 
 /* The connecton handler */
 
-static NXHANDLE g_hnx = NULL;
-static int g_exitcode = NXEXIT_SUCCESS;
+NXHANDLE g_hnx = NULL;
+
+/* The screen resolution */
 
-/* Initialized to zero, incremented when connected */
+nxgl_coord_t g_xres;
+nxgl_coord_t g_yres;
 
+boolean b_haveresolution = FALSE;
 #ifdef CONFIG_NX_MULTIUSER
-static boolean g_connected = FALSE;
+boolean g_connected = FALSE;
 #endif
-static boolean b_haveresolution = FALSE;
-static sem_t g_semevent = {0};
-
-/* The screen resolution */
-
-static nxgl_coord_t g_xres;
-static nxgl_coord_t g_yres;
+sem_t g_semevent = {0};
 
 /* Colors used to fill window 1 & 2 */
 
-static nxgl_mxpixel_t g_color1[CONFIG_NX_NPLANES];
-static nxgl_mxpixel_t g_color2[CONFIG_NX_NPLANES];
+nxgl_mxpixel_t g_color1[CONFIG_NX_NPLANES];
+nxgl_mxpixel_t g_color2[CONFIG_NX_NPLANES];
 
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
 
-/****************************************************************************
- * Name: nxeg_redraw1
- ****************************************************************************/
-
-static void nxeg_redraw1(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect,
-                         boolean more, FAR void *arg)
-{
-  message("nxeg_redraw%d: hwnd=%p rect={(%d,%d),(%d,%d)} more=%s\n",
-           (int)arg, hwnd,
-           rect->pt1.x, rect->pt1.y, rect->pt2.x, rect->pt2.y,
-           more ? "TRUE" : "FALSE");
-  nx_fill(hwnd, rect, g_color1);
-}
-
-/****************************************************************************
- * Name: nxeg_redraw2
- ****************************************************************************/
-
-static void nxeg_redraw2(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect,
-                         boolean more, FAR void *arg)
-{
-  message("nxeg_redraw%d: hwnd=%p rect={(%d,%d),(%d,%d)} more=%s\n",
-           (int)arg, hwnd,
-           rect->pt1.x, rect->pt1.y, rect->pt2.x, rect->pt2.y,
-           more ? "TRUE" : "FALSE");
-  nx_fill(hwnd, rect, g_color2);
-}
-
-/****************************************************************************
- * Name: nxeg_position1
- ****************************************************************************/
-
-static void nxeg_position1(NXWINDOW hwnd, FAR const struct nxgl_rect_s *size,
-                           FAR const struct nxgl_point_s *pos,
-                           FAR const struct nxgl_rect_s *bounds,
-                           FAR void *arg)
-{
-  /* Report the position */
-
-  message("nxeg_position%d: hwnd=%p size={(%d,%d),(%d,%d)} pos=(%d,%d) bounds={(%d,%d),(%d,%d)}\n",
-           arg, hwnd,
-           size->pt1.x, size->pt1.y, size->pt2.x, size->pt2.y,
-           pos->x, pos->y,
-           bounds->pt1.x, bounds->pt1.y, bounds->pt2.x, bounds->pt2.y);
-
-  /* Have we picked off the window bounds yet? */
-
-  if (!b_haveresolution)
-    {
-      /* Save the window limits (these should be the same for all places and all windows */
-
-      g_xres = bounds->pt2.x;
-      g_yres = bounds->pt2.y;
-
-      b_haveresolution = TRUE;
-      sem_post(&g_semevent);
-      message("nxeg_position2: Have xres=%d yres=%d\n", g_xres, g_yres);
-    }
-}
-
-/****************************************************************************
- * Name: nxeg_position2
- ****************************************************************************/
-
-static void nxeg_position2(NXWINDOW hwnd, FAR const struct nxgl_rect_s *size,
-                           FAR const struct nxgl_point_s *pos,
-                           FAR const struct nxgl_rect_s *bounds,
-                           FAR void *arg)
-{
-  /* Report the position */
-
-  message("nxeg_position%d: hwnd=%p size={(%d,%d),(%d,%d)} pos=(%d,%d) bounds={(%d,%d),(%d,%d)}\n",
-           arg, hwnd,
-           size->pt1.x, size->pt1.y, size->pt2.x, size->pt2.y,
-           pos->x, pos->y,
-           bounds->pt1.x, bounds->pt1.y, bounds->pt2.x, bounds->pt2.y);
-}
-
-/****************************************************************************
- * Name: nxeg_mousein1
- ****************************************************************************/
-
-#ifdef CONFIG_NX_MOUSE
-static void nxeg_mousein1(NXWINDOW hwnd, FAR const struct nxgl_point_s *pos,
-                          ubyte buttons, FAR void *arg)
-{
-  message("nxeg_mousein%d: hwnd=%p pos=(%d,%d) button=%02x\n",
-           (int)arg, hwnd,  pos->x, pos->y, buttons);
-}
-#endif
-
-/****************************************************************************
- * Name: nxeg_mousein2
- ****************************************************************************/
-
-#ifdef CONFIG_NX_MOUSE
-static void nxeg_mousein2(NXWINDOW hwnd, FAR const struct nxgl_point_s *pos,
-                          ubyte buttons, FAR void *arg)
-{
-  message("nxeg_mousein%d: hwnd=%p pos=(%d,%d) button=%02x\n",
-          (int)arg, hwnd,  pos->x, pos->y, buttons);
-}
-#endif
-
 /****************************************************************************
  * Name: nxeg_drivemouse
  ****************************************************************************/
@@ -287,85 +122,6 @@ static void nxeg_drivemouse(void)
 }
 #endif
 
-/****************************************************************************
- * Name: nxeg_kbdinfo
- ****************************************************************************/
-
-#ifdef CONFIG_NX_KBD
-static void nxeg_kbdinfo(ubyte nch, const ubyte *ch)
-{
-  int i;
-  for (i = 0; i < nch; i++)
-    {
-      if (isprint(ch[i]))
-        {
-          message("          ch[%d]=  (%02x)", i, ch[i]);
-        }
-      else
-        {
-          message("          ch[%d]=%c (%02x)", i, ch[i], ch[i]);
-        }
-    }
-}
-#endif
-
-/****************************************************************************
- * Name: nxeg_kbdin1
- ****************************************************************************/
-
-#ifdef CONFIG_NX_KBD
-static void nxeg_kbdin1(NXWINDOW hwnd, ubyte nch, const ubyte *ch)
-{
-  message("nxeg_kbdin1: hwnd=%p nch=%d\n", hwnd, nch);
-  nxeg_kbdinfo(nch, ch);
-}
-#endif
-
-/****************************************************************************
- * Name: nxeg_kbdin2
- ****************************************************************************/
-
-#ifdef CONFIG_NX_KBD
-static void nxeg_kbdin2(NXWINDOW hwnd, ubyte nch, const ubyte *ch)
-{
-  message("nxeg_kbdin2: hwnd=%p nch=%d\n", hwnd, nch);
-  nxeg_kbdinfo(nch, ch);
-}
-#endif
-
-/****************************************************************************
- * Name: nxeg_suinitialize
- ****************************************************************************/
-
-#ifdef CONFIG_NX_MULTIUSER
-static void nxeg_sigaction(int signo, FAR siginfo_t *info, FAR void *context)
-{
-  int ret;
-
-  /* I know... you are not supposed to call printf from signal handlers */
-
-  message("nxeg_sigaction: received signo=%d\n", signo);
-  ret = nx_eventhandler(g_hnx);
-
-  /* If we received a message, we must be connected */
-
-  if (!g_connected)
-    {
-      g_connected = TRUE;
-      sem_post(&g_semevent);
-      message("nxeg_sigaction: Connected\n");
-    }
-
-  /* Request notification of further incoming events */
-
-  ret = nx_eventnotify(g_hnx, CONFIG_EXAMPLES_NX_NOTIFYSIGNO);
-  if (ret < 0)
-     {
-       message("nxeg_sigaction: nx_eventnotify failed: %d\n", errno);
-     }
-}
-#endif
-
 /****************************************************************************
  * Name: nxeg_suinitialize
  ****************************************************************************/
@@ -416,35 +172,19 @@ static inline int nxeg_suinitialize(void)
 #ifdef CONFIG_NX_MULTIUSER
 static inline int nxeg_muinitialize(void)
 {
-  struct sigaction act;
-  sigset_t sigset;
+  struct sched_param param;
+  pthread_t thread;
   pid_t servrid;
   int ret;
 
-  /* Set up to catch a signal */
-
-  message("nxeg_initialize: Unmasking signal %d\n" , CONFIG_EXAMPLES_NX_NOTIFYSIGNO);
-  (void)sigemptyset(&sigset);
-  (void)sigaddset(&sigset, CONFIG_EXAMPLES_NX_NOTIFYSIGNO);
-  ret = sigprocmask(SIG_UNBLOCK, &sigset, NULL);
-  if (ret < 0)
-    {
-      message("nxeg_initialize: sigprocmask failed: \n", ret);
-      g_exitcode = NXEXIT_SIGPROCMASK;
-      return ERROR;
-    }
-
-  message("nxeg_initialize: Registering signal handler\n" );
-  act.sa_sigaction = nxeg_sigaction;
-  act.sa_flags     = SA_SIGINFO;
-  (void)sigfillset(&act.sa_mask);
-  (void)sigdelset(&act.sa_mask, CONFIG_EXAMPLES_NX_NOTIFYSIGNO);
+  /* Set the client task priority */
 
-  ret = sigaction(CONFIG_EXAMPLES_NX_NOTIFYSIGNO, &act, NULL);
+  param.sched_priority = CONFIG_EXAMPLES_NX_CLIENTPRIO;
+  ret = sched_setparam(0, &param);
   if (ret < 0)
     {
-      message("nxeg_initialize: sigaction failed: %d\n" , ret);
-      g_exitcode = NXEXIT_SIGACTION;
+      message("nxeg_initialize: sched_setparam failed: %d\n" , ret);
+      g_exitcode = NXEXIT_SCHEDSETPARAM;
       return ERROR;
     }
 
@@ -462,22 +202,30 @@ static inline int nxeg_muinitialize(void)
 
   /* Wait a bit to let the server get started */
 
-  sleep(2);
+  sleep(1);
 
   /* Connect to the server */
 
   g_hnx = nx_connect();
   if (g_hnx)
     {
-       /* Request notification of incoming events */
+       pthread_attr_t attr;
+
+       /* Start a separate thread to listen for server events.  This is probably
+        * the least efficient way to do this, but it makes this example flow more
+        * smoothly.
+        */
 
-       ret = nx_eventnotify(g_hnx, CONFIG_EXAMPLES_NX_NOTIFYSIGNO);
-       if (ret < 0)
+       (void)pthread_attr_init(&attr);
+       param.sched_priority = CONFIG_EXAMPLES_NX_LISTENERPRIO;
+       (void)pthread_attr_setschedparam(&attr, &param);
+       (void)pthread_attr_setstacksize(&attr, CONFIG_EXAMPLES_NX_STACKSIZE);
+
+       ret = pthread_create(&thread, &attr, nx_listenerthread, NULL);
+       if (ret != 0)
          {
-            message("nxeg_initialize: nx_eventnotify failed: %d\n", errno);
-            (void)nx_disconnect(g_hnx);
-            g_hnx      = NULL;
-            g_exitcode = NXEXIT_EVENTNOTIFY;
+            printf("nxeg_initialize: pthread_create failed: %d\n", ret);
+            g_exitcode = NXEXIT_PTHREADCREATE;
             return ERROR;
          }
 
@@ -485,33 +233,16 @@ static inline int nxeg_muinitialize(void)
 
        while (!g_connected)
          {
-            /* Assuming that the incoming message queue is configured non-blocking,
-             * we can poll the event handler here.  This accounts for the case where
-             * the server is higher prioirty than the client.  In that case, the
-             * server will have already responded to the connection request BEFORE
-             * the nx_eventnotify was called.
-             */
-
-             ret = nx_eventhandler(g_hnx);
-             if (ret == 0)
-               {
-                 /* If a message was received, then we are connected */
-
-                 g_connected = TRUE;
-               }
-
-             /* Otherwise, we will have to wait for the event handler to wake up up
-              * when we really are connected.
-              */
-             else
-               {
-                 (void)sem_wait(&g_semevent);
-               }
+           /* Wait for the listener thread to wake us up when we really
+            * are connected.
+            */
+
+           (void)sem_wait(&g_semevent);
          }
     }
   else
     {
-      message("user_start: nx_connect failed: %d\n", errno);
+      message("nxeg_initialize: nx_connect failed: %d\n", errno);
       g_exitcode = NXEXIT_NXCONNECT;
       return ERROR;
     }
@@ -589,7 +320,6 @@ int user_start(int argc, char *argv[])
       g_exitcode = NXEXIT_NXSETBGCOLOR;
       goto errout_with_nx;
     }
-  (void)nx_eventhandler(g_hnx); /* Check for server events -- normally done in a loop */
 
   /* Create window #1 */