From 0860510a3519855cdbff730ab01f8ea08220e183 Mon Sep 17 00:00:00 2001 From: patacongo Date: Mon, 7 May 2012 15:05:07 +0000 Subject: NxWidgets: Fix a potential deadlock that can occur waiting for toolbard geometry data git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4709 42af7a65-404d-4744-a932-0658087f49c3 --- NxWidgets/libnxwidgets/include/cwidgetcontrol.hxx | 74 ++++++++++++++++------- NxWidgets/libnxwidgets/src/cnxtkwindow.cxx | 6 ++ NxWidgets/libnxwidgets/src/cwidgetcontrol.cxx | 59 +++++++++++------- 3 files changed, 96 insertions(+), 43 deletions(-) (limited to 'NxWidgets/libnxwidgets') diff --git a/NxWidgets/libnxwidgets/include/cwidgetcontrol.hxx b/NxWidgets/libnxwidgets/include/cwidgetcontrol.hxx index 7725dec2c..e33757a95 100644 --- a/NxWidgets/libnxwidgets/include/cwidgetcontrol.hxx +++ b/NxWidgets/libnxwidgets/include/cwidgetcontrol.hxx @@ -303,6 +303,16 @@ namespace NXWidgets #endif } + /** + * Wait for geometry data + */ + + inline void waitGeoData(void) + { + takeGeoSem(); + giveGeoSem(); + } + /** * Clear all mouse events */ @@ -535,11 +545,11 @@ namespace NXWidgets /** * This event means that new mouse data is available for the window. * - * @param pPos The (x,y) position of the mouse. + * @param pos The (x,y) position of the mouse. * @param buttons See NX_MOUSE_* definitions. */ - void newMouseEvent(FAR const struct nxgl_point_s *pPos, uint8_t buttons); + void newMouseEvent(FAR const struct nxgl_point_s *pos, uint8_t buttons); /** * This event means that keyboard/keypad data is available for the window. @@ -570,71 +580,93 @@ namespace NXWidgets } /** - * Get the window bounding box in physical display coordinated. + * Get the window bounding box in physical display coordinated. This + * method may need to wait until geometry data is available. * * @return This function returns the window handle. */ inline CRect getWindowBoundingBox(void) { - takeGeoSem(); - CRect rect(&m_bounds); - giveGeoSem(); - return rect; + waitGeoData(); + return CRect(&m_bounds); + } + + inline void getWindowBoundingBox(FAR struct nxgl_rect_s *bounds) + { + waitGeoData(); + nxgl_rectcopy(bounds, &m_bounds); } /** - * Get the position of the window (as reported by the last NX callback). + * Get the position of the window (as reported by the last NX callback). This + * method may need to wait until geometry data is available. * * @return The position. */ - inline bool getWindowPosition(FAR struct nxgl_point_s *pPos) + inline bool getWindowPosition(FAR struct nxgl_point_s *pos) { - takeGeoSem(); - pPos->x = m_pos.x; - pPos->x = m_pos.y; - giveGeoSem(); + waitGeoData(); + pos->x = m_pos.x; + pos->x = m_pos.y; return true; } /** - * Get the size of the window (as reported by the last NX callback). + * Get the size of the window (as reported by the last NX callback). This + * method may need to wait until geometry data is available. * * @return The size. */ - inline bool getWindowSize(FAR struct nxgl_size_s *pSize) + inline bool getWindowSize(FAR struct nxgl_size_s *size) { - takeGeoSem(); - pSize->h = m_size.h; - pSize->w = m_size.w; - giveGeoSem(); + waitGeoData(); + size->h = m_size.h; + size->w = m_size.w; return true; } /** - * Get the width of the window (as reported by the last NX callback). + * Get the width of the window (as reported by the last NX callback). This + * method may need to wait until geometry data is available. * * @return The size. */ inline nxgl_coord_t getWindowWidth(void) { + waitGeoData(); return m_size.w; } /** - * Get the height of the window (as reported by the last NX callback). + * Get the height of the window (as reported by the last NX callback). This + * method may need to wait until geometry data is available. * * @return The size. */ inline nxgl_coord_t getWindowHeight(void) { + waitGeoData(); return m_size.h; } + /** + * Set the size of the window. This is normally reported by an NX callback. But + * the toolbar widget control does not get NX callbacks and has to get the + * window size throught this method. This method should not be called by user + * code + * + * @param hWindow The window handle that should be used to communicate + * with the window + * @param bounds. The size of the underlying window. + */ + + void setWindowBounds(NXHANDLE hWindow, FAR const struct nxgl_rect_s *bounds); + /** * The creation sequence is: * diff --git a/NxWidgets/libnxwidgets/src/cnxtkwindow.cxx b/NxWidgets/libnxwidgets/src/cnxtkwindow.cxx index 8b880a618..3f77254b2 100644 --- a/NxWidgets/libnxwidgets/src/cnxtkwindow.cxx +++ b/NxWidgets/libnxwidgets/src/cnxtkwindow.cxx @@ -178,6 +178,12 @@ CNxToolbar *CNxTkWindow::openToolbar(nxgl_coord_t height) delete widgetControl; return (CNxToolbar *)0; } + + // Provide parent widget control information to new widget control instance + + struct nxgl_rect_s bounds; + m_widgetControl->getWindowBoundingBox(&bounds); + widgetControl->setWindowBounds(m_widgetControl->getWindowHandle(), &bounds); } return m_toolbar; diff --git a/NxWidgets/libnxwidgets/src/cwidgetcontrol.cxx b/NxWidgets/libnxwidgets/src/cwidgetcontrol.cxx index 1e1c9ce87..42cd047fa 100644 --- a/NxWidgets/libnxwidgets/src/cwidgetcontrol.cxx +++ b/NxWidgets/libnxwidgets/src/cwidgetcontrol.cxx @@ -400,30 +400,18 @@ void CWidgetControl::setFocusedWidget(CNxWidget *widget) } /** - * This event is called from CCallback instance to provide - * notifications of certain NX-server related events. This event, - * in particular, will occur when the position or size of the underlying - * window occurs. + * Set the size of the window. This is normally reported by an NX callback. But + * the toolbar widget control does not get NX callbacks and has to get the + * window size throught this method. This method should not be called by user + * code * * @param hWindow The window handle that should be used to communicate * with the window - * @param pos The position of the window in the physical device space. - * @param size The size of the window. - * @param bounds The size of the underlying display (pixels x rows) + * @param bounds. The size of the underlying window. */ -void CWidgetControl::geometryEvent(NXHANDLE hWindow, - const struct nxgl_size_s *size, - const struct nxgl_point_s *pos, - const struct nxgl_rect_s *bounds) +void CWidgetControl::setWindowBounds(NXHANDLE hWindow, FAR const struct nxgl_rect_s *bounds) { - // Save positional data that may change dynamically - - m_pos.x = pos->x; - m_pos.y = pos->y; - m_size.h = size->h; - m_size.w = size->w; - // The first callback is important. This is the handshake that proves // that we are truly communicating with the servier. This is also // a critical point because this is when we know the physical @@ -445,6 +433,33 @@ void CWidgetControl::geometryEvent(NXHANDLE hWindow, } } +/** + * This event is called from CCallback instance to provide + * notifications of certain NX-server related events. This event, + * in particular, will occur when the position or size of the underlying + * window occurs. + * + * @param hWindow The window handle that should be used to communicate + * with the window + * @param pos The position of the window in the physical device space. + * @param size The size of the window. + * @param bounds The size of the underlying display (pixels x rows) + */ + +void CWidgetControl::geometryEvent(NXHANDLE hWindow, + FAR const struct nxgl_size_s *size, + FAR const struct nxgl_point_s *pos, + FAR const struct nxgl_rect_s *bounds) +{ + // Save positional data that may change dynamically + + m_pos.x = pos->x; + m_pos.y = pos->y; + m_size.h = size->h; + m_size.w = size->w; + setWindowBounds(hWindow, bounds); +} + /** * This event is called from CCallback instance to provide * notifications of certain NX-server related events. This event, @@ -467,16 +482,16 @@ void CWidgetControl::redrawEvent(FAR const struct nxgl_rect_s *nxRect, bool more * certain NX-server related events. This event, in particular, means that * new mouse data is available for the window. * - * @param pPos The (x,y) position of the mouse. + * @param pos The (x,y) position of the mouse. * @param buttons See NX_MOUSE_* definitions. */ -void CWidgetControl::newMouseEvent(FAR const struct nxgl_point_s *pPos, uint8_t buttons) +void CWidgetControl::newMouseEvent(FAR const struct nxgl_point_s *pos, uint8_t buttons) { // Save the mouse X/Y position - m_mouse.x = pPos->x; - m_mouse.y = pPos->y; + m_mouse.x = pos->x; + m_mouse.y = pos->y; // Update button press states -- cgit v1.2.3