From 10388e91232621fe7aac8aee8f97528aa3b046eb Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 25 Mar 2019 13:48:27 -0600 Subject: [PATCH] exmamples/, graphics/NxWidgets: Implement new interfaces nx_synch() and nxtk_synch(). This are used to syncrhonize the NX server with the window client. Currently most of the logic is equivalent to nx_block() and nxtk_block(), but with slightly different semantics. The are separate now because they are likely to diverge in the future. --- graphics/nxmu/nxmu_server.c | 11 +++++- include/nuttx/nx/nx.h | 77 ++++++++++++++++++++++++++++++------- include/nuttx/nx/nxmu.h | 13 +++++++ include/nuttx/nx/nxtk.h | 77 ++++++++++++++++++++++++++++++------- libs/libnx/nxmu/Make.defs | 5 ++- libs/libnx/nxmu/nx_block.c | 2 +- libs/libnx/nxtk/Make.defs | 4 +- 7 files changed, 155 insertions(+), 34 deletions(-) diff --git a/graphics/nxmu/nxmu_server.c b/graphics/nxmu/nxmu_server.c index a3d427c728..79d3cdc12f 100644 --- a/graphics/nxmu/nxmu_server.c +++ b/graphics/nxmu/nxmu_server.c @@ -141,8 +141,8 @@ static inline void nxmu_shutdown(FAR struct nxmu_state_s *fe) * Name: nxmu_event ****************************************************************************/ -static inline void nxmu_event(FAR struct nxbe_window_s *wnd, - enum nx_event_e event, FAR void *arg) +static void nxmu_event(FAR struct nxbe_window_s *wnd, enum nx_event_e event, + FAR void *arg) { struct nxclimsg_event_s outmsg; int ret; @@ -369,6 +369,13 @@ int nx_runinstance(FAR const char *mqname, FAR NX_DRIVERTYPE *dev) } break; + case NX_SVRMSG_SYNCH: /* Synchronization request */ + { + FAR struct nxsvrmsg_synch_s *synch = (FAR struct nxsvrmsg_synch_s *)buffer; + nxmu_event(synch->wnd, NXEVENT_SYNCHED, synch->arg); + } + break; + case NX_SVRMSG_REQUESTBKGD: /* Give access to the background window */ { FAR struct nxsvrmsg_requestbkgd_s *rqbgmsg = (FAR struct nxsvrmsg_requestbkgd_s *)buffer; diff --git a/include/nuttx/nx/nx.h b/include/nuttx/nx/nx.h index b3ba1b45cc..3876766331 100644 --- a/include/nuttx/nx/nx.h +++ b/include/nuttx/nx/nx.h @@ -101,7 +101,7 @@ typedef FAR void *NXWINDOW; enum nx_event_e { NXEVENT_BLOCKED = 0, /* Window messages are blocked */ - NXEVENT_SYCNCHED, /* Synchronization handshake */ + NXEVENT_SYNCHED, /* Synchronization handshake */ }; /* These define callbacks that must be provided to nx_openwindow. These @@ -227,7 +227,7 @@ struct nx_callback_s * safely closed. Closing the window prior with pending callbacks can * lead to bad behavior when the callback is executed. * - * NXEVENT_SYCNCHED - Synchronization handshake + * NXEVENT_SYNCHED - Synchronization handshake * * This completes the handshake started by nx_synch(). nx_synch() * sends a syncrhonization messages to the NX server which responds @@ -444,22 +444,23 @@ int nx_closewindow(NXWINDOW hwnd); * This is callback will do to things: (1) any queue a 'blocked' callback * to the window and then (2) block any further window messaging. * - * The 'blocked' callback is the response from nx_block (or nxtk_block). - * Those blocking interfaces are used to assure that no further messages are - * are directed to the window. Receipt of the blocked callback signifies - * that (1) there are no further pending callbacks and (2) that the - * window is now 'defunct' and will receive no further callbacks. + * The 'event' callback with the NXEVENT_BLOCKED event is the response + * from nx_block (or nxtk_block). Those blocking interfaces are used to + * assure that no further messages are are directed to the window. Receipt + * of the NXEVENT_BLOCKED event signifies that (1) there are no further + * pending callbacks and (2) that the window is now 'defunct' and will + * receive no further callbacks. * - * This callback supports coordinated destruction of a window. In multi- - * user mode, the client window logic must stay intact until all of the - * queued callbacks are processed. Then the window may be safely closed. - * Closing the window prior with pending callbacks can lead to bad behavior - * when the callback is executed. + * This callback supports coordinated destruction of a window. The client + * window logic must stay intact until all of the queued callbacks are + * processed. Then the window may be safely closed. Closing the window + * prior with pending callbacks can lead to bad behavior when the callback + * is executed. * * Input Parameters: * wnd - The window to be blocked * arg - An argument that will accompany the block messages (This is arg2 - * in the blocked callback). + * in the event callback). * * Returned Value: * OK on success; ERROR on failure with errno set appropriately @@ -468,6 +469,56 @@ int nx_closewindow(NXWINDOW hwnd); int nx_block(NXWINDOW hwnd, FAR void *arg); +/**************************************************************************** + * Name: nx_synch + * + * Description: + * This interface can be used to syncrhonize the window client with the + * NX server. It really just implements an 'echo': A synch message is + * sent from the window client to the server which then responds + * immediately by sending the NXEVENT_SYNCHED back to the windows client. + * + * Due to the highly asynchronous nature of client-server communications, + * nx_synch() is sometimes necessary to assure that the client and server + * are fully synchronized in time. + * + * Usage by the window client might be something like this: + * + * extern bool g_synched; + * extern sem_t g_synch_sem; + * + * g_synched = false; + * ret = nx_synch(hwnd, handle); + * if (ret < 0) + * { + * -- Handle the error -- + * } + * + * while (!g_synched) + * { + * ret = sem_wait(&g_sync_sem); + * if (ret < 0) + * { + * -- Handle the error -- + * } + * } + * + * When the windwo listener thread receives the NXEVENT_SYNCHED event, it + * would set g_synched to true and post g_synch_sem, waking up the above + * loop. + * + * Input Parameters: + * wnd - The window to be synched + * arg - An argument that will accompany the block messages (This is arg2 + * in the event callback). + * + * Returned Value: + * OK on success; ERROR on failure with errno set appropriately + * + ****************************************************************************/ + +int nx_synch(NXWINDOW hwnd, FAR void *arg); + /**************************************************************************** * Name: nx_requestbkgd * diff --git a/include/nuttx/nx/nxmu.h b/include/nuttx/nx/nxmu.h index 7e32f098a0..18f5c8a0db 100644 --- a/include/nuttx/nx/nxmu.h +++ b/include/nuttx/nx/nxmu.h @@ -139,6 +139,7 @@ enum nxmsg_e NX_SVRMSG_OPENWINDOW, /* Create a new window */ NX_SVRMSG_CLOSEWINDOW, /* Close an existing window */ NX_SVRMSG_BLOCKED, /* The window is blocked */ + NX_SVRMSG_SYNCH, /* Window syncrhonization request */ NX_SVRMSG_REQUESTBKGD, /* Open the background window */ NX_SVRMSG_RELEASEBKGD, /* Release the background window */ NX_SVRMSG_SETPOSITION, /* Window position has changed */ @@ -281,6 +282,18 @@ struct nxsvrmsg_blocked_s FAR void *arg; /* User argument */ }; +/* Synchronization request. This is essentially an 'echo': The NX server + * will receive the synchronization request and simply respond with a + * synchronized event. + */ + +struct nxsvrmsg_synch_s +{ + uint32_t msgid; /* NX_SVRMSG_SYNCH */ + FAR struct nxbe_window_s *wnd; /* The window that requires synch'ing */ + FAR void *arg; /* User argument */ +}; + /* This message requests the server to create a new window */ struct nxsvrmsg_requestbkgd_s diff --git a/include/nuttx/nx/nxtk.h b/include/nuttx/nx/nxtk.h index 14625b7dd8..7c978665fb 100644 --- a/include/nuttx/nx/nxtk.h +++ b/include/nuttx/nx/nxtk.h @@ -161,24 +161,23 @@ int nxtk_closewindow(NXTKWINDOW hfwnd); * This is callback will do to things: (1) any queue a 'blocked' callback * to the window and then (2) block any further window messaging. * - * The 'blocked' callback is the response from nx_block (or nxtk_block). - * Those blocking interfaces are used to assure that no further messages - * are are directed to the window. Receipt of the blocked callback - * signifies that (1) there are no further pending callbacks and (2) that - * the window is now 'defunct' and will receive no further callbacks. + * The 'event' callback with the NXEVENT_BLOCKED event is the response + * from nx_block (or nxtk_block). Those blocking interfaces are used to + * assure that no further messages are are directed to the window. Receipt + * of the NXEVENT_BLOCKED event signifies that (1) there are no further + * pending callbacks and (2) that the window is now 'defunct' and will + * receive no further callbacks. * - * This callback supports coordinated destruction of a window in multi- - * user mode. In multi-use mode, the client window logic must stay - * intact until all of the queued callbacks are processed. Then the - * window may be safely closed. Closing the window prior with pending - * callbacks can lead to bad behavior when the callback is executed. - * - * Multiple user mode only! + * This callback supports coordinated destruction of a window. The client + * window logic must stay intact until all of the queued callbacks are + * processed. Then the window may be safely closed. Closing the window + * prior with pending callbacks can lead to bad behavior when the callback + * is executed. * * Input Parameters: * hfwnd - The window to be blocked - * arg - An argument that will accompany the block messages (This is arg2 - * in the blocked callback). + * arg - An argument that will accompany the block messages (This is arg2 + * in the blocked callback). * * Returned Value: * OK on success; ERROR on failure with errno set appropriately @@ -187,6 +186,56 @@ int nxtk_closewindow(NXTKWINDOW hfwnd); int nxtk_block(NXTKWINDOW hfwnd, FAR void *arg); +/**************************************************************************** + * Name: nxtk_synch + * + * Description: + * This interface can be used to syncrhonize the window client with the + * NX server. It really just implements an 'echo': A synch message is + * sent from the window client to the server which then responds + * immediately by sending the NXEVENT_SYNCHED back to the windows client. + * + * Due to the highly asynchronous nature of client-server communications, + * nxtk_synch() is sometimes necessary to assure that the client and server + * are fully synchronized in time. + * + * Usage by the window client might be something like this: + * + * extern bool g_synched; + * extern sem_t g_synch_sem; + * + * g_synched = false; + * ret = nxtk_synch(hwnd, handle); + * if (ret < 0) + * { + * -- Handle the error -- + * } + * + * while (!g_synched) + * { + * ret = sem_wait(&g_sync_sem); + * if (ret < 0) + * { + * -- Handle the error -- + * } + * } + * + * When the windwo listener thread receives the NXEVENT_SYNCHED event, it + * would set g_synched to true and post g_synch_sem, waking up the above + * loop. + * + * Input Parameters: + * hfwnd - The window to be synched + * arg - An argument that will accompany the block messages (This is arg2 + * in the event callback). + * + * Returned Value: + * OK on success; ERROR on failure with errno set appropriately + * + ****************************************************************************/ + +int nxtk_synch(NXTKWINDOW hfwnd, FAR void *arg); + /**************************************************************************** * Name: nxtk_getposition * diff --git a/libs/libnx/nxmu/Make.defs b/libs/libnx/nxmu/Make.defs index 121d10ce81..224bbfc9aa 100644 --- a/libs/libnx/nxmu/Make.defs +++ b/libs/libnx/nxmu/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # libs/libnx/nxmu/Make.defs # -# Copyright (C) 2013, 2017 Gregory Nutt. All rights reserved. +# Copyright (C) 2013, 2017, 2019 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -40,7 +40,8 @@ ifeq ($(CONFIG_NX),y) CSRCS += nxmu_sendserver.c nx_connect.c nx_disconnect.c -CSRCS += nx_eventhandler.c nx_eventnotify.c nxmu_semtake.c nx_block.c +CSRCS += nx_eventhandler.c nx_eventnotify.c nxmu_semtake.c +CSRCS += nx_block.c nx_synch.c CSRCS += nx_kbdchin.c nx_kbdin.c nx_mousein.c CSRCS += nx_releasebkgd.c nx_requestbkgd.c nx_setbgcolor.c diff --git a/libs/libnx/nxmu/nx_block.c b/libs/libnx/nxmu/nx_block.c index 2e9434377d..c20a4c0282 100644 --- a/libs/libnx/nxmu/nx_block.c +++ b/libs/libnx/nxmu/nx_block.c @@ -105,7 +105,7 @@ int nx_block(NXWINDOW hwnd, FAR void *arg) NXBE_SETBLOCKED(wnd); - /* Send the message inicating that the window is blocked (and because of + /* Send the message indicating that the window is blocked (and because of * queue also that there are no additional queue messages for the window) */ diff --git a/libs/libnx/nxtk/Make.defs b/libs/libnx/nxtk/Make.defs index cd1a5d081d..b118c758e2 100644 --- a/libs/libnx/nxtk/Make.defs +++ b/libs/libnx/nxtk/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # libs/libnx/nxtk/Make.defs # -# Copyright (C) 2008, 2011, 2013 Gregory Nutt. All rights reserved. +# Copyright (C) 2008, 2011, 2013, 2019 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -42,7 +42,7 @@ CSRCS += nxtk_setposition.c nxtk_setsize.c nxtk_raise.c nxtk_lower.c CSRCS += nxtk_fillwindow.c nxtk_getwindow.c nxtk_filltrapwindow.c CSRCS += nxtk_movewindow.c nxtk_bitmapwindow.c nxtk_events.c CSRCS += nxtk_setsubwindows.c nxtk_drawcirclewindow.c nxtk_drawlinewindow.c -CSRCS += nxtk_fillcirclewindow.c nxtk_block.c +CSRCS += nxtk_fillcirclewindow.c nxtk_block.c nxtk_synch.c CSRCS += nxtk_opentoolbar.c nxtk_closetoolbar.c nxtk_filltoolbar.c CSRCS += nxtk_gettoolbar.c nxtk_filltraptoolbar.c nxtk_movetoolbar.c