summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-02-28 18:48:11 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-02-28 18:48:11 +0000
commita63f8bb684d01a23bfe1ee85b1d7faf983b9d1ea (patch)
tree3f51cea039f16c0a9b0b8e05550fe9112d72d824
parentf1b1e3ba11994bcbb0a1ddad9f8e686a6a9ae475 (diff)
downloadnuttx-a63f8bb684d01a23bfe1ee85b1d7faf983b9d1ea.tar.gz
nuttx-a63f8bb684d01a23bfe1ee85b1d7faf983b9d1ea.tar.bz2
nuttx-a63f8bb684d01a23bfe1ee85b1d7faf983b9d1ea.zip
NxWidgets/NxWM updates from Petteri Aimonen (Patches 0007-0013)
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5689 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--NxWidgets/ChangeLog.txt48
-rw-r--r--NxWidgets/Kconfig24
-rw-r--r--NxWidgets/libnxwidgets/include/cimage.hxx8
-rw-r--r--NxWidgets/libnxwidgets/include/cwidgetcontrol.hxx71
-rw-r--r--NxWidgets/libnxwidgets/src/cimage.cxx27
-rw-r--r--NxWidgets/libnxwidgets/src/cmultilinetextbox.cxx4
-rw-r--r--NxWidgets/libnxwidgets/src/cnxtimer.cxx8
-rw-r--r--NxWidgets/libnxwidgets/src/cwidgetcontrol.cxx46
-rw-r--r--NxWidgets/nxwm/include/cstartwindow.hxx1
-rw-r--r--NxWidgets/nxwm/include/cwindowmessenger.hxx25
-rw-r--r--NxWidgets/nxwm/src/capplicationwindow.cxx22
-rw-r--r--NxWidgets/nxwm/src/cstartwindow.cxx153
-rw-r--r--NxWidgets/nxwm/src/ctaskbar.cxx18
-rw-r--r--NxWidgets/nxwm/src/cwindowmessenger.cxx116
-rw-r--r--apps/NxWidgets/Kconfig24
-rw-r--r--nuttx/tools/cfgdefine.c8
-rw-r--r--nuttx/tools/cfgparser.c8
17 files changed, 319 insertions, 292 deletions
diff --git a/NxWidgets/ChangeLog.txt b/NxWidgets/ChangeLog.txt
index dd3422dcc..1d2abab4d 100644
--- a/NxWidgets/ChangeLog.txt
+++ b/NxWidgets/ChangeLog.txt
@@ -280,4 +280,50 @@
it works with indexed input images.
* NxWidgets::CLabel: Fix backward conditional compilation in the
"flicker free" logic.
-
+* NxWidgets::CNxTimer: Previously repeated timers were re-enabled after
+ the timer action event. Consequently, if the action event handler tried
+ to stop the timer, the request would be ignored. Changes the order
+ so that the timer is re-enabled before the callback. There is still
+ no risk of re-entrancy, because everything executes on the USRWORK work
+ queue. From Petteri Aimonen.
+* NxWidgets::CMultiLineTestBox: Fix text placement error. From Petteri
+ Aimonen.
+* NxWidgets::CWidgetControl: Added another semaphore, boundssem, which
+ is set as soon as the screen bounds are known. This corrects two
+ problems:
+ 1) Due to the way nxgl_rectsize computes the size, it will never
+ be 0,0 like CWidgetControl expects. Therefore the size is considered
+ valid even though it has not been set yet.
+ 2) After the check is fixed to test for > 1, NxWM window creation will
+ hang. This is due to the fact that it uses the screen bounds for
+ determining window size. This was being blocked on geosem, which
+ is only posted after the size has been set.
+ From Petteri Aimonen.
+* NxWidgets::CImage: Two enhancements:
+ 1) Allow changing the bitmap even after the control has been created.
+ 2) Allow giving 'null' to have the control draw no image at all.
+ From Petteri Aimonen.
+* NxWM::CTaskBar: Allow windows with null icon. This makes sense for e.g.
+ full screen windows. From Petteri Aimonen.
+* NxWM::CApplicationWindow: Add config options to override NxWM
+ stop/minimize icons. From Petteri Aimonen.
+* NwWM::CStartWindow, NxWM::CWindowMessenger: Get rid of the start window
+ thread. Instead, handle all events through the USRWORK work queue.
+ For me, this was necessary because I would open some files in button
+ handlers and close them in NxTimer handlers. If these belonged to
+ different tasks, the close operation would fail. Further benefits:
+ + Gets rid of one task and message queue.
+ + Reduces the amount of code required
+ + Decouples CStartWindow from everything else - now it is just a window
+ with application icons, not an integral part of the event logic.
+ + All events come from the same thread, which reduces the possibility of
+ multithreading errors in user code.
+ + The user code can also send events to USRWORK, so that everything gets
+ serialized nicely without having to use so many mutexes.
+ Drawbacks:
+ - Currently the work state structure is malloc()ed, causing one allocation
+ and free per each input event. Could add a memory pool for these later, but
+ the speed difference doesn't seem noticeable.
+ - The work queue will add ~50 ms latency to input events. This is however
+ configurable, and the delay is anyway short enough that it is unnoticeable.
+ From Petteri Aimonen.
diff --git a/NxWidgets/Kconfig b/NxWidgets/Kconfig
index 656399199..6f5f3e924 100644
--- a/NxWidgets/Kconfig
+++ b/NxWidgets/Kconfig
@@ -463,6 +463,30 @@ config NXWM_BACKGROUND_IMAGE
The name of the image to use in the background window. Default:
NXWidgets::g_nuttxBitmap
+comment "Application Window Configuration"
+
+config NXWM_CUSTOM_APPWINDOW_ICONS
+ bool "Custom Start/Stop Application Window Icons"
+ default n
+ ---help---
+ Select to override the default Application Window Stop and Minimize Icons.
+
+if NXWM_CUSTOM_APPWINDOW_ICONS
+
+config NXWM_STOP_BITMAP
+ string "Stop Icon"
+ default "NxWM::g_stopBitmap"
+ ---help---
+ The glyph to use as the Stop icon. Default: NxWM::g_stopBitmap
+
+config NXWM_MINIMIZE_BITMAP
+ string "Minimize Icon"
+ default "NxWM::g_minimizeBitmap"
+ ---help---
+ The glyph to use as the Minimize icon. Default: NxWM::g_minimizeBitmap
+
+endif
+
comment "Start Window Configuration"
comment "Horizontal and vertical spacing of icons in the task bar"
diff --git a/NxWidgets/libnxwidgets/include/cimage.hxx b/NxWidgets/libnxwidgets/include/cimage.hxx
index 6093c5f33..438ea7267 100644
--- a/NxWidgets/libnxwidgets/include/cimage.hxx
+++ b/NxWidgets/libnxwidgets/include/cimage.hxx
@@ -1,7 +1,7 @@
/****************************************************************************
* NxWidgets/libnxwidgets/include/cimage.hxx
*
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -208,6 +208,12 @@ namespace NXWidgets
inline FAR IBitmap *getBitmap() const { return m_bitmap; }
/**
+ * Set the bitmap that this image contains.
+ */
+
+ inline void setBitmap(FAR IBitmap *bitmap) { m_bitmap = bitmap; }
+
+ /**
* Insert the dimensions that this widget wants to have into the rect
* passed in as a parameter. All coordinates are relative to the
* widget's parent.
diff --git a/NxWidgets/libnxwidgets/include/cwidgetcontrol.hxx b/NxWidgets/libnxwidgets/include/cwidgetcontrol.hxx
index e709271a0..f0afe2c47 100644
--- a/NxWidgets/libnxwidgets/include/cwidgetcontrol.hxx
+++ b/NxWidgets/libnxwidgets/include/cwidgetcontrol.hxx
@@ -1,7 +1,7 @@
/****************************************************************************
* NxWidgets/libnxwidgets/include/cwidgetcontrol.hxx
*
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -39,11 +39,12 @@
/****************************************************************************
* Included Files
****************************************************************************/
-
+
#include <nuttx/config.h>
#include <stdint.h>
#include <stdbool.h>
+#include <stdlib.h>
#include <semaphore.h>
#include <time.h>
@@ -203,6 +204,7 @@ namespace NXWidgets
struct nxgl_rect_s m_bounds; /**< Size of the display */
#ifdef CONFIG_NX_MULTIUSER
sem_t m_geoSem; /**< Posted when geometry is valid */
+ sem_t m_boundsSem; /**< Posted when bounds are valid */
#endif
CWindowEventHandlerList m_eventHandlers; /**< List of event handlers. */
@@ -228,7 +230,7 @@ namespace NXWidgets
* @param startTime A time in the past from which to compute the elapsed time.
* @return The elapsed time since startTime
*/
-
+
uint32_t elapsedTime(FAR const struct timespec *startTime);
/**
@@ -256,7 +258,7 @@ namespace NXWidgets
/**
* Delete any widgets in the deletion queue.
*/
-
+
void processDeleteQueue(void);
/**
@@ -325,6 +327,37 @@ namespace NXWidgets
}
/**
+ * Take the bounds semaphore (handling signal interruptions)
+ */
+
+#ifdef CONFIG_NX_MULTIUSER
+ void takeBoundsSem(void);
+#else
+ inline void takeBoundsSem(void) {}
+#endif
+
+ /**
+ * Give the bounds semaphore
+ */
+
+ inline void giveBoundsSem(void)
+ {
+#ifdef CONFIG_NX_MULTIUSER
+ sem_post(&m_boundsSem);
+#endif
+ }
+
+ /**
+ * Wait for bounds data
+ */
+
+ inline void waitBoundsData(void)
+ {
+ takeBoundsSem();
+ giveBoundsSem();
+ }
+
+ /**
* Clear all mouse events
*/
@@ -345,7 +378,7 @@ namespace NXWidgets
/**
* Destructor.
*/
-
+
virtual ~CWidgetControl(void);
/**
@@ -407,7 +440,7 @@ namespace NXWidgets
* all widgets in the window.
* @return True means some interesting event occurred
*/
-
+
bool pollEvents(CNxWidget *widget = (CNxWidget *)NULL);
/**
@@ -425,7 +458,7 @@ namespace NXWidgets
*
* @param widget The widget to be controlled.
*/
-
+
inline void addControlledWidget(CNxWidget* widget)
{
m_widgets.push_back(widget);
@@ -438,7 +471,7 @@ namespace NXWidgets
*/
void removeControlledWidget(CNxWidget* widget);
-
+
/**
* Get the number of controlled widgets.
*
@@ -456,7 +489,7 @@ namespace NXWidgets
*
* @param widget The widget to add to the delete queue.
*/
-
+
void addToDeleteQueue(CNxWidget *widget);
/**
@@ -469,7 +502,7 @@ namespace NXWidgets
void setClickedWidget(CNxWidget *widget);
/**
- * Get the clicked widget pointer.
+ * Get the clicked widget pointer.
*
* @return Pointer to the clicked widget.
*/
@@ -502,7 +535,7 @@ namespace NXWidgets
}
/**
- * Get the focused widget pointer.
+ * Get the focused widget pointer.
*
* @return Pointer to the focused widget.
*/
@@ -513,7 +546,7 @@ namespace NXWidgets
}
/**
- * Check for the occurrence of a double click.
+ * Check for the occurrence of a double click.
*
* @return Pointer to the clicked widget.
*/
@@ -582,7 +615,7 @@ namespace NXWidgets
* @param pos The (x,y) position of the mouse.
* @param buttons See NX_MOUSE_* definitions.
*/
-
+
void newMouseEvent(FAR const struct nxgl_point_s *pos, uint8_t buttons);
/**
@@ -624,7 +657,7 @@ namespace NXWidgets
*
* @param cursorControl The cursor control code received.
*/
-
+
void newCursorControlEvent(ECursorControl cursorControl);
/**
@@ -639,21 +672,21 @@ namespace NXWidgets
}
/**
- * Get the window bounding box in physical display coordinated. This
- * method may need to wait until geometry data is available.
+ * Get the window bounding box in physical display coordinates. This
+ * method may need to wait until bounds data is available.
*
* @return This function returns the window handle.
*/
inline CRect getWindowBoundingBox(void)
{
- waitGeoData();
+ waitBoundsData();
return CRect(&m_bounds);
}
inline void getWindowBoundingBox(FAR struct nxgl_rect_s *bounds)
{
- waitGeoData();
+ waitBoundsData();
nxgl_rectcopy(bounds, &m_bounds);
}
@@ -759,7 +792,7 @@ namespace NXWidgets
inline void removeWindowEventHandler(CWindowEventHandler *eventHandler)
{
- m_eventHandlers.removeWindowEventHandler(eventHandler);
+ m_eventHandlers.removeWindowEventHandler(eventHandler);
}
};
}
diff --git a/NxWidgets/libnxwidgets/src/cimage.cxx b/NxWidgets/libnxwidgets/src/cimage.cxx
index 30bf7e78b..9b3137129 100644
--- a/NxWidgets/libnxwidgets/src/cimage.cxx
+++ b/NxWidgets/libnxwidgets/src/cimage.cxx
@@ -1,7 +1,7 @@
/****************************************************************************
* NxWidgets/libnxwidgets/include/cimage.cxx
*
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -88,7 +88,7 @@
/****************************************************************************
* Pre-Processor Definitions
****************************************************************************/
-
+
/****************************************************************************
* Method Implementations
****************************************************************************/
@@ -163,6 +163,13 @@ void CImage::getPreferredDimensions(CRect &rect) const
void CImage::drawContents(CGraphicsPort *port)
{
+ if (!m_bitmap)
+ {
+ // No image to draw
+
+ return;
+ }
+
// Get the the drawable region
CRect rect;
@@ -187,11 +194,11 @@ void CImage::drawContents(CGraphicsPort *port)
m_bitmap->setSelected(isClicked() || m_highlighted);
// This is the number of rows that we can draw at the top of the display
-
+
nxgl_coord_t nTopRows = m_bitmap->getHeight() - m_origin.y;
if (nTopRows > rect.getHeight())
{
- nTopRows = rect.getHeight();
+ nTopRows = rect.getHeight();
}
else if (nTopRows < 0)
{
@@ -214,7 +221,7 @@ void CImage::drawContents(CGraphicsPort *port)
// the display
nxgl_coord_t nLeftPixels = m_bitmap->getWidth() - m_origin.x;
-
+
// This is the number of rows that we have to pad on the right if the display
// width is wider than the image width
@@ -257,7 +264,7 @@ void CImage::drawContents(CGraphicsPort *port)
// Replace any transparent pixels with the background color.
// Then we can use the faster opaque drawBitmap() function.
-
+
ptr = buffer;
for (int i = 0; i < nLeftPixels; i++, ptr++)
{
@@ -337,12 +344,12 @@ void CImage::drawBorder(CGraphicsPort *port)
{
return;
}
-
+
// Work out which colors to use
nxgl_coord_t color1;
nxgl_coord_t color2;
-
+
if (isClicked())
{
// Bevelled into the screen
@@ -357,7 +364,7 @@ void CImage::drawBorder(CGraphicsPort *port)
color1 = getShineEdgeColor();
color2 = getShadowEdgeColor();
}
-
+
port->drawBevelledRect(getX(), getY(), getWidth(), getHeight(), color1, color2);
}
@@ -389,7 +396,7 @@ void CImage::onClick(nxgl_coord_t x, nxgl_coord_t y)
}
/**
- * Raises an action.
+ * Raises an action.
*
* @param x The x coordinate of the mouse.
* @param y The y coordinate of the mouse.
diff --git a/NxWidgets/libnxwidgets/src/cmultilinetextbox.cxx b/NxWidgets/libnxwidgets/src/cmultilinetextbox.cxx
index 94caac5fd..df060f037 100644
--- a/NxWidgets/libnxwidgets/src/cmultilinetextbox.cxx
+++ b/NxWidgets/libnxwidgets/src/cmultilinetextbox.cxx
@@ -1261,8 +1261,8 @@ void CMultiLineTextBox::drawRow(CGraphicsPort *port, int row)
uint8_t rowLength = m_text->getLineTrimmedLength(row);
struct nxgl_point_s pos;
- pos.x = getRowX(row) + m_canvasX;
- pos.y = getRowY(row) + m_canvasY;
+ pos.x = getRowX(row) + m_canvasX + rect.getX();
+ pos.y = getRowY(row) + m_canvasY + rect.getY();
// Determine the background and text color
diff --git a/NxWidgets/libnxwidgets/src/cnxtimer.cxx b/NxWidgets/libnxwidgets/src/cnxtimer.cxx
index d663df036..d67cee6e8 100644
--- a/NxWidgets/libnxwidgets/src/cnxtimer.cxx
+++ b/NxWidgets/libnxwidgets/src/cnxtimer.cxx
@@ -193,16 +193,16 @@ void CNxTimer::workQueueCallback(FAR void *arg)
This->m_isRunning = false;
- // Raise the action event.
-
- This->m_widgetEventHandlers->raiseActionEvent();
-
// Restart the timer if this is a repeating timer
if (This->m_isRepeater)
{
This->start();
}
+
+ // Raise the action event.
+
+ This->m_widgetEventHandlers->raiseActionEvent();
}
diff --git a/NxWidgets/libnxwidgets/src/cwidgetcontrol.cxx b/NxWidgets/libnxwidgets/src/cwidgetcontrol.cxx
index 644abd714..2cb1a930d 100644
--- a/NxWidgets/libnxwidgets/src/cwidgetcontrol.cxx
+++ b/NxWidgets/libnxwidgets/src/cwidgetcontrol.cxx
@@ -1,7 +1,7 @@
/****************************************************************************
* NxWidgets/libnxwidgets/src/cwidgetcontrol.cxx
*
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -117,6 +117,7 @@ CWidgetControl::CWidgetControl(FAR const CWidgetStyle *style)
sem_init(&m_waitSem, 0, 0);
#endif
#ifdef CONFIG_NX_MULTIUSER
+ sem_init(&m_boundsSem, 0, 0);
sem_init(&m_geoSem, 0, 0);
#endif
@@ -135,12 +136,11 @@ CWidgetControl::CWidgetControl(FAR const CWidgetStyle *style)
copyWidgetStyle(&m_style, style);
}
}
-
/**
* Destructor.
*/
-
+
CWidgetControl::~CWidgetControl(void)
{
// Notify any external waiters... this should not happen because it
@@ -235,7 +235,7 @@ void CWidgetControl::postWindowEvent(void)
* all widgets in the window.
* @return True means some interesting event occurred
*/
-
+
bool CWidgetControl::pollEvents(CNxWidget *widget)
{
// Delete any queued widgets
@@ -299,7 +299,7 @@ void CWidgetControl::removeControlledWidget(CNxWidget *widget)
*
* @param widget The widget to add to the delete queue.
*/
-
+
void CWidgetControl::addToDeleteQueue(CNxWidget *widget)
{
// Add the widget to the delete queue
@@ -330,7 +330,7 @@ void CWidgetControl::setClickedWidget(CNxWidget *widget)
m_clickedWidget->release(m_clickedWidget->getX() - 10, 0);
}
-
+
// Update the pointer
m_clickedWidget = widget;
@@ -394,18 +394,19 @@ void CWidgetControl::geometryEvent(NXHANDLE hWindow,
if (!m_hWindow)
{
// Save one-time server specific information
-
+
m_hWindow = hWindow;
nxgl_rectcopy(&m_bounds, bounds);
+ giveBoundsSem();
}
// In the normal start up sequence, the window is created with zero size
// at position 0,0. The safe thing to do is to set the position (still
// with size 0, then then set the size. Assuming that is what is being
// done, we will not report that we have valid geometry until the size
- // becomes nonzero.
+ // becomes nonzero (or actually over 1).
- if (!m_haveGeometry && size->h > 0 && size->w > 0)
+ if (!m_haveGeometry && size->h > 1 && size->w > 1)
{
// Wake up any threads waiting for initial position information.
// REVISIT: If the window is moved or repositioned, then the
@@ -619,7 +620,7 @@ void CWidgetControl::newKeyboardEvent(uint8_t nCh, FAR const uint8_t *pStr)
*
* @param cursorControl The cursor control code received.
*/
-
+
void CWidgetControl::newCursorControlEvent(ECursorControl cursorControl)
{
// Append the new cursor control
@@ -688,7 +689,7 @@ void CWidgetControl::copyWidgetStyle(CWidgetStyle *dest, const CWidgetStyle *src
* @param tp A time in the past from which to compute the elapsed time.
* @return The elapsed time since tp
*/
-
+
uint32_t CWidgetControl::elapsedTime(FAR const struct timespec *startTime)
{
struct timespec endTime;
@@ -701,7 +702,7 @@ uint32_t CWidgetControl::elapsedTime(FAR const struct timespec *startTime)
uint32_t seconds = endTime.tv_sec - startTime->tv_sec;
// Get the elapsed nanoseconds, borrowing from the seconds if necessary
-
+
int32_t endNanoSeconds = endTime.tv_nsec;
if (startTime->tv_nsec > endNanoSeconds)
{
@@ -767,7 +768,7 @@ void CWidgetControl::handleLeftClick(nxgl_coord_t x, nxgl_coord_t y, CNxWidget *
/**
* Delete any widgets in the deletion queue.
*/
-
+
void CWidgetControl::processDeleteQueue(void)
{
int i = 0;
@@ -917,6 +918,25 @@ void CWidgetControl::takeGeoSem(void)
#endif
/**
+ * Take the bounds semaphore (handling signal interruptions)
+ */
+
+#ifdef CONFIG_NX_MULTIUSER
+void CWidgetControl::takeBoundsSem(void)
+{
+ // Take the bounds semaphore. Retry is an error occurs (only if
+ // the error is due to a signal interruption).
+
+ int ret;
+ do
+ {
+ ret = sem_wait(&m_boundsSem);
+ }
+ while (ret < 0 && errno == EINTR);
+}
+#endif
+
+/**
* Clear all mouse events
*/
diff --git a/NxWidgets/nxwm/include/cstartwindow.hxx b/NxWidgets/nxwm/include/cstartwindow.hxx
index 52a67fbd4..250d5068c 100644
--- a/NxWidgets/nxwm/include/cstartwindow.hxx
+++ b/NxWidgets/nxwm/include/cstartwindow.hxx
@@ -119,7 +119,6 @@ namespace NxWM
CApplicationWindow *m_window; /**< Reference to the application window */
TNxArray<struct SStartWindowSlot> m_slots; /**< List of apps in the start window */
struct nxgl_size_s m_iconSize; /**< A box big enough to hold the largest icon */
- pid_t m_taskId; /**< ID of the start window task */
/**
* This is the start window task. This function receives window events from
diff --git a/NxWidgets/nxwm/include/cwindowmessenger.hxx b/NxWidgets/nxwm/include/cwindowmessenger.hxx
index 11a48645b..a30010fd8 100644
--- a/NxWidgets/nxwm/include/cwindowmessenger.hxx
+++ b/NxWidgets/nxwm/include/cwindowmessenger.hxx
@@ -1,7 +1,7 @@
/****************************************************************************
* NxWidgets/nxwm/include/cwindowmessenger.hxx
*
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -39,12 +39,12 @@
/****************************************************************************
* Included Files
****************************************************************************/
-
+
#include <nuttx/config.h>
#include <sys/types.h>
-#include <mqueue.h>
+#include <nuttx/wqueue.h>
#include <nuttx/nx/nxtk.h>
#include <nuttx/nx/nxconsole.h>
@@ -83,9 +83,20 @@ namespace NxWM
public NXWidgets::CWidgetControl
{
private:
- mqd_t m_mqd; /**< Message queue descriptor used to commincate with the
- ** start window thread. */
-
+ /** Structure that stores data for the work queue callback. */
+
+ struct work_state_t
+ {
+ work_s work;
+ CWindowMessenger *windowMessenger;
+ void *instance;
+ };
+
+ /** Work queue callback functions */
+
+ static void inputWorkCallback(FAR void *arg);
+ static void destroyWorkCallback(FAR void *arg);
+
/**
* Handle an NX window mouse input event.
*
@@ -109,7 +120,7 @@ namespace NxWM
*
* @param arg - User provided argument (see nx_block or nxtk_block)
*/
-
+
void handleBlockedEvent(FAR void *arg);
public:
diff --git a/NxWidgets/nxwm/src/capplicationwindow.cxx b/NxWidgets/nxwm/src/capplicationwindow.cxx
index d2e044298..77d196d07 100644
--- a/NxWidgets/nxwm/src/capplicationwindow.cxx
+++ b/NxWidgets/nxwm/src/capplicationwindow.cxx
@@ -1,7 +1,7 @@
/********************************************************************************************
* NxWidgets/nxwm/src/capplicationwindow.cxx
*
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -54,6 +54,18 @@
* Pre-Processor Definitions
********************************************************************************************/
+#ifdef CONFIG_NXWM_STOP_BITMAP
+extern const struct NXWidgets::SRlePaletteBitmap CONFIG_NXWM_STOP_BITMAP;
+#else
+# define CONFIG_NXWM_STOP_BITMAP g_stopBitmap
+#endif
+
+#ifdef CONFIG_NXWM_MINIMIZE_BITMAP
+extern const struct NXWidgets::SRlePaletteBitmap CONFIG_NXWM_MINIMIZE_BITMAP;
+#else
+# define CONFIG_NXWM_MINIMIZE_BITMAP g_minimizeBitmap
+#endif
+
/********************************************************************************************
* CApplicationWindow Method Implementations
********************************************************************************************/
@@ -192,7 +204,7 @@ bool CApplicationWindow::open(void)
{
// Create STOP bitmap container
- m_stopBitmap = new NXWidgets::CRlePaletteBitmap(&g_stopBitmap);
+ m_stopBitmap = new NXWidgets::CRlePaletteBitmap(&CONFIG_NXWM_STOP_BITMAP);
if (!m_stopBitmap)
{
return false;
@@ -244,7 +256,7 @@ bool CApplicationWindow::open(void)
#ifndef CONFIG_NXWM_DISABLE_MINIMIZE
// Create MINIMIZE application bitmap container
- m_minimizeBitmap = new NXWidgets::CRlePaletteBitmap(&g_minimizeBitmap);
+ m_minimizeBitmap = new NXWidgets::CRlePaletteBitmap(&CONFIG_NXWM_MINIMIZE_BITMAP);
if (!m_minimizeBitmap)
{
return false;
@@ -375,7 +387,7 @@ void CApplicationWindow::redraw(void)
m_minimizeImage->redraw();
m_minimizeImage->setRaisesEvents(true);
}
-
+
// And finally draw the window label
m_windowLabel->enableDrawing();
@@ -406,7 +418,7 @@ void CApplicationWindow::hide(void)
m_minimizeImage->disableDrawing();
m_minimizeImage->setRaisesEvents(false);
}
-
+
// Disable the window label
m_windowLabel->disableDrawing();
diff --git a/NxWidgets/nxwm/src/cstartwindow.cxx b/NxWidgets/nxwm/src/cstartwindow.cxx
index bc7b747f8..1b56094ec 100644
--- a/NxWidgets/nxwm/src/cstartwindow.cxx
+++ b/NxWidgets/nxwm/src/cstartwindow.cxx
@@ -1,7 +1,7 @@
/********************************************************************************************
* NxWidgets/nxwm/src/cstartwindow.cxx
*
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -44,8 +44,6 @@
#include <csched>
#include <cerrno>
-#include <mqueue.h>
-
#include "cwidgetcontrol.hxx"
#include "nxwmconfig.hxx"
@@ -66,7 +64,7 @@
*/
FAR const char *NxWM::g_startWindowMqName = CONFIG_NXWM_STARTWINDOW_MQNAME;
-
+
/********************************************************************************************
* CStartWindow Method Implementations
********************************************************************************************/
@@ -89,10 +87,6 @@ CStartWindow::CStartWindow(CTaskbar *taskbar, CApplicationWindow *window)
m_taskbar = taskbar;
m_window = window;
- // The start window task is not running
-
- m_taskId = -1;
-
// Add our personalized window label
NXWidgets::CNxString myName = getName();
@@ -169,24 +163,7 @@ NXWidgets::CNxString CStartWindow::getName(void)
bool CStartWindow::run(void)
{
- // Some sanity checking
-
- if (m_taskId >= 0)
- {
- // The start window task is already running???
-
- return false;
- }
-
- // Start the start window task
-
- m_taskId = TASK_CREATE("StartWindow", CONFIG_NXWM_STARTWINDOW_PRIO,
- CONFIG_NXWM_STARTWINDOW_STACKSIZE, startWindow,
- (FAR char * const *)0);
-
- // Did we successfully start the NxConsole task?
-
- return m_taskId >= 0;
+ return true;
}
/**
@@ -195,21 +172,8 @@ bool CStartWindow::run(void)
void CStartWindow::stop(void)
{
- // Delete the start window task --- what are we doing? This should never
- // happen because the start window task is persistent!
-
- if (m_taskId >= 0)
- {
- // Call task_delete(), possibly stranding resources
-
- pid_t pid = m_taskId;
- m_taskId = -1;
-
- // Then delete the NSH task
-
- task_delete(pid);
- }
}
+
/**
* Destroy the application and free all of its resources. This method
* will initiate blocking of messages from the NX server. The server
@@ -532,7 +496,7 @@ void CStartWindow::getIconBounds(void)
void CStartWindow::removeAllApplications(void)
{
- // Stop all applications and remove them from the start window. Clearly, there
+ // Stop all applications and remove them from the start window. Clearly, there
// are some ordering issues here... On an orderly system shutdown, disconnection
// should really occur priority to deleting instances
@@ -543,7 +507,7 @@ void CStartWindow::removeAllApplications(void)
IApplicationFactory *app = m_slots.at(0).app;
// Now, delete the image and the application
-
+
delete app;
delete m_slots.at(0).image;
@@ -596,108 +560,3 @@ void CStartWindow::handleActionEvent(const NXWidgets::CWidgetEventArgs &e)
}
}
-/**
- * This is the start window task. This function receives window events from
- * the NX listener threads indirectly through this sequence:
- *
- * 1. NX listener thread receives a windows event. This may be a
- * positional change notification, a redraw request, or mouse or
- * keyboard input.
- * 2. The NX listener thread performs the callback by calling a
- * NXWidgets::CCallback method associated with the window.
- * 3. NXWidgets::CCallback calls into NXWidgets::CWidgetControl to process
- * the event.
- * 4. NXWidgets::CWidgetControl records the new state data and raises a
- * window event.
- * 5. NXWidgets::CWindowEventHandlerList will give the event to
- * NxWM::CWindowMessenger.
- * 6. NxWM::CWindowMessenger will send the a message on a well-known message
- * queue.
- * 7. This CStartWindow::startWindow task will receive and process that
- * message.
- */
-
-int CStartWindow::startWindow(int argc, char *argv[])
-{
- /* Open a well-known message queue for reading */
-
- struct mq_attr attr;
- attr.mq_maxmsg = CONFIG_NXWM_STARTWINDOW_MXMSGS;
- attr.mq_msgsize = sizeof(struct SStartWindowMessage);
- attr.mq_flags = 0;
-
- mqd_t mqd = mq_open(g_startWindowMqName, O_RDONLY|O_CREAT, 0666, &attr);
- if (mqd == (mqd_t)-1)
- {
- gdbg("ERROR: mq_open(%s) failed: %d\n", g_startWindowMqName, errno);
- return EXIT_FAILURE;
- }
-
- // Now loop forever, receiving and processing messages. Ultimately, all
- // widget driven events (button presses, etc.) are driven by this logic
- // on this thread.
-
- for (;;)
- {
- // Receive the next message
-
- struct SStartWindowMessage msg;
- ssize_t nbytes = mq_receive(mqd, &msg, sizeof(struct SStartWindowMessage), 0);
- if (nbytes < 0)
- {
- int errval = errno;
-
- // EINTR is not an error. The wait was interrupted by a signal and
- // we just need to try reading again.
-
- if (errval != EINTR)
- {
- gdbg("ERROR: mq_receive failed: %d\n", errval);
- }
- else
- {
- gdbg("mq_receive interrupted by signal\n");
- }
-
- continue;
- }
-
- gvdbg("Received msgid=%d nbytes=%d\n", msg.msgId, nbytes);
- DEBUGASSERT(nbytes = sizeof(struct SStartWindowMessage) && msg.instance);
-
- // Dispatch the message to the appropriate CWidgetControl and to the
- // appropriate CWidgetControl method
-
- switch (msg.msgId)
- {
- break;
-
- case MSGID_MOUSE_INPUT: // New mouse input is available
- case MSGID_KEYBOARD_INPUT: // New keyboard input is available
- {
- // Handle all new window input events by calling the CWidgetControl::pollEvents() method
-
- NXWidgets::CWidgetControl *control = (NXWidgets::CWidgetControl *)msg.instance;
- control->pollEvents();
- }
- break;
-
- case MSGID_DESTROY_APP: // Destroy the application
- {
- // Handle all destroy application events
-
- gdbg("Deleting app=%p\n", msg.instance);
- IApplication *app = (IApplication *)msg.instance;
- delete app;
- }
- break;
-
- case MSGID_POSITIONAL_CHANGE: // Change in window positional data (not used)
- case MSGID_REDRAW_REQUEST: // Request to redraw a portion of the window (not used)
- default:
- gdbg("ERROR: Unrecognized or unsupported msgId: %d\n", (int)msg.msgId);
- break;
- }
- }
-}
-
diff --git a/NxWidgets/nxwm/src/ctaskbar.cxx b/NxWidgets/nxwm/src/ctaskbar.cxx
index 031edbf3a..93c38ed98 100644
--- a/NxWidgets/nxwm/src/ctaskbar.cxx
+++ b/NxWidgets/nxwm/src/ctaskbar.cxx
@@ -1,7 +1,7 @@
/********************************************************************************************
* NxWidgets/nxwm/src/ctaskbar.cxx
*
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -456,11 +456,21 @@ bool CTaskbar::startApplication(IApplication *app, bool minimized)
NXWidgets::IBitmap *bitmap = app->getIcon();
- // Create a CImage instance to manage the applications icon
+ // Create a CImage instance to manage the applications icon. Assume the
+ // minimum size in case no bitmap is provided (bitmap == NULL)
+
+ int w = 1;
+ int h = 1;
+
+ if (bitmap)
+ {
+ w = bitmap->getWidth();
+ h = bitmap->getHeight();
+ }
NXWidgets::CImage *image =
- new NXWidgets::CImage(control, 0, 0, bitmap->getWidth(),
- bitmap->getHeight(), bitmap, 0);
+ new NXWidgets::CImage(control, 0, 0, w, h, bitmap, 0);
+
if (!image)
{
return false;
diff --git a/NxWidgets/nxwm/src/cwindowmessenger.cxx b/NxWidgets/nxwm/src/cwindowmessenger.cxx
index 032dd1bf2..114690838 100644
--- a/NxWidgets/nxwm/src/cwindowmessenger.cxx
+++ b/NxWidgets/nxwm/src/cwindowmessenger.cxx
@@ -1,7 +1,7 @@
/********************************************************************************************
* NxWidgets/nxwm/src/cwindowmessenger.cxx
*
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -69,20 +69,6 @@ using namespace NxWM;
CWindowMessenger::CWindowMessenger(FAR const NXWidgets::CWidgetStyle *style)
: NXWidgets::CWidgetControl(style)
{
- // Open a message queue to communicate with the start window task. We need to create
- // the message queue if it does not exist.
-
- struct mq_attr attr;
- attr.mq_maxmsg = CONFIG_NXWM_STARTWINDOW_MXMSGS;
- attr.mq_msgsize = sizeof(struct SStartWindowMessage);
- attr.mq_flags = 0;
-
- m_mqd = mq_open(g_startWindowMqName, O_WRONLY|O_CREAT, 0666, &attr);
- if (m_mqd == (mqd_t)-1)
- {
- gdbg("ERROR: mq_open(%s) failed: %d\n", g_startWindowMqName, errno);
- }
-
// Add ourself to the list of window event handlers
addWindowEventHandler(this);
@@ -97,10 +83,6 @@ CWindowMessenger::~CWindowMessenger(void)
// Remove ourself from the list of the window event handlers
removeWindowEventHandler(this);
-
- // Close the message queue
-
- (void)mq_close(m_mqd);
}
/**
@@ -120,8 +102,8 @@ void CWindowMessenger::handleMouseEvent(void)
// 3. The NX server will determine which window gets the mouse input
// and send a window event message to the NX listener thread.
// 4. The NX listener thread receives a windows event. The NX listener thread
- // which is part of CTaskBar and was created when NX server connection was
- // established). This event may be a positional change notification, a
+ // is part of CTaskBar and was created when NX server connection was
+ // established. This event may be a positional change notification, a
// redraw request, or mouse or keyboard input. In this case, mouse input.
// 5. The NX listener thread handles the message by calling nx_eventhandler().
// nx_eventhandler() dispatches the message by calling a method in the
@@ -133,20 +115,18 @@ void CWindowMessenger::handleMouseEvent(void)
// window event.
// 8. NXWidgets::CWindowEventHandlerList will give the event to this method
// NxWM::CWindowMessenger.
- // 9. This NxWM::CWindowMessenger method will send the a message on a well-
- // known message queue.
- // 10. This CStartWindow::startWindow task will receive and process that
- // message by calling CWidgetControl::pollEvents()
+ // 9. This NxWM::CWindowMessenger method will schedule an entry on the work
+ // queue.
+ // 10. The work queue callback will finally call pollEvents() to execute whatever
+ // actions the input event should trigger.
- struct SStartWindowMessage outmsg;
- outmsg.msgId = MSGID_MOUSE_INPUT;
- outmsg.instance = (FAR void *)static_cast<CWidgetControl*>(this);
+ work_state_t *state = new work_state_t;
+ state->windowMessenger = this;
- int ret = mq_send(m_mqd, &outmsg, sizeof(struct SStartWindowMessage),
- CONFIG_NXWM_STARTWINDOW_MXMPRIO);
+ int ret = work_queue(USRWORK, &state->work, &inputWorkCallback, state, 0);
if (ret < 0)
{
- gdbg("ERROR: mq_send failed: %d\n", errno);
+ gdbg("ERROR: work_queue failed: %d\n", ret);
}
}
#endif
@@ -158,41 +138,13 @@ void CWindowMessenger::handleMouseEvent(void)
#ifdef CONFIG_NX_KBD
void CWindowMessenger::handleKeyboardEvent(void)
{
- // The logic path here is tortuous but flexible:
- //
- // 1. A listener thread receives keyboard input and injects that into NX
- // via nx_kbdin.
- // 2. In the multi-user mode, this will send a message to the NX server
- // 3. The NX server will determine which window gets the keyboard input
- // and send a window event message to the NX listener thread.
- // 4. The NX listener thread receives a windows event. The NX listener thread
- // which is part of CTaskBar and was created when NX server connection was
- // established). This event may be a positional change notification, a
- // redraw request, or mouse or keyboard input. In this case, keyboard input.
- // 5. The NX listener thread handles the message by calling nx_eventhandler().
- // nx_eventhandler() dispatches the message by calling a method in the
- // NXWidgets::CCallback instance associated with the window.
- // NXWidgets::CCallback is a part of the CWidgetControl.
- // 6. NXWidgets::CCallback calls into NXWidgets::CWidgetControl to process
- // the event.
- // 7. NXWidgets::CWidgetControl records the new state data and raises a
- // window event.
- // 8. NXWidgets::CWindowEventHandlerList will give the event to this method
- // NxWM::CWindowMessenger.
- // 9. This NxWM::CWindowMessenger method will send the a message on a well-
- // known message queue.
- // 10. This CStartWindow::startWindow task will receive and process that
- // message by calling CWidgetControl::pollEvents()
-
- struct SStartWindowMessage outmsg;
- outmsg.msgId = MSGID_KEYBOARD_INPUT;
- outmsg.instance = (FAR void *)static_cast<CWidgetControl*>(this);
+ work_state_t *state = new work_state_t;
+ state->windowMessenger = this;
- int ret = mq_send(m_mqd, &outmsg, sizeof(struct SStartWindowMessage),
- CONFIG_NXWM_STARTWINDOW_MXMPRIO);
+ int ret = work_queue(USRWORK, &state->work, &inputWorkCallback, state, 0);
if (ret < 0)
{
- gdbg("ERROR: mq_send failed: %d\n", errno);
+ gdbg("ERROR: work_queue failed: %d\n", ret);
}
}
#endif
@@ -213,18 +165,40 @@ void CWindowMessenger::handleKeyboardEvent(void)
void CWindowMessenger::handleBlockedEvent(FAR void *arg)
{
- // Send a message to destroy the window isntance at a later time
+ // Send a message to destroy the window instance.
- struct SStartWindowMessage outmsg;
- outmsg.msgId = MSGID_DESTROY_APP;
- outmsg.instance = arg;
+ work_state_t *state = new work_state_t;
+ state->windowMessenger = this;
+ state->instance = arg;
- gdbg("Sending MSGID_DESTROY_APP with instance=%p\n", arg);
- int ret = mq_send(m_mqd, &outmsg, sizeof(struct SStartWindowMessage),
- CONFIG_NXWM_STARTWINDOW_MXMPRIO);
+ int ret = work_queue(USRWORK, &state->work, &destroyWorkCallback, state, 0);
if (ret < 0)
{
- gdbg("ERROR: mq_send failed: %d\n", errno);
+ gdbg("ERROR: work_queue failed: %d\n", ret);
}
}
+/** Work queue callback functions */
+
+void CWindowMessenger::inputWorkCallback(FAR void *arg)
+{
+ work_state_t *state = (work_state_t*)arg;
+ state->windowMessenger->pollEvents();
+ delete state;
+}
+
+void CWindowMessenger::destroyWorkCallback(FAR void *arg)
+{
+ work_state_t *state = (work_state_t*)arg;
+
+ // First make sure any pending input events have been handled.
+
+ state->windowMessenger->pollEvents();
+
+ // Then release the memory.
+
+ gdbg("Deleting app=%p\n", state->instance);
+ IApplication *app = (IApplication *)state->instance;
+ delete app;
+ delete state;
+}
diff --git a/apps/NxWidgets/Kconfig b/apps/NxWidgets/Kconfig
index 656399199..6f5f3e924 100644
--- a/apps/NxWidgets/Kconfig
+++ b/apps/NxWidgets/Kconfig
@@ -463,6 +463,30 @@ config NXWM_BACKGROUND_IMAGE
The name of the image to use in the background window. Default:
NXWidgets::g_nuttxBitmap
+comment "Application Window Configuration"
+
+config NXWM_CUSTOM_APPWINDOW_ICONS
+ bool "Custom Start/Stop Application Window Icons"
+ default n
+ ---help---
+ Select to override the default Application Window Stop and Minimize Icons.
+
+if NXWM_CUSTOM_APPWINDOW_ICONS
+
+config NXWM_STOP_BITMAP
+ string "Stop Icon"
+ default "NxWM::g_stopBitmap"
+ ---help---
+ The glyph to use as the Stop icon. Default: NxWM::g_stopBitmap
+
+config NXWM_MINIMIZE_BITMAP
+ string "Minimize Icon"
+ default "NxWM::g_minimizeBitmap"
+ ---help---
+ The glyph to use as the Minimize icon. Default: NxWM::g_minimizeBitmap
+
+endif
+
comment "Start Window Configuration"
comment "Horizontal and vertical spacing of icons in the task bar"
diff --git a/nuttx/tools/cfgdefine.c b/nuttx/tools/cfgdefine.c
index f026a186f..ca503c629 100644
--- a/nuttx/tools/cfgdefine.c
+++ b/nuttx/tools/cfgdefine.c
@@ -1,7 +1,7 @@
/****************************************************************************
* tools/cfgdefine.c
*
- * Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -69,6 +69,8 @@ static const char *dequote_list[] =
/* NxWidgets/NxWM */
"CONFIG_NXWM_BACKGROUND_IMAGE", /* Name of bitmap image class */
+ "CONFIG_NXWM_STOP_BITMAP", /* Name of bitmap image class */
+ "CONFIG_NXWM_MINIMIZE_BITMAP", /* Name of bitmap image class */
"CONFIG_NXWM_STARTWINDOW_ICON", /* Name of bitmap image class */
"CONFIG_NXWM_NXCONSOLE_ICON", /* Name of bitmap image class */
"CONFIG_NXWM_CALIBRATION_ICON", /* Name of bitmap image class */
@@ -82,7 +84,7 @@ static const char *dequote_list[] =
****************************************************************************/
/* Skip over any spaces */
-
+
static char *skip_space(char *ptr)
{
while (*ptr && isspace((int)*ptr)) ptr++;
@@ -184,7 +186,7 @@ static void parse_line(char *ptr, char **varname, char **varval)
/* The variable value should follow =, perhaps separated by some
* white space.
*/
-
+
ptr = skip_space(ptr + 1);
if (*ptr)
{
diff --git a/nuttx/tools/cfgparser.c b/nuttx/tools/cfgparser.c
index ac25bd26b..439dcb9d5 100644
--- a/nuttx/tools/cfgparser.c
+++ b/nuttx/tools/cfgparser.c
@@ -1,7 +1,7 @@
/****************************************************************************
* tools/cfgpaser.c
*
- * Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -62,7 +62,7 @@ char line[LINESIZE+1];
****************************************************************************/
/* Skip over any spaces */
-
+
static char *skip_space(char *ptr)
{
while (*ptr && isspace((int)*ptr)) ptr++;
@@ -164,7 +164,7 @@ static void parse_line(char *ptr, char **varname, char **varval)
/* The variable value should follow =, perhaps separated by some
* white space.
*/
-
+
ptr = skip_space(ptr + 1);
if (*ptr)
{
@@ -287,7 +287,7 @@ struct variable_s *find_variable(const char *varname, struct variable_s *list)
{
return list;
}
-
+
list = list->flink;
}