diff --git a/configs/sim/nx/defconfig b/configs/sim/nx/defconfig index 8218088bb1..27c5baf60f 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 5c95f8eabc..397159148a 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 2fbb54e8f7..f3b7aba5cb 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 d15d17ae3d..2447ae5754 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 0000000000..9d6b2f055f --- /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 + * + * 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 + +#include +#include +#include +#include +#include + +#include +#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 60ec466e2e..32164eac3e 100644 --- a/examples/nx/nx_internal.h +++ b/examples/nx/nx_internal.h @@ -42,6 +42,7 @@ #include #include +#include /**************************************************************************** * 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 f30fef1192..d8b7811b0d 100644 --- a/examples/nx/nx_main.c +++ b/examples/nx/nx_main.c @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include #include @@ -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; - -/* Initialized to zero, incremented when connected */ - -#ifdef CONFIG_NX_MULTIUSER -static boolean g_connected = FALSE; -#endif -static boolean b_haveresolution = FALSE; -static sem_t g_semevent = {0}; +NXHANDLE g_hnx = NULL; /* The screen resolution */ -static nxgl_coord_t g_xres; -static nxgl_coord_t g_yres; +nxgl_coord_t g_xres; +nxgl_coord_t g_yres; + +boolean b_haveresolution = FALSE; +#ifdef CONFIG_NX_MULTIUSER +boolean g_connected = FALSE; +#endif +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 */ + /* Set the client task priority */ - 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); + param.sched_priority = CONFIG_EXAMPLES_NX_CLIENTPRIO; + ret = sched_setparam(0, ¶m); 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); - - ret = sigaction(CONFIG_EXAMPLES_NX_NOTIFYSIGNO, &act, NULL); - 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; - ret = nx_eventnotify(g_hnx, CONFIG_EXAMPLES_NX_NOTIFYSIGNO); - if (ret < 0) + /* 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. + */ + + (void)pthread_attr_init(&attr); + param.sched_priority = CONFIG_EXAMPLES_NX_LISTENERPRIO; + (void)pthread_attr_setschedparam(&attr, ¶m); + (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. - */ + /* Wait for the listener thread to wake us up when we really + * are connected. + */ - 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); - } + (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 */