diff --git a/graphics/NxWidgets/nxwidgets/src/ccallback.cxx b/graphics/NxWidgets/nxwidgets/src/ccallback.cxx index e7b69c344..b304efb1a 100644 --- a/graphics/NxWidgets/nxwidgets/src/ccallback.cxx +++ b/graphics/NxWidgets/nxwidgets/src/ccallback.cxx @@ -46,8 +46,16 @@ #include #include +#include #include +#include +#include + +#include +#include +#include + #include "graphics/nxwidgets/cwidgetcontrol.hxx" #include "graphics/nxwidgets/ccallback.hxx" @@ -85,13 +93,69 @@ CCallback::CCallback(CWidgetControl *widgetControl) #endif m_callbacks.event = windowEvent; - // Keyboard input is initially direct to the widgets within the window + // Synchronization support + + m_synchronized = false; + + sem_init(&m_semevent, 0, 0); + sem_setprotocol(&m_semevent, SEM_PRIO_NONE); #ifdef CONFIG_NXTERM_NXKBDIN + // Keyboard input is initially directed to the widgets within the window + m_nxterm = (NXTERM)0; #endif } +/** + * Synchronize the window with the NX server. This function will delay + * until the the NX server has caught up with all of the queued requests. + * When this function returns, the state of the NX server will be the + * same as the state of the application. + * + * REVISIT: An instance of this function is not re-entrant. + * + * @param hwnd Handle to a specific NX window. + */ + +void CCallback::synchronize(NXWINDOW hwnd, enum WindowType windowType) +{ + m_synchronized = false; + + // Request synchronization. Window type matters here because the void* + // window handle will be interpreted differently. + + if (windowType == NX_RAWWINDOW) + { + int ret = nx_synch(hwnd, (FAR void *)this); + if (ret < 0) + { + gerr("ERROR: nx_synch() failed: %d\n", errno); + return; + } + } + else + { + DEBUGASSERT(windowType == NXTK_FRAMEDWINDOW); + + int ret = nxtk_synch(hwnd, (FAR void *)this); + if (ret < 0) + { + gerr("ERROR: nxtk_synch() failed: %d\n", errno); + return; + } + } + + while (!m_synchronized) + { + int ret = sem_wait(&m_semevent); + DEBUGASSERT(ret >= 0 || errno == EINTR); + UNUSED(ret); + } + + m_synchronized = false; +} + /** * ReDraw Callback. The redraw action is handled by CWidgetControl:redrawEvent. * @@ -154,6 +218,7 @@ void CCallback::position(NXHANDLE hwnd, This->m_widgetControl->geometryEvent(hwnd, size, pos, bounds); } +#ifdef CONFIG_NX_XYINPUT /** * New mouse data is available for the window. The new mouse data is * handled by CWidgetControl::newMouseEvent. @@ -165,7 +230,6 @@ void CCallback::position(NXHANDLE hwnd, * nxtk_openwindow, or nxtk_opentoolbar). */ -#ifdef CONFIG_NX_XYINPUT void CCallback::newMouseEvent(NXHANDLE hwnd, FAR const struct nxgl_point_s *pos, uint8_t buttons, FAR void *arg) @@ -183,6 +247,7 @@ void CCallback::newMouseEvent(NXHANDLE hwnd, } #endif /* CONFIG_NX_XYINPUT */ +#ifdef CONFIG_NX_KBD /** * New keyboard/keypad data is available for the window. The new keyboard * data is handled by CWidgetControl::newKeyboardEvent. @@ -194,7 +259,6 @@ void CCallback::newMouseEvent(NXHANDLE hwnd, * nxtk_openwindow, or nxtk_opentoolbar). */ -#ifdef CONFIG_NX_KBD void CCallback::newKeyboardEvent(NXHANDLE hwnd, uint8_t nCh, FAR const uint8_t *str, FAR void *arg) @@ -205,11 +269,11 @@ void CCallback::newKeyboardEvent(NXHANDLE hwnd, uint8_t nCh, CCallback *This = (CCallback *)arg; +#ifdef CONFIG_NXTERM_NXKBDIN // Is NX keyboard input being directed to the widgets within the window // (default) OR is NX keyboard input being re-directed to an NxTerm // driver? -#ifdef CONFIG_NXTERM_NXKBDIN if (This->m_nxterm) { struct boardioc_nxterm_kbdin_s kbdin; @@ -266,7 +330,7 @@ void CCallback::newKeyboardEvent(NXHANDLE hwnd, uint8_t nCh, * @param event. The server event * @param arg1. User provided argument (see nx_openwindow, nx_requestbkgd, * nxtk_openwindow, or nxtk_opentoolbar) - * @param arg2 - User provided argument (see nx_block or nxtk_block) + * @param arg2 - User provided argument (see nx[tk]_block or nx[tk]_synch) */ void CCallback::windowEvent(NXWINDOW hwnd, enum nx_event_e event, @@ -274,17 +338,36 @@ void CCallback::windowEvent(NXWINDOW hwnd, enum nx_event_e event, { ginfo("hwnd=%p devent=%d arg1=%p arg2=%p\n", hwnd, event, arg1, arg2); - // The first argument must be the CCallback instance - - CCallback *This = (CCallback *)arg1; - - // Check for the window blocked event - - if (event == NXEVENT_BLOCKED) + switch (event) { - // Let the CWidgetControl::windowBlocked method handle the event. + case NXEVENT_SYNCHED: // Server is syncrhonized + { + // The second argument must be the CCallback instance - This->m_widgetControl->windowBlocked(arg2); + CCallback *This = (CCallback *)arg2; + DEBUGASSERT(This != NULL); + + // We are now syncrhonized + + This->m_synchronized = true; + sem_post(&This->m_semevent); + } + break; + + case NXEVENT_BLOCKED: // Window block, ready to be closed. + { + // The first argument must be the CCallback instance + + CCallback *This = (CCallback *)arg1; + DEBUGASSERT(This != NULL); + + // Let the CWidgetControl::windowBlocked method handle the event. + + This->m_widgetControl->windowBlocked(arg2); + } + break; + + default: + break; } } - diff --git a/include/graphics/nxwidgets/cbgwindow.hxx b/include/graphics/nxwidgets/cbgwindow.hxx index c2d799b6f..0ca0be32b 100644 --- a/include/graphics/nxwidgets/cbgwindow.hxx +++ b/include/graphics/nxwidgets/cbgwindow.hxx @@ -1,7 +1,7 @@ /**************************************************************************** * apps/include/graphics/nxwidgets/cbgwindow.hxx * - * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2012, 2015, 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -139,6 +139,18 @@ namespace NXWidgets CWidgetControl *getWidgetControl(void) const; + /** + * Synchronize the window with the NX server. This function will delay + * until the the NX server has caught up with all of the queued requests. + * When this function returns, the state of the NX server will be the + * same as the state of the application. + */ + + inline void synchronize(void) + { + CCallback::synchronize(m_hWindow, CCallback::NX_RAWWINDOW); + } + /** * Request the position and size information of the window. The values * will be returned asynchronously through the client callback method. @@ -206,6 +218,7 @@ namespace NXWidgets bool lower(void); +#ifdef CONFIG_NXTERM_NXKBDIN /** * Each window implementation also inherits from CCallback. CCallback, * by default, forwards NX keyboard input to the various widgets residing @@ -220,7 +233,6 @@ namespace NXWidgets * directed to the widgets within the window. */ -#ifdef CONFIG_NXTERM_NXKBDIN inline void redirectNxTerm(NXTERM handle) { setNxTerm(handle); diff --git a/include/graphics/nxwidgets/ccallback.hxx b/include/graphics/nxwidgets/ccallback.hxx index fa44f5ce2..e762960a5 100644 --- a/include/graphics/nxwidgets/ccallback.hxx +++ b/include/graphics/nxwidgets/ccallback.hxx @@ -1,7 +1,7 @@ /**************************************************************************** * apps/include/graphics/nxwidgets/ccallback.hxx * - * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2012, 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -96,6 +97,8 @@ namespace NXWidgets #ifdef CONFIG_NXTERM_NXKBDIN NXTERM m_nxterm; /**< The NxTerm handle for redirection of keyboard input */ #endif + volatile bool m_synchronized; /**< True: Syncrhonized with NX server */ + sem_t m_semevent; /**< Event wait semaphore */ // Methods in the callback vtable @@ -139,6 +142,7 @@ namespace NXWidgets FAR const struct nxgl_rect_s *bounds, FAR void *arg); +#ifdef CONFIG_NX_XYINPUT /** * New mouse data is available for the window. The new mouse * data is handled by CWidgetControl::newMouseEvent. @@ -158,12 +162,12 @@ namespace NXWidgets * nxtk_openwindow, or nxtk_opentoolbar). */ -#ifdef CONFIG_NX_XYINPUT static void newMouseEvent(NXHANDLE hwnd, FAR const struct nxgl_point_s *pos, uint8_t buttons, FAR void *arg); #endif /* CONFIG_NX_XYINPUT */ +#ifdef CONFIG_NX_KBD /** * New keyboard/keypad data is available for the window. The new * keyboard data is handled by CWidgetControl::newKeyboardEvent. @@ -183,7 +187,6 @@ namespace NXWidgets * nxtk_openwindow, or nxtk_opentoolbar). */ -#ifdef CONFIG_NX_KBD static void newKeyboardEvent(NXHANDLE hwnd, uint8_t nCh, FAR const uint8_t *str, FAR void *arg); #endif // CONFIG_NX_KBD @@ -229,6 +232,16 @@ namespace NXWidgets public: + /** + * Enum of window types + */ + + enum WindowType + { + NX_RAWWINDOW = 0, + NXTK_FRAMEDWINDOW + }; + /** * Constructor. * @@ -259,6 +272,18 @@ namespace NXWidgets return &m_callbacks; } + /** + * Synchronize the window with the NX server. This function will delay + * until the the NX server has caught up with all of the queued requests. + * When this function returns, the state of the NX server will be the + * same as the state of the application. + * + * @param hwnd Handle to a specific NX window. + */ + + void synchronize(NXWINDOW hwnd, enum WindowType windowType); + +#ifdef CONFIG_NXTERM_NXKBDIN /** * By default, NX keyboard input is given to the various widgets * residing in the window. But NxTerm is a different usage model; @@ -273,7 +298,6 @@ namespace NXWidgets * directed to the widgets within the window. */ -#ifdef CONFIG_NXTERM_NXKBDIN inline void setNxTerm(NXTERM handle) { m_nxterm = handle; diff --git a/include/graphics/nxwidgets/cnxtkwindow.hxx b/include/graphics/nxwidgets/cnxtkwindow.hxx index ee46509c7..36dd0c026 100644 --- a/include/graphics/nxwidgets/cnxtkwindow.hxx +++ b/include/graphics/nxwidgets/cnxtkwindow.hxx @@ -1,7 +1,7 @@ /**************************************************************************** * apps/include/graphics/nxwidgets/cnxtkwindow.hxx * - * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2012, 2015, 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -139,6 +139,18 @@ namespace NXWidgets CWidgetControl *getWidgetControl(void) const; + /** + * Synchronize the window with the NX server. This function will delay + * until the the NX server has caught up with all of the queued requests. + * When this function returns, the state of the NX server will be the + * same as the state of the application. + */ + + inline void synchronize(void) + { + CCallback::synchronize(m_hNxTkWindow, CCallback::NXTK_FRAMEDWINDOW); + } + /** * Open a toolbar on the framed window. This method both instantiates * the toolbar object AND calls the INxWindow::open() method to diff --git a/include/graphics/nxwidgets/cnxtoolbar.hxx b/include/graphics/nxwidgets/cnxtoolbar.hxx index 9c4ed5c68..fd468f014 100644 --- a/include/graphics/nxwidgets/cnxtoolbar.hxx +++ b/include/graphics/nxwidgets/cnxtoolbar.hxx @@ -1,7 +1,7 @@ /**************************************************************************** * apps/include/graphics/nxwidgets/cnxtoolbar.hxx * - * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2012, 2015, 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -129,6 +129,18 @@ namespace NXWidgets CWidgetControl *getWidgetControl(void) const; + /** + * Synchronize the window with the NX server. This function will delay + * until the the NX server has caught up with all of the queued requests. + * When this function returns, the state of the NX server will be the + * same as the state of the application. + */ + + inline void synchronize(void) + { + CCallback::synchronize(m_hNxTkWindow, CCallback::NXTK_FRAMEDWINDOW); + } + /** * Request the position and size information of the toolbar. The values * will be returned asynchronously through the client callback method. diff --git a/include/graphics/nxwidgets/cnxwindow.hxx b/include/graphics/nxwidgets/cnxwindow.hxx index 00655a0ac..4bf5a2daa 100644 --- a/include/graphics/nxwidgets/cnxwindow.hxx +++ b/include/graphics/nxwidgets/cnxwindow.hxx @@ -1,7 +1,7 @@ /**************************************************************************** * apps/include/graphics/nxwidgets/cnxwindow.hxx * - * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2012, 2015, 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -139,6 +139,18 @@ namespace NXWidgets CWidgetControl *getWidgetControl(void) const; + /** + * Synchronize the window with the NX server. This function will delay + * until the the NX server has caught up with all of the queued requests. + * When this function returns, the state of the NX server will be the + * same as the state of the application. + */ + + inline void synchronize(void) + { + CCallback::synchronize(m_hNxWindow, CCallback::NX_RAWWINDOW); + } + /** * Request the position and size information of the window. The values * will be returned asynchronously through the client callback method. diff --git a/include/graphics/nxwidgets/inxwindow.hxx b/include/graphics/nxwidgets/inxwindow.hxx index a78f42280..2ac7bc113 100644 --- a/include/graphics/nxwidgets/inxwindow.hxx +++ b/include/graphics/nxwidgets/inxwindow.hxx @@ -1,7 +1,7 @@ /**************************************************************************** * apps/include/graphics/nxwidgets/inxwindow.hxx * - * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2012, 2015, 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -119,6 +119,15 @@ namespace NXWidgets virtual CWidgetControl *getWidgetControl(void) const = 0; + /** + * Synchronize the window with the NX server. This function will delay + * until the the NX server has caught up with all of the queued requests. + * When this function returns, the state of the NX server will be the + * same as the state of application. + */ + + virtual void synchronize(void) = 0; + /** * Request the position and size information of the window. The values * will be returned asynchronously through the client callback method. @@ -180,6 +189,7 @@ namespace NXWidgets virtual bool lower(void) = 0; +#ifdef CONFIG_NXTERM_NXKBDIN /** * Each window implementation also inherits from CCallback. CCallback, * by default, forwards NX keyboard input to the various widgets residing @@ -194,7 +204,6 @@ namespace NXWidgets * directed to the widgets within the window. */ -#ifdef CONFIG_NXTERM_NXKBDIN virtual void redirectNxTerm(NXTERM handle) = 0; #endif