diff --git a/UnitTests/nxwm/main.cxx b/UnitTests/nxwm/main.cxx index d93d9b391..f07cdb19c 100644 --- a/UnitTests/nxwm/main.cxx +++ b/UnitTests/nxwm/main.cxx @@ -172,6 +172,17 @@ int MAIN_NAME(int argc, char *argv[]) return EXIT_FAILURE; } + // Initialize the NSH library + + printf(MAIN_STRING "Initialize the NSH library\n"); + if (!NxWM::nshlibInitialize()) + { + printf(MAIN_STRING "ERROR: Failed to initialize the NSH library\n"); + delete window; + delete g_nxwmtest.taskbar; + return EXIT_FAILURE; + } + // Add the NxConsole application to the start window NxWM::CNxConsole *console = (NxWM::CNxConsole *)0; // Avoid compiler complaint diff --git a/libnxwidgets/include/cwidgetcontrol.hxx b/libnxwidgets/include/cwidgetcontrol.hxx index 9fedd4618..0a894eae8 100644 --- a/libnxwidgets/include/cwidgetcontrol.hxx +++ b/libnxwidgets/include/cwidgetcontrol.hxx @@ -193,6 +193,9 @@ namespace NXWidgets struct nxgl_size_s m_size; /**< Size of the window */ struct nxgl_point_s m_pos; /**< Position in display space */ struct nxgl_rect_s m_bounds; /**< Size of the display */ +#ifdef CONFIG_NX_MULTIUSER + sem_t m_geosem; /**< Posted when geometry is valid */ +#endif /** * Style @@ -279,6 +282,27 @@ namespace NXWidgets void wakeupModalLoop(void); + /** + * Take the geometry semaphore (handling signal interruptions) + */ + +#ifdef CONFIG_NX_MULTIUSER + void takeGeoSem(void); +#else + inline void takeGeoSem(void) {} +#endif + + /** + * Give the geometry semaphore + */ + + inline void giveGeoSem(void) + { +#ifdef CONFIG_NX_MULTIUSER + sem_post(&m_geosem); +#endif + } + /** * Clear all mouse events */ @@ -553,7 +577,10 @@ namespace NXWidgets inline CRect getWindowBoundingBox(void) { - return CRect(&m_bounds); + takeGeoSem(); + CRect rect(&m_bounds); + giveGeoSem(); + return rect; } /** @@ -564,8 +591,10 @@ namespace NXWidgets inline bool getWindowPosition(FAR struct nxgl_point_s *pPos) { + takeGeoSem(); pPos->x = m_pos.x; pPos->x = m_pos.y; + giveGeoSem(); return true; } @@ -577,8 +606,10 @@ namespace NXWidgets inline bool getWindowSize(FAR struct nxgl_size_s *pSize) { + takeGeoSem(); pSize->h = m_size.h; pSize->w = m_size.w; + giveGeoSem(); return true; } diff --git a/libnxwidgets/src/cimage.cxx b/libnxwidgets/src/cimage.cxx index c905737fd..0ca6f571e 100644 --- a/libnxwidgets/src/cimage.cxx +++ b/libnxwidgets/src/cimage.cxx @@ -272,7 +272,7 @@ void CImage::drawContents(CGraphicsPort *port) } else { - port->drawBitmapGreyScale(rect.getX(),displayRow, + port->drawBitmapGreyScale(rect.getX(), displayRow, rect.getWidth(), 1, &bitmap, 0, 0); } diff --git a/libnxwidgets/src/cwidgetcontrol.cxx b/libnxwidgets/src/cwidgetcontrol.cxx index 5ea672a2f..a6807dad5 100644 --- a/libnxwidgets/src/cwidgetcontrol.cxx +++ b/libnxwidgets/src/cwidgetcontrol.cxx @@ -42,6 +42,7 @@ #include #include #include +#include #include "nxconfig.hxx" #include "cnxserver.hxx" @@ -427,6 +428,13 @@ void CWidgetControl::geometryEvent(NXHANDLE hWindow, m_hWindow = hWindow; nxgl_rectcopy(&m_bounds, bounds); + + // Wake up any threads waiting for initial position information. + // REVISIT: If the window is moved or repositioned, then the + // position and size data will be incorrect for a period of time. + // That case should be handled here as well. + + giveGeoSem(); } } @@ -864,6 +872,25 @@ bool CWidgetControl::pollCursorControlEvents(void) return cursorControlEvent; } +/** + * Take the geometry semaphore (handling signal interruptions) + */ + +#ifdef CONFIG_NX_MULTIUSER +void CWidgetControl::takeGeoSem(void) +{ + // Take the geometry semaphore. Retry is an error occurs (only if + // the error is due to a signal interruption). + + int ret; + do + { + ret = sem_wait(&m_geosem); + } + while (ret < 0 && errno == EINTR); +} +#endif + /** * Clear all mouse events */ diff --git a/nxwm/src/cnxconsole.cxx b/nxwm/src/cnxconsole.cxx index 5fe81d844..3652364c7 100644 --- a/nxwm/src/cnxconsole.cxx +++ b/nxwm/src/cnxconsole.cxx @@ -142,38 +142,6 @@ CNxConsole::~CNxConsole(void) } } -/** - * One time NSH initialization. This function must be called exactly - * once during the boot-up sequence to initialize the NSH library. - * - * @return True on successful initialization - */ - -bool nshlibInitialize(void) -{ - // Initialize the global data structure - - sem_init(&g_nxconvars.sem, 0, 0); - - // Initialize the NSH library - - nsh_initialize(); - - // If the Telnet console is selected as a front-end, then start the - // Telnet daemon. - -#ifdef CONFIG_NSH_TELNET - int ret = nsh_telnetstart(); - if (ret < 0) - { - // The daemon is NOT running! - - return false; - } -#endif - return true; -} - /** * Each implementation of IApplication must provide a method to recover * the contained CApplicationWindow instance. @@ -442,5 +410,35 @@ void CNxConsole::close(void) m_taskbar->stopApplication(static_cast(this)); } +/** + * One time NSH initialization. This function must be called exactly + * once during the boot-up sequence to initialize the NSH library. + * + * @return True on successful initialization + */ +bool NxWM::nshlibInitialize(void) +{ + // Initialize the global data structure + + sem_init(&g_nxconvars.sem, 0, 0); + + // Initialize the NSH library + + nsh_initialize(); + + // If the Telnet console is selected as a front-end, then start the + // Telnet daemon. + +#ifdef CONFIG_NSH_TELNET + int ret = nsh_telnetstart(); + if (ret < 0) + { + // The daemon is NOT running! + + return false; + } +#endif + return true; +} diff --git a/nxwm/src/ctaskbar.cxx b/nxwm/src/ctaskbar.cxx index faac2fa76..1dba90c5a 100644 --- a/nxwm/src/ctaskbar.cxx +++ b/nxwm/src/ctaskbar.cxx @@ -867,7 +867,7 @@ bool CTaskbar::redrawTaskbarWindow(void) { // Get the icon associated with this application - NXWidgets::CImage *image = m_slots.at(i).image; + NXWidgets::CImage *image = m_slots.at(i).image; // Disable drawing of the icon image; disable events from the icon @@ -962,6 +962,7 @@ bool CTaskbar::redrawBackgroundWindow(void) // Then re-draw the background image on the window + m_backImage->enableDrawing(); m_backImage->redraw(); return true; } @@ -982,7 +983,7 @@ bool CTaskbar::redrawApplicationWindow(void) { // No.. Search for that last, non-minimized application - for (int i = m_slots.size() - 1; i > 0; i--) + for (int i = m_slots.size() - 1; i >= 0; i--) { IApplication *candidate = m_slots.at(i).app; if (!candidate->isMinimized()) @@ -1002,6 +1003,10 @@ bool CTaskbar::redrawApplicationWindow(void) m_topapp = app; app->setTopApplication(true); + // Disable drawing of the background image. + + m_backImage->disableDrawing(); + // And.. Draw the application app->redraw(); @@ -1009,7 +1014,7 @@ bool CTaskbar::redrawApplicationWindow(void) } else { - // Otherwise, re-draw the background + // Otherwise, re-draw the background image m_topapp = (IApplication *)0; return redrawBackgroundWindow();