summaryrefslogtreecommitdiff
path: root/NxWidgets/libnxwidgets
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-05-07 15:05:07 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-05-07 15:05:07 +0000
commit0860510a3519855cdbff730ab01f8ea08220e183 (patch)
tree9bcef9d2c82162732b856d2b3544ecdd310558eb /NxWidgets/libnxwidgets
parent2ca1594f911180b2a342c884e87285060a052865 (diff)
downloadnuttx-0860510a3519855cdbff730ab01f8ea08220e183.tar.gz
nuttx-0860510a3519855cdbff730ab01f8ea08220e183.tar.bz2
nuttx-0860510a3519855cdbff730ab01f8ea08220e183.zip
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
Diffstat (limited to 'NxWidgets/libnxwidgets')
-rw-r--r--NxWidgets/libnxwidgets/include/cwidgetcontrol.hxx74
-rw-r--r--NxWidgets/libnxwidgets/src/cnxtkwindow.cxx6
-rw-r--r--NxWidgets/libnxwidgets/src/cwidgetcontrol.cxx59
3 files changed, 96 insertions, 43 deletions
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
@@ -304,6 +304,16 @@ namespace NXWidgets
}
/**
+ * 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
@@ -448,6 +436,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,
* in particular, will occur when the a portion of the window that was
* previously obscured is now exposed.
*
@@ -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