summaryrefslogtreecommitdiff
path: root/NxWidgets/UnitTests
diff options
context:
space:
mode:
Diffstat (limited to 'NxWidgets/UnitTests')
-rw-r--r--NxWidgets/UnitTests/CButton/Makefile172
-rw-r--r--NxWidgets/UnitTests/CButton/cbuttontest.cxx325
-rw-r--r--NxWidgets/UnitTests/CButton/cbuttontest.hxx167
-rw-r--r--NxWidgets/UnitTests/CButton/main.cxx155
-rw-r--r--NxWidgets/UnitTests/CButtonArray/Makefile172
-rw-r--r--NxWidgets/UnitTests/CButtonArray/cbuttonarraytest.cxx301
-rw-r--r--NxWidgets/UnitTests/CButtonArray/cbuttonarraytest.hxx182
-rw-r--r--NxWidgets/UnitTests/CButtonArray/main.cxx327
-rw-r--r--NxWidgets/UnitTests/CCheckBox/Makefile172
-rw-r--r--NxWidgets/UnitTests/CCheckBox/ccheckboxtest.cxx297
-rw-r--r--NxWidgets/UnitTests/CCheckBox/ccheckboxtest.hxx152
-rw-r--r--NxWidgets/UnitTests/CCheckBox/main.cxx209
-rw-r--r--NxWidgets/UnitTests/CGlyphButton/Makefile172
-rw-r--r--NxWidgets/UnitTests/CGlyphButton/cglyphbuttontest.cxx307
-rw-r--r--NxWidgets/UnitTests/CGlyphButton/cglyphbuttontest.hxx182
-rw-r--r--NxWidgets/UnitTests/CGlyphButton/main.cxx225
-rw-r--r--NxWidgets/UnitTests/CImage/Makefile172
-rw-r--r--NxWidgets/UnitTests/CImage/cimagetest.cxx240
-rw-r--r--NxWidgets/UnitTests/CImage/cimagetest.hxx150
-rw-r--r--NxWidgets/UnitTests/CImage/main.cxx222
-rw-r--r--NxWidgets/UnitTests/CKeypad/Makefile172
-rw-r--r--NxWidgets/UnitTests/CKeypad/ckeypadtest.cxx458
-rw-r--r--NxWidgets/UnitTests/CKeypad/ckeypadtest.hxx192
-rw-r--r--NxWidgets/UnitTests/CKeypad/main.cxx274
-rw-r--r--NxWidgets/UnitTests/CLabel/Makefile172
-rw-r--r--NxWidgets/UnitTests/CLabel/clabeltest.cxx263
-rw-r--r--NxWidgets/UnitTests/CLabel/clabeltest.hxx148
-rw-r--r--NxWidgets/UnitTests/CLabel/main.cxx130
-rw-r--r--NxWidgets/UnitTests/CLatchButton/Makefile172
-rw-r--r--NxWidgets/UnitTests/CLatchButton/clatchbuttontest.cxx321
-rw-r--r--NxWidgets/UnitTests/CLatchButton/clatchbuttontest.hxx165
-rw-r--r--NxWidgets/UnitTests/CLatchButton/main.cxx199
-rw-r--r--NxWidgets/UnitTests/CLatchButtonArray/Makefile172
-rw-r--r--NxWidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.cxx301
-rw-r--r--NxWidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.hxx182
-rw-r--r--NxWidgets/UnitTests/CLatchButtonArray/main.cxx301
-rw-r--r--NxWidgets/UnitTests/CListBox/Makefile172
-rw-r--r--NxWidgets/UnitTests/CListBox/clistboxtest.cxx224
-rw-r--r--NxWidgets/UnitTests/CListBox/clistboxtest.hxx147
-rw-r--r--NxWidgets/UnitTests/CListBox/main.cxx327
-rw-r--r--NxWidgets/UnitTests/CProgressBar/Makefile172
-rw-r--r--NxWidgets/UnitTests/CProgressBar/cprogressbartest.cxx224
-rw-r--r--NxWidgets/UnitTests/CProgressBar/cprogressbartest.hxx147
-rw-r--r--NxWidgets/UnitTests/CProgressBar/main.cxx238
-rw-r--r--NxWidgets/UnitTests/CRadioButton/Makefile172
-rw-r--r--NxWidgets/UnitTests/CRadioButton/cradiobuttontest.cxx305
-rw-r--r--NxWidgets/UnitTests/CRadioButton/cradiobuttontest.hxx162
-rw-r--r--NxWidgets/UnitTests/CRadioButton/main.cxx238
-rw-r--r--NxWidgets/UnitTests/CScrollbarHorizontal/Makefile172
-rw-r--r--NxWidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.cxx225
-rw-r--r--NxWidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.hxx147
-rw-r--r--NxWidgets/UnitTests/CScrollbarHorizontal/main.cxx231
-rw-r--r--NxWidgets/UnitTests/CScrollbarVertical/Makefile172
-rw-r--r--NxWidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.cxx225
-rw-r--r--NxWidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.hxx147
-rw-r--r--NxWidgets/UnitTests/CScrollbarVertical/main.cxx231
-rw-r--r--NxWidgets/UnitTests/CSliderHorizonal/Makefile172
-rw-r--r--NxWidgets/UnitTests/CSliderHorizonal/csliderhorizontaltest.cxx224
-rw-r--r--NxWidgets/UnitTests/CSliderHorizonal/csliderhorizontaltest.hxx147
-rw-r--r--NxWidgets/UnitTests/CSliderHorizonal/main.cxx231
-rw-r--r--NxWidgets/UnitTests/CSliderVertical/Makefile172
-rw-r--r--NxWidgets/UnitTests/CSliderVertical/csliderverticaltest.cxx225
-rw-r--r--NxWidgets/UnitTests/CSliderVertical/csliderverticaltest.hxx147
-rw-r--r--NxWidgets/UnitTests/CSliderVertical/main.cxx231
-rw-r--r--NxWidgets/UnitTests/CTextBox/Makefile172
-rw-r--r--NxWidgets/UnitTests/CTextBox/ctextboxtest.cxx287
-rw-r--r--NxWidgets/UnitTests/CTextBox/ctextboxtest.hxx152
-rw-r--r--NxWidgets/UnitTests/CTextBox/main.cxx141
-rw-r--r--NxWidgets/UnitTests/README.txt394
-rwxr-xr-xNxWidgets/UnitTests/tools/addobjs.sh141
-rwxr-xr-xNxWidgets/UnitTests/tools/install.sh152
71 files changed, 14989 insertions, 0 deletions
diff --git a/NxWidgets/UnitTests/CButton/Makefile b/NxWidgets/UnitTests/CButton/Makefile
new file mode 100644
index 000000000..fbb7d815b
--- /dev/null
+++ b/NxWidgets/UnitTests/CButton/Makefile
@@ -0,0 +1,172 @@
+#################################################################################
+# NxWidgets/Unitests/CButton/Makefile
+#
+# Copyright (C) 2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+# me be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#################################################################################
+
+TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'}
+
+-include $(TOPDIR)/.config
+-include $(TOPDIR)/Make.defs
+include $(APPDIR)/Make.defs
+
+# Add the path to the NXWidget include directory to the CFLAGS
+
+NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets"
+NXWIDGETS_INC="$(NXWIDGETS_DIR)/include"
+NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)"
+
+INCDIR=$(TOPDIR)/tools/incdir.sh
+ifeq ($(WINTOOL),y)
+ CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"}
+else
+ CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"}
+endif
+
+# Get the path to the archiver tool
+
+TESTTOOL_DIR="$(TESTDIR)/../tools"
+ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh
+
+# Hello, World! C++ Example
+
+ASRCS =
+CSRCS =
+CXXSRCS = main.cxx cbuttontest.cxx
+
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+COBJS = $(CSRCS:.c=$(OBJEXT))
+CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS)
+OBJS = $(AOBJS) $(COBJS) $(CXXOBJS)
+
+POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)"
+ifeq ($(WINTOOL),y)
+ BIN = "${shell cygpath -w $(POSIX_BIN)}"
+else
+ BIN = $(POSIX_BIN)
+endif
+
+ROOTDEPPATH = --dep-path .
+
+# helloxx built-in application info
+
+APPNAME = cbutton
+PRIORITY = SCHED_PRIORITY_DEFAULT
+STACKSIZE = 2048
+
+# Common build
+
+VPATH =
+
+all: .built
+.PHONY: clean depend context disclean chkcxx chklib
+
+# Object file creation targets
+
+$(AOBJS): %$(OBJEXT): %.S
+ $(call ASSEMBLE, $<, $@)
+
+$(COBJS): %$(OBJEXT): %.c
+ $(call COMPILE, $<, $@)
+
+$(CXXOBJS): %$(OBJEXT): %.cxx
+ $(call COMPILEXX, $<, $@)
+
+# Verify that the NuttX configuration is setup to support C++
+
+chkcxx:
+ifneq ($(CONFIG_HAVE_CXX),y)
+ @echo ""
+ @echo "In order to use this example, you toolchain must support must"
+ @echo ""
+ @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support"
+ @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file"
+ @echo " of the configuration that you are using."
+ @echo ""
+ @exit 1
+endif
+
+# Verify that the NXWidget library has been built
+
+chklib:
+ @( \
+ if [ ! -e "$(NXWIDGETS_LIB)" ]; then \
+ echo "$(NXWIDGETS_LIB) does not exist."; \
+ echo "Please go to $(NXWIDGETS_DIR)"; \
+ echo "and rebuild the library"; \
+ exit 1; \
+ fi; \
+ )
+
+# Library creation targets
+
+$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work.
+
+.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB)
+ @( for obj in $(OBJS) ; do \
+ $(call ARCHIVE, $(BIN), $${obj}); \
+ done ; )
+ifeq ($(WINTOOL),y)
+ @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+else
+ @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+endif
+ @touch .built
+
+# Standard housekeeping targets
+
+.context:
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+ $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
+endif
+ @touch $@
+
+context: .context
+
+.depend: Makefile $(SRCS)
+ @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep
+ @touch $@
+
+depend: .depend
+
+clean:
+ @rm -f *.o *~ .*.swp .built
+ $(call CLEAN)
+
+distclean: clean
+ @rm -f Make.dep .depend
+
+-include Make.dep
diff --git a/NxWidgets/UnitTests/CButton/cbuttontest.cxx b/NxWidgets/UnitTests/CButton/cbuttontest.cxx
new file mode 100644
index 000000000..49f32f551
--- /dev/null
+++ b/NxWidgets/UnitTests/CButton/cbuttontest.cxx
@@ -0,0 +1,325 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CButton/cbuttontest.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cerrno>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+#include <nuttx/nx/nxfonts.h>
+
+#include "nxconfig.hxx"
+#include "cbuttontest.hxx"
+#include "cbgwindow.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// CButtonTest Method Implementations
+/////////////////////////////////////////////////////////////////////////////
+
+// CButtonTest Constructor
+
+CButtonTest::CButtonTest()
+{
+ m_bgWindow = (CBgWindow *)NULL;
+ m_nxFont = (CNxFont *)NULL;
+ m_text = (CNxString *)NULL;
+}
+
+// CButtonTest Descriptor
+
+CButtonTest::~CButtonTest()
+{
+ disconnect();
+}
+
+// Connect to the NX server
+
+bool CButtonTest::connect(void)
+{
+ // Connect to the server
+
+ bool nxConnected = CNxServer::connect();
+ if (nxConnected)
+ {
+ // Create the default font instance
+
+ m_nxFont = new CNxFont(NXFONT_DEFAULT,
+ CONFIG_NXWIDGETS_DEFAULT_FONTCOLOR,
+ CONFIG_NXWIDGETS_TRANSPARENT_COLOR);
+ if (!m_nxFont)
+ {
+ printf("CButtonTest::connect: Failed to create the default font\n");
+ }
+
+ // Set the background color
+
+ if (!setBackgroundColor(CONFIG_CBUTTONTEST_BGCOLOR))
+ {
+ printf("CButtonTest::connect: setBackgroundColor failed\n");
+ }
+ }
+
+ return nxConnected;
+}
+
+// Disconnect from the NX server
+
+void CButtonTest::disconnect(void)
+{
+ // Close the window
+
+ if (m_bgWindow)
+ {
+ delete m_bgWindow;
+ }
+
+ // Free the display string
+
+ if (m_text)
+ {
+ delete m_text;
+ m_text = (CNxString *)NULL;
+ }
+
+ // Free the default font
+
+ if (m_nxFont)
+ {
+ delete m_nxFont;
+ m_nxFont = (CNxFont *)NULL;
+ }
+
+ // And disconnect from the server
+
+ CNxServer::disconnect();
+}
+
+// Create the background window instance. This function illustrates
+// the basic steps to instantiate any window:
+//
+// 1) Create a dumb CWigetControl instance
+// 2) Pass the dumb CWidgetControl instance to the window constructor
+// that inherits from INxWindow. This will "smarten" the CWidgetControl
+// instance with some window knowlede
+// 3) Call the open() method on the window to display the window.
+// 4) After that, the fully smartened CWidgetControl instance can
+// be used to generate additional widgets by passing it to the
+// widget constructor
+
+bool CButtonTest::createWindow(void)
+{
+ // Initialize the widget control using the default style
+
+ m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL);
+
+ // Get an (uninitialized) instance of the background window as a class
+ // that derives from INxWindow.
+
+ m_bgWindow = getBgWindow(m_widgetControl);
+ if (!m_bgWindow)
+ {
+ printf("CButtonTest::createGraphics: Failed to create CBgWindow instance\n");
+ delete m_widgetControl;
+ return false;
+ }
+
+ // Open (and initialize) the window
+
+ bool success = m_bgWindow->open();
+ if (!success)
+ {
+ printf("CButtonTest::createGraphics: Failed to open background window\n");
+ delete m_bgWindow;
+ m_bgWindow = (CBgWindow*)0;
+ return false;
+ }
+
+ return true;
+}
+
+// Create a CButton instance
+
+CButton *CButtonTest::createButton(FAR const char *text)
+{
+ // Get the width of the display
+
+ struct nxgl_size_s windowSize;
+ if (!m_bgWindow->getSize(&windowSize))
+ {
+ printf("CButtonTest::createGraphics: Failed to get window size\n");
+ return (CButton *)NULL;
+ }
+
+ // Create a CNxString instance to contain the C string
+
+ m_text = new CNxString(text);
+
+ // Get the height and width of the text display area
+
+ nxgl_coord_t stringWidth = m_nxFont->getStringWidth(*m_text);
+ nxgl_coord_t stringHeight = (nxgl_coord_t)m_nxFont->getHeight();
+
+ // The default CButton has borders enabled with thickness of the border
+ // width. Add twice the thickness of the borderto the width and height. (We
+ // could let CButton do this for us by calling CButton::getPreferredDimensions())
+
+ stringWidth += 2 * 1;
+ stringHeight += 2 * 1;
+
+ // Pick an X/Y position such that the button will be centered in the display
+
+ nxgl_coord_t buttonX;
+ if (stringWidth >= windowSize.w)
+ {
+ buttonX = 0;
+ }
+ else
+ {
+ buttonX = (windowSize.w - stringWidth) >> 1;
+ }
+
+ nxgl_coord_t buttonY;
+ if (stringHeight >= windowSize.h)
+ {
+ buttonY = 0;
+ }
+ else
+ {
+ buttonY = (windowSize.h - stringHeight) >> 1;
+ }
+
+ // Save the center position of the button for use by click and release
+
+ m_center.x = buttonX + (stringWidth >> 1);
+ m_center.y = buttonY + (stringHeight >> 1);
+
+ // Now we have enough information to create the button
+
+ return new CButton(m_widgetControl, buttonX, buttonY, stringWidth, stringHeight, *m_text);
+}
+
+// Draw the button
+
+void CButtonTest::showButton(CButton *button)
+{
+ button->enable(); // Un-necessary, the widget is enabled by default
+ button->enableDrawing();
+ button->redraw();
+}
+
+// Perform a simulated mouse click on the button. This method injects
+// the mouse click through the NX heirarchy just as would real mouse
+// hardward.
+
+void CButtonTest::click(void)
+{
+ // nx_mousein is meant to be called by mouse handling software.
+ // Here we just inject a left-button click directly in the center of
+ // the button.
+
+ // First, get the server handle. Graphics software will never care
+ // about the server handle. Here we need it to get access to the
+ // low-level mouse interface
+
+ NXHANDLE handle = getServer();
+
+ // Then inject the mouse click
+
+ (void)nx_mousein(handle, m_center.x, m_center.y, NX_MOUSE_LEFTBUTTON);
+}
+
+// The counterpart to click. This simulates a button release through
+// the same mechanism.
+
+void CButtonTest::release(void)
+{
+ // nx_mousein is meant to be called by mouse handling software.
+ // Here we just inject a left-button click directly in the center of
+ // the button.
+
+ // First, get the server handle. Graphics software will never care
+ // about the server handle. Here we need it to get access to the
+ // low-level mouse interface
+
+ NXHANDLE handle = getServer();
+
+ // Then inject the mouse click
+
+ (void)nx_mousein(handle, m_center.x, m_center.y, NX_MOUSE_NOBUTTONS);
+}
+
+// Widget events are normally handled in a modal loop (by calling goModal()).
+// However, for this case we know when there should be press and release
+// events so we don't have to poll. We can just perform a one pass poll
+// then check if the event was processed corredly.
+
+bool CButtonTest::poll(CButton *button)
+{
+ // Poll for mouse events
+
+ m_widgetControl->pollEvents(button);
+
+ // And return the button clicked state
+
+ return button->isClicked();
+}
+
diff --git a/NxWidgets/UnitTests/CButton/cbuttontest.hxx b/NxWidgets/UnitTests/CButton/cbuttontest.hxx
new file mode 100644
index 000000000..f125af6b3
--- /dev/null
+++ b/NxWidgets/UnitTests/CButton/cbuttontest.hxx
@@ -0,0 +1,167 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CButton/cbuttontest.hxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef __UNITTESTS_CBUTTON_CBUTTONTEST_HXX
+#define __UNITTESTS_CBUTTON_CBUTTONTEST_HXX
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <semaphore.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "nxconfig.hxx"
+#include "cwidgetcontrol.hxx"
+#include "ccallback.hxx"
+#include "cbgwindow.hxx"
+#include "cnxserver.hxx"
+#include "cnxfont.hxx"
+#include "cnxstring.hxx"
+#include "cbutton.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+// Configuration ////////////////////////////////////////////////////////////
+
+#ifndef CONFIG_HAVE_CXX
+# error "CONFIG_HAVE_CXX must be defined"
+#endif
+
+#ifndef CONFIG_CBUTTONTEST_BGCOLOR
+# define CONFIG_CBUTTONTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR
+#endif
+
+#ifndef CONFIG_CBUTTONTEST_FONTCOLOR
+# define CONFIG_CBUTTONTEST_FONTCOLOR CONFIG_NXWIDGETS_DEFAULT_FONTCOLOR
+#endif
+
+// What is the entry point called?
+
+#ifdef CONFIG_NSH_BUILTIN_APPS
+# define MAIN_NAME cbutton_main
+# define MAIN_STRING "cbutton_main: "
+#else
+# define MAIN_NAME user_start
+# define MAIN_STRING "user_start: "
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Classes
+/////////////////////////////////////////////////////////////////////////////
+
+using namespace NXWidgets;
+
+class CButtonTest : public CNxServer
+{
+private:
+ CWidgetControl *m_widgetControl; // The controlling widget for the window
+ CNxFont *m_nxFont; // Default font
+ CBgWindow *m_bgWindow; // Background window instance
+ CNxString *m_text; // The button string
+ struct nxgl_point_s m_center; // X, Y position the center of the button
+
+public:
+ // Constructor/destructors
+
+ CButtonTest();
+ ~CButtonTest();
+
+ // Initializer/unitializer. These methods encapsulate the basic steps for
+ // starting and stopping the NX server
+
+ bool connect(void);
+ void disconnect(void);
+
+ // Create a window. This method provides the general operations for
+ // creating a window that you can draw within.
+ //
+ // Those general operations are:
+ // 1) Create a dumb CWigetControl instance
+ // 2) Pass the dumb CWidgetControl instance to the window constructor
+ // that inherits from INxWindow. This will "smarten" the CWidgetControl
+ // instance with some window knowlede
+ // 3) Call the open() method on the window to display the window.
+ // 4) After that, the fully smartened CWidgetControl instance can
+ // be used to generate additional widgets by passing it to the
+ // widget constructor
+
+ bool createWindow(void);
+
+ // Create a CButton instance. This method will show you how to create
+ // a CButton widget
+
+ CButton *createButton(FAR const char *text);
+
+ // Draw the button. This method illustrates how to draw the CButton widget.
+
+ void showButton(CButton *button);
+
+ // Perform a simulated mouse click on the button. This method injects
+ // the mouse click through the NX heirarchy just as would real mouse
+ // hardward.
+
+ void click(void);
+
+ // The counterpart to click. This simulates a button release through
+ // the same mechanism.
+
+ void release(void);
+
+ // Widget events are normally handled in a model loop (by calling goModel()).
+ // However, for this case we know when there should be press and release
+ // events so we don't have to poll. We can just perform a one pass poll
+ // then check if the event was processed corredly.
+
+ bool poll(CButton *button);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+
+#endif // __UNITTESTS_CBUTTON_CBUTTONTEST_HXX
diff --git a/NxWidgets/UnitTests/CButton/main.cxx b/NxWidgets/UnitTests/CButton/main.cxx
new file mode 100644
index 000000000..13e9099d9
--- /dev/null
+++ b/NxWidgets/UnitTests/CButton/main.cxx
@@ -0,0 +1,155 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CButton/main.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <unistd.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "cbuttontest.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+static const char g_pushme[] = "Push Me";
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+// Suppress name-mangling
+
+extern "C" int MAIN_NAME(int argc, char *argv[]);
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// user_start/nxheaders_main
+/////////////////////////////////////////////////////////////////////////////
+
+int MAIN_NAME(int argc, char *argv[])
+{
+ // Create an instance of the font test
+
+ printf(MAIN_STRING "Create CButtonTest instance\n");
+ CButtonTest *test = new CButtonTest();
+
+ // Connect the NX server
+
+ printf(MAIN_STRING "Connect the CButtonTest instance to the NX server\n");
+ if (!test->connect())
+ {
+ printf(MAIN_STRING "Failed to connect the CButtonTest instance to the NX server\n");
+ delete test;
+ return 1;
+ }
+
+ // Create a window to draw into
+
+ printf(MAIN_STRING "Create a Window\n");
+ if (!test->createWindow())
+ {
+ printf(MAIN_STRING "Failed to create a window\n");
+ delete test;
+ return 1;
+ }
+
+ // Create a CButton instance
+
+ CButton *button = test->createButton(g_pushme);
+ if (!button)
+ {
+ printf(MAIN_STRING "Failed to create a button\n");
+ delete test;
+ return 1;
+ }
+
+ // Show the button
+
+ printf(MAIN_STRING "Show the button\n");
+ test->showButton(button);
+
+ // Wait two seconds, then perform a simulated mouse click on the button
+
+ sleep(2);
+ printf(MAIN_STRING "Click the button\n");
+ test->click();
+
+ // Poll for the mouse click event (of course this can hang if something fails)
+
+ bool clicked = test->poll(button);
+ printf(MAIN_STRING "Button is %s\n", clicked ? "clicked" : "released");
+
+ // Wait a second, then release the mouse buttone
+
+ sleep(1);
+ test->release();
+
+ // Poll for the mouse release event (of course this can hang if something fails)
+
+ clicked = test->poll(button);
+ printf(MAIN_STRING "Button is %s\n", clicked ? "clicked" : "released");
+
+ // Wait a few more seconds so that the tester can ponder the result
+
+ sleep(3);
+
+ // Clean up and exit
+
+ printf(MAIN_STRING "Clean-up and exit\n");
+ delete button;
+ delete test;
+ return 0;
+}
+
diff --git a/NxWidgets/UnitTests/CButtonArray/Makefile b/NxWidgets/UnitTests/CButtonArray/Makefile
new file mode 100644
index 000000000..6bb67424c
--- /dev/null
+++ b/NxWidgets/UnitTests/CButtonArray/Makefile
@@ -0,0 +1,172 @@
+#################################################################################
+# NxWidgets/UnitTests/CButtonArray/Makefile
+#
+# Copyright (C) 2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+# me be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#################################################################################
+
+TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'}
+
+-include $(TOPDIR)/.config
+-include $(TOPDIR)/Make.defs
+include $(APPDIR)/Make.defs
+
+# Add the path to the NXWidget include directory to the CFLAGS
+
+NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets"
+NXWIDGETS_INC="$(NXWIDGETS_DIR)/include"
+NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)"
+
+INCDIR=$(TOPDIR)/tools/incdir.sh
+ifeq ($(WINTOOL),y)
+ CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"}
+else
+ CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"}
+endif
+
+# Get the path to the archiver tool
+
+TESTTOOL_DIR="$(TESTDIR)/../tools"
+ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh
+
+# Hello, World! C++ Example
+
+ASRCS =
+CSRCS =
+CXXSRCS = main.cxx cbuttonarraytest.cxx
+
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+COBJS = $(CSRCS:.c=$(OBJEXT))
+CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS)
+OBJS = $(AOBJS) $(COBJS) $(CXXOBJS)
+
+POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)"
+ifeq ($(WINTOOL),y)
+ BIN = "${shell cygpath -w $(POSIX_BIN)}"
+else
+ BIN = $(POSIX_BIN)
+endif
+
+ROOTDEPPATH = --dep-path .
+
+# helloxx built-in application info
+
+APPNAME = cbuttonarray
+PRIORITY = SCHED_PRIORITY_DEFAULT
+STACKSIZE = 2048
+
+# Common build
+
+VPATH =
+
+all: .built
+.PHONY: clean depend context disclean chkcxx chklib
+
+# Object file creation targets
+
+$(AOBJS): %$(OBJEXT): %.S
+ $(call ASSEMBLE, $<, $@)
+
+$(COBJS): %$(OBJEXT): %.c
+ $(call COMPILE, $<, $@)
+
+$(CXXOBJS): %$(OBJEXT): %.cxx
+ $(call COMPILEXX, $<, $@)
+
+# Verify that the NuttX configuration is setup to support C++
+
+chkcxx:
+ifneq ($(CONFIG_HAVE_CXX),y)
+ @echo ""
+ @echo "In order to use this example, you toolchain must support must"
+ @echo ""
+ @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support"
+ @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file"
+ @echo " of the configuration that you are using."
+ @echo ""
+ @exit 1
+endif
+
+# Verify that the NXWidget library has been built
+
+chklib:
+ @( \
+ if [ ! -e "$(NXWIDGETS_LIB)" ]; then \
+ echo "$(NXWIDGETS_LIB) does not exist."; \
+ echo "Please go to $(NXWIDGETS_DIR)"; \
+ echo "and rebuild the library"; \
+ exit 1; \
+ fi; \
+ )
+
+# Library creation targets
+
+$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work.
+
+.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB)
+ @( for obj in $(OBJS) ; do \
+ $(call ARCHIVE, $(BIN), $${obj}); \
+ done ; )
+ifeq ($(WINTOOL),y)
+ @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+else
+ @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+endif
+ @touch .built
+
+# Standard housekeeping targets
+
+.context:
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+ $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
+endif
+ @touch $@
+
+context: .context
+
+.depend: Makefile $(SRCS)
+ @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep
+ @touch $@
+
+depend: .depend
+
+clean:
+ @rm -f *.o *~ .*.swp .built
+ $(call CLEAN)
+
+distclean: clean
+ @rm -f Make.dep .depend
+
+-include Make.dep
diff --git a/NxWidgets/UnitTests/CButtonArray/cbuttonarraytest.cxx b/NxWidgets/UnitTests/CButtonArray/cbuttonarraytest.cxx
new file mode 100644
index 000000000..4e4f4487f
--- /dev/null
+++ b/NxWidgets/UnitTests/CButtonArray/cbuttonarraytest.cxx
@@ -0,0 +1,301 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CButtonArray/cbuttonarraytest.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cerrno>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+#include <nuttx/nx/nxfonts.h>
+
+#include "nxconfig.hxx"
+#include "cbuttonarraytest.hxx"
+#include "cbgwindow.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// CButtonArrayTest Method Implementations
+/////////////////////////////////////////////////////////////////////////////
+
+// CButtonArrayTest Constructor
+
+CButtonArrayTest::CButtonArrayTest()
+{
+ m_widgetControl = (CWidgetControl *)NULL;
+ m_bgWindow = (CBgWindow *)NULL;
+}
+
+// CButtonArrayTest Descriptor
+
+CButtonArrayTest::~CButtonArrayTest()
+{
+ disconnect();
+}
+
+// Connect to the NX server
+
+bool CButtonArrayTest::connect(void)
+{
+ // Connect to the server
+
+ bool nxConnected = CNxServer::connect();
+ if (nxConnected)
+ {
+ // Set the background color
+
+ if (!setBackgroundColor(CONFIG_CBUTTONARRAYTEST_BGCOLOR))
+ {
+ message("CButtonArrayTest::connect: setBackgroundColor failed\n");
+ }
+ }
+
+ return nxConnected;
+}
+
+// Disconnect from the NX server
+
+void CButtonArrayTest::disconnect(void)
+{
+ // Close the window
+
+ if (m_bgWindow)
+ {
+ delete m_bgWindow;
+ }
+
+ // Destroy the widget control
+
+ if (m_widgetControl)
+ {
+ delete m_widgetControl;
+ }
+
+ // And disconnect from the server
+
+ CNxServer::disconnect();
+}
+
+// Create the background window instance. This function illustrates
+// the basic steps to instantiate any window:
+//
+// 1) Create a dumb CWigetControl instance
+// 2) Pass the dumb CWidgetControl instance to the window constructor
+// that inherits from INxWindow. This will "smarten" the CWidgetControl
+// instance with some window knowlede
+// 3) Call the open() method on the window to display the window.
+// 4) After that, the fully smartened CWidgetControl instance can
+// be used to generate additional widgets by passing it to the
+// widget constructor
+
+bool CButtonArrayTest::createWindow(void)
+{
+ // Initialize the widget control using the default style
+
+ m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL);
+
+ // Get an (uninitialized) instance of the background window as a class
+ // that derives from INxWindow.
+
+ m_bgWindow = getBgWindow(m_widgetControl);
+ if (!m_bgWindow)
+ {
+ message("CButtonArrayTest::createGraphics: Failed to create CBgWindow instance\n");
+ delete m_widgetControl;
+ return false;
+ }
+
+ // Open (and initialize) the window
+
+ bool success = m_bgWindow->open();
+ if (!success)
+ {
+ message("CButtonArrayTest::createGraphics: Failed to open background window\n");
+ delete m_bgWindow;
+ m_bgWindow = (CBgWindow*)0;
+ return false;
+ }
+
+ return true;
+}
+
+// Create a CButtonArray instance
+
+CButtonArray *CButtonArrayTest::createButtonArray(void)
+{
+ // Get the width of the display
+
+ struct nxgl_size_s windowSize;
+ if (!m_bgWindow->getSize(&windowSize))
+ {
+ message("CButtonArrayTest::createGraphics: Failed to get window size\n");
+ return (CButtonArray *)NULL;
+ }
+
+ // Pick an X/Y position such that the button array will be centered in the display
+
+ nxgl_coord_t buttonArrayX;
+ if (BUTTONARRAY_WIDTH >= windowSize.w)
+ {
+ buttonArrayX = 0;
+ }
+ else
+ {
+ buttonArrayX = (windowSize.w - BUTTONARRAY_WIDTH) >> 1;
+ }
+
+ nxgl_coord_t buttonArrayY;
+ if (BUTTONARRAY_HEIGHT >= windowSize.h)
+ {
+ buttonArrayY = 0;
+ }
+ else
+ {
+ buttonArrayY = (windowSize.h - BUTTONARRAY_HEIGHT) >> 1;
+ }
+
+ // Now we have enough information to create the button array
+
+ return new CButtonArray(m_widgetControl,
+ buttonArrayX, buttonArrayY,
+ BUTTONARRAY_NCOLUMNS, BUTTONARRAY_NROWS,
+ BUTTONARRAY_BUTTONWIDTH, BUTTONARRAY_BUTTONHEIGHT);
+}
+
+// Draw the button array
+
+void CButtonArrayTest::showButton(CButtonArray *buttonArray)
+{
+ buttonArray->enable(); // Un-necessary, the widget is enabled by default
+ buttonArray->enableDrawing();
+ buttonArray->redraw();
+}
+
+// Perform a simulated mouse click on a button in the array. This method injects
+// the mouse click through the NX heirarchy just as would real mouse
+// hardward.
+
+void CButtonArrayTest::click(CButtonArray *buttonArray, int column, int row)
+{
+ // nx_mousein is meant to be called by mouse handling software.
+ // Here we just inject a left-button click directly in the center of
+ // the selected button.
+
+ // First, get the server handle. Graphics software will never care
+ // about the server handle. Here we need it to get access to the
+ // low-level mouse interface
+
+ NXHANDLE handle = getServer();
+
+ // The the coorinates of the center of the button
+
+ nxgl_coord_t buttonX = buttonArray->getX() +
+ column * BUTTONARRAY_BUTTONWIDTH +
+ BUTTONARRAY_BUTTONWIDTH/2;
+ nxgl_coord_t buttonY = buttonArray->getY() +
+ row * BUTTONARRAY_BUTTONHEIGHT +
+ BUTTONARRAY_BUTTONHEIGHT/2;
+
+ // Then inject the mouse click
+
+ (void)nx_mousein(handle, buttonX, buttonY, NX_MOUSE_LEFTBUTTON);
+}
+
+// The counterpart to click. This simulates a button release through
+// the same mechanism.
+
+void CButtonArrayTest::release(CButtonArray *buttonArray, int column, int row)
+{
+ // nx_mousein is meant to be called by mouse handling software.
+ // Here we just inject a left-button click directly in the center of
+ // the button.
+
+ // First, get the server handle. Graphics software will never care
+ // about the server handle. Here we need it to get access to the
+ // low-level mouse interface
+
+ NXHANDLE handle = getServer();
+
+ // The the coorinates of the center of the button
+
+ nxgl_coord_t buttonX = buttonArray->getX() +
+ column * BUTTONARRAY_BUTTONWIDTH +
+ BUTTONARRAY_BUTTONWIDTH/2;
+ nxgl_coord_t buttonY = buttonArray->getY() +
+ row * BUTTONARRAY_BUTTONHEIGHT +
+ BUTTONARRAY_BUTTONHEIGHT/2;
+
+ // Then inject the mouse release
+
+ (void)nx_mousein(handle, buttonX, buttonY, NX_MOUSE_NOBUTTONS);
+}
+
+// Widget events are normally handled in a modal loop (by calling goModal()).
+// However, for this case we know when there should be press and release
+// events so we don't have to poll. We can just perform a one pass poll
+// then check if the event was processed corredly.
+
+void CButtonArrayTest::poll(CButtonArray *button)
+{
+ // Poll for mouse events
+
+ m_widgetControl->pollEvents(button);
+}
+
diff --git a/NxWidgets/UnitTests/CButtonArray/cbuttonarraytest.hxx b/NxWidgets/UnitTests/CButtonArray/cbuttonarraytest.hxx
new file mode 100644
index 000000000..ef265efbf
--- /dev/null
+++ b/NxWidgets/UnitTests/CButtonArray/cbuttonarraytest.hxx
@@ -0,0 +1,182 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CButtonArray/cbuttonarraytest.hxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef __UNITTESTS_CBUTTONARRAY_CBUTTONARRAYTEST_HXX
+#define __UNITTESTS_CBUTTONARRAY_CBUTTONARRAYTEST_HXX
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <semaphore.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "nxconfig.hxx"
+#include "cwidgetcontrol.hxx"
+#include "ccallback.hxx"
+#include "cbgwindow.hxx"
+#include "cnxserver.hxx"
+#include "cnxfont.hxx"
+#include "cnxstring.hxx"
+#include "cbuttonarray.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+// Configuration ////////////////////////////////////////////////////////////
+
+#ifndef CONFIG_HAVE_CXX
+# error "CONFIG_HAVE_CXX must be defined"
+#endif
+
+#ifndef CONFIG_CBUTTONARRAYTEST_BGCOLOR
+# define CONFIG_CBUTTONARRAYTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR
+#endif
+
+#ifndef CONFIG_CBUTTONARRAYTEST_FONTCOLOR
+# define CONFIG_CBUTTONARRAYTEST_FONTCOLOR CONFIG_NXWIDGETS_DEFAULT_FONTCOLOR
+#endif
+
+// What is the entry point called?
+
+#ifdef CONFIG_NSH_BUILTIN_APPS
+# define MAIN_NAME cbuttonarray_main
+# define MAIN_STRING "cbuttonarray_main: "
+#else
+# define MAIN_NAME user_start
+# define MAIN_STRING "user_start: "
+#endif
+
+// If debug is enabled, use the debug function, lib_rawprintf() instead
+// of printf() so that the output is synchronized.
+
+#ifdef CONFIG_DEBUG
+# define message lib_lowprintf
+#else
+# define message printf
+#endif
+
+// The geometry of the button array
+
+#define BUTTONARRAY_NCOLUMNS 4
+#define BUTTONARRAY_NROWS 7
+#define BUTTONARRAY_BUTTONWIDTH 60
+#define BUTTONARRAY_BUTTONHEIGHT 32
+#define BUTTONARRAY_WIDTH (BUTTONARRAY_BUTTONWIDTH * BUTTONARRAY_NCOLUMNS)
+#define BUTTONARRAY_HEIGHT (BUTTONARRAY_BUTTONHEIGHT * BUTTONARRAY_NROWS)
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Classes
+/////////////////////////////////////////////////////////////////////////////
+
+using namespace NXWidgets;
+
+class CButtonArrayTest : public CNxServer
+{
+private:
+ CWidgetControl *m_widgetControl; // The widget control for the window
+ CBgWindow *m_bgWindow; // Background window instance
+
+public:
+ // Constructor/destructors
+
+ CButtonArrayTest();
+ ~CButtonArrayTest();
+
+ // Initializer/unitializer. These methods encapsulate the basic steps for
+ // starting and stopping the NX server
+
+ bool connect(void);
+ void disconnect(void);
+
+ // Create a window. This method provides the general operations for
+ // creating a window that you can draw within.
+ //
+ // Those general operations are:
+ // 1) Create a dumb CWigetControl instance
+ // 2) Pass the dumb CWidgetControl instance to the window constructor
+ // that inherits from INxWindow. This will "smarten" the CWidgetControl
+ // instance with some window knowlede
+ // 3) Call the open() method on the window to display the window.
+ // 4) After that, the fully smartened CWidgetControl instance can
+ // be used to generate additional widgets by passing it to the
+ // widget constructor
+
+ bool createWindow(void);
+
+ // Create a CButtonArray instance. This method will show you how to create
+ // a CButtonArray widget
+
+ CButtonArray *createButtonArray(void);
+
+ // Draw the button array. This method illustrates how to draw the CButtonArray widget.
+
+ void showButton(CButtonArray *buttonArray);
+
+ // Perform a simulated mouse click on a button in the array. This method injects
+ // the mouse click through the NX heirarchy just as would real mouse
+ // hardward.
+
+ void click(CButtonArray *buttonArray, int column, int row);
+
+ // The counterpart to click. This simulates a button release through
+ // the same mechanism.
+
+ void release(CButtonArray *buttonArray, int column, int row);
+
+ // Widget events are normally handled in a model loop (by calling goModel()).
+ // However, for this case we know when there should be press and release
+ // events so we don't have to poll. We can just perform a one pass poll
+ // then check if the event was processed corredly.
+
+ void poll(CButtonArray *buttonArray);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+
+#endif // __UNITTESTS_CBUTTONARRAY_CBUTTONARRAYTEST_HXX
diff --git a/NxWidgets/UnitTests/CButtonArray/main.cxx b/NxWidgets/UnitTests/CButtonArray/main.cxx
new file mode 100644
index 000000000..fa02413a4
--- /dev/null
+++ b/NxWidgets/UnitTests/CButtonArray/main.cxx
@@ -0,0 +1,327 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CButtonArray/main.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cstdlib>
+#include <unistd.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "cnxstring.hxx"
+#include "cbuttonarraytest.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+static unsigned int g_mmInitial;
+static unsigned int g_mmPrevious;
+static unsigned int g_mmPeak;
+
+static FAR const char *g_buttonLabels[BUTTONARRAY_NCOLUMNS*BUTTONARRAY_NROWS] = {
+ "=>", "A", "B", "<DEL",
+ "C", "D", "E", "F",
+ "G", "H", "I", "J",
+ "K", "L", "M", "N",
+ "O", "P", "Q", "R",
+ "S", "T", "U", "V",
+ "W", "X", "Y", "Z"
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+// Suppress name-mangling
+
+extern "C" int MAIN_NAME(int argc, char *argv[]);
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: updateMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void updateMemoryUsage(unsigned int previous,
+ FAR const char *msg)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ /* Show the change from the previous time */
+
+ message("%s: Before: %8d After: %8d Change: %8d\n",
+ msg, previous, mmcurrent.uordblks, mmcurrent.uordblks - previous);
+
+ /* Set up for the next test */
+
+ g_mmPrevious = mmcurrent.uordblks;
+ if ((unsigned int)mmcurrent.uordblks > g_mmPeak)
+ {
+ g_mmPeak = mmcurrent.uordblks;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: initMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void initMemoryUsage(void)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ g_mmInitial = mmcurrent.uordblks;
+ g_mmPrevious = mmcurrent.uordblks;
+ g_mmPeak = mmcurrent.uordblks;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: checkHighlighting
+/////////////////////////////////////////////////////////////////////////////
+
+static void checkHighlighting(CButtonArray *buttonArray)
+{
+ // Turn highlighting on
+
+ buttonArray->setCursorPosition(0, 0);
+ buttonArray->cursor(true);
+
+ // Then test the cursor movement
+
+ for (int row = 0; row < BUTTONARRAY_NROWS; row++)
+ {
+ for (int column = 0; column < BUTTONARRAY_NCOLUMNS; column++)
+ {
+ // Set cursor position
+
+ buttonArray->setCursorPosition(column, row);
+
+ // Check cursor position
+
+ int checkColumn;
+ int checkRow;
+ if (buttonArray->isCursorPosition(checkColumn, checkRow))
+ {
+ printf("ERROR: Not button selected\n");
+ printf(" Expected (%d,%d)\n", column, row);
+ }
+ else if (checkColumn != column || checkRow != row)
+ {
+ printf("ERROR: Wrong button selected\n");
+ printf(" Expected (%d,%d)\n", column, row);
+ printf(" Selected (%d,%d)\n", checkColumn, checkRow);
+ }
+
+ // Wait a bit so that we can see the highlighting
+
+ usleep(500*1000);
+ }
+ }
+
+ // Turn highlighting off
+
+ buttonArray->cursor(false);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// user_start/nxheaders_main
+/////////////////////////////////////////////////////////////////////////////
+
+int MAIN_NAME(int argc, char *argv[])
+{
+ // Initialize memory monitor logic
+
+ initMemoryUsage();
+
+ // Create an instance of the button array test
+
+ printf(MAIN_STRING "Create CButtonArrayTest instance\n");
+ CButtonArrayTest *test = new CButtonArrayTest();
+ updateMemoryUsage(g_mmPrevious, "After creating CButtonArrayTest");
+
+ // Connect the NX server
+
+ printf(MAIN_STRING "Connect the CButtonArrayTest instance to the NX server\n");
+ if (!test->connect())
+ {
+ printf(MAIN_STRING "Failed to connect the CButtonArrayTest instance to the NX server\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmPrevious, "After connecting to the server");
+
+ // Create a window to draw into
+
+ printf(MAIN_STRING "Create a Window\n");
+ if (!test->createWindow())
+ {
+ printf(MAIN_STRING "Failed to create a window\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmPrevious, "After creating a window");
+
+ // Create a CButtonArray instance
+
+ CButtonArray *buttonArray = test->createButtonArray();
+ if (!buttonArray)
+ {
+ printf(MAIN_STRING "Failed to create a button array\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmPrevious, "After creating CButtonArray");
+
+ // Add the labels to each button
+
+ FAR const char **ptr = g_buttonLabels;
+ for (int j = 0; j < BUTTONARRAY_NROWS; j++)
+ {
+ for (int i = 0; i < BUTTONARRAY_NCOLUMNS; i++)
+ {
+ printf(MAIN_STRING "Label (%d,%d): %s\n", i, j, *ptr);
+ CNxString string = *ptr++;
+ buttonArray->setText(i, j, string);
+ }
+ }
+ updateMemoryUsage(g_mmPrevious, "After adding labels to the buttons");
+
+ // Show the button array
+
+ printf(MAIN_STRING "Show the button array\n");
+ test->showButton(buttonArray);
+ sleep(1);
+
+ // Verify that button highlighting works
+
+ checkHighlighting(buttonArray);
+ updateMemoryUsage(g_mmPrevious, "After highliting");
+
+ // Then perform a simulated mouse click on a button in the array
+
+ for (int j = 0; j < BUTTONARRAY_NROWS; j++)
+ {
+ for (int i = 0; i < BUTTONARRAY_NCOLUMNS; i++)
+ {
+ printf(MAIN_STRING "Click the button (%d,%d)\n", i, j);
+ test->click(buttonArray, i, j);
+
+ // Poll for the mouse click event
+
+ test->poll(buttonArray);
+
+ // Is anything clicked?
+
+ int clickColumn;
+ int clickRow;
+ if (buttonArray->isButtonClicked(clickColumn, clickRow))
+ {
+ printf(MAIN_STRING "%s: Button (%d, %d) is clicked\n",
+ clickColumn == i && clickRow == j ? "OK" : "ERROR",
+ clickColumn, clickRow);
+ }
+ else
+ {
+ printf(MAIN_STRING "ERROR: No button is clicked\n");
+ }
+
+ // Wait a bit, then release the mouse button
+
+ usleep(500*1000);
+ test->release(buttonArray, i, j);
+
+ // Poll for the mouse release event (of course this can hang if something fails)
+
+ test->poll(buttonArray);
+ if (buttonArray->isButtonClicked(clickColumn, clickRow))
+ {
+ printf(MAIN_STRING "ERROR: Button (%d, %d) is clicked\n",
+ clickColumn, clickRow);
+ }
+
+ usleep(500*1000);
+ }
+ }
+ updateMemoryUsage(g_mmPrevious, "After pushing buttons");
+
+ // Clean up and exit
+
+ printf(MAIN_STRING "Clean-up and exit\n");
+ delete buttonArray;
+ updateMemoryUsage(g_mmPrevious, "After deleting the button array");
+ delete test;
+ updateMemoryUsage(g_mmPrevious, "After deleting the test");
+ updateMemoryUsage(g_mmInitial, "Final memory usage");
+ message("Peak memory usage: %8d\n", g_mmPeak - g_mmInitial);
+ return 0;
+}
+
diff --git a/NxWidgets/UnitTests/CCheckBox/Makefile b/NxWidgets/UnitTests/CCheckBox/Makefile
new file mode 100644
index 000000000..9dae246ce
--- /dev/null
+++ b/NxWidgets/UnitTests/CCheckBox/Makefile
@@ -0,0 +1,172 @@
+#################################################################################
+# NxWidgets/UnitTests/CCheckBox/Makefile
+#
+# Copyright (C) 2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+# me be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#################################################################################
+
+TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'}
+
+-include $(TOPDIR)/.config
+-include $(TOPDIR)/Make.defs
+include $(APPDIR)/Make.defs
+
+# Add the path to the NXWidget include directory to the CFLAGS
+
+NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets"
+NXWIDGETS_INC="$(NXWIDGETS_DIR)/include"
+NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)"
+
+INCDIR=$(TOPDIR)/tools/incdir.sh
+ifeq ($(WINTOOL),y)
+ CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"}
+else
+ CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"}
+endif
+
+# Get the path to the archiver tool
+
+TESTTOOL_DIR="$(TESTDIR)/../tools"
+ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh
+
+# Hello, World! C++ Example
+
+ASRCS =
+CSRCS =
+CXXSRCS = main.cxx ccheckboxtest.cxx
+
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+COBJS = $(CSRCS:.c=$(OBJEXT))
+CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS)
+OBJS = $(AOBJS) $(COBJS) $(CXXOBJS)
+
+POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)"
+ifeq ($(WINTOOL),y)
+ BIN = "${shell cygpath -w $(POSIX_BIN)}"
+else
+ BIN = $(POSIX_BIN)
+endif
+
+ROOTDEPPATH = --dep-path .
+
+# helloxx built-in application info
+
+APPNAME = ccheckbox
+PRIORITY = SCHED_PRIORITY_DEFAULT
+STACKSIZE = 2048
+
+# Common build
+
+VPATH =
+
+all: .built
+.PHONY: clean depend context disclean chkcxx chklib
+
+# Object file creation targets
+
+$(AOBJS): %$(OBJEXT): %.S
+ $(call ASSEMBLE, $<, $@)
+
+$(COBJS): %$(OBJEXT): %.c
+ $(call COMPILE, $<, $@)
+
+$(CXXOBJS): %$(OBJEXT): %.cxx
+ $(call COMPILEXX, $<, $@)
+
+# Verify that the NuttX configuration is setup to support C++
+
+chkcxx:
+ifneq ($(CONFIG_HAVE_CXX),y)
+ @echo ""
+ @echo "In order to use this example, you toolchain must support must"
+ @echo ""
+ @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support"
+ @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file"
+ @echo " of the configuration that you are using."
+ @echo ""
+ @exit 1
+endif
+
+# Verify that the NXWidget library has been built
+
+chklib:
+ @( \
+ if [ ! -e "$(NXWIDGETS_LIB)" ]; then \
+ echo "$(NXWIDGETS_LIB) does not exist."; \
+ echo "Please go to $(NXWIDGETS_DIR)"; \
+ echo "and rebuild the library"; \
+ exit 1; \
+ fi; \
+ )
+
+# Library creation targets
+
+$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work.
+
+.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB)
+ @( for obj in $(OBJS) ; do \
+ $(call ARCHIVE, $(BIN), $${obj}); \
+ done ; )
+ifeq ($(WINTOOL),y)
+ @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+else
+ @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+endif
+ @touch .built
+
+# Standard housekeeping targets
+
+.context:
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+ $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
+endif
+ @touch $@
+
+context: .context
+
+.depend: Makefile $(SRCS)
+ @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep
+ @touch $@
+
+depend: .depend
+
+clean:
+ @rm -f *.o *~ .*.swp .built
+ $(call CLEAN)
+
+distclean: clean
+ @rm -f Make.dep .depend
+
+-include Make.dep
diff --git a/NxWidgets/UnitTests/CCheckBox/ccheckboxtest.cxx b/NxWidgets/UnitTests/CCheckBox/ccheckboxtest.cxx
new file mode 100644
index 000000000..90abf2e67
--- /dev/null
+++ b/NxWidgets/UnitTests/CCheckBox/ccheckboxtest.cxx
@@ -0,0 +1,297 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CCheckBox/ccheckboxtest.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cerrno>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+#include <nuttx/nx/nxfonts.h>
+
+#include "nxconfig.hxx"
+#include "cbgwindow.hxx"
+#include "ccheckboxtest.hxx"
+#include "cbitmap.hxx"
+#include "glyphs.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// CCheckBoxTest Method Implementations
+/////////////////////////////////////////////////////////////////////////////
+
+// CCheckBoxTest Constructor
+
+CCheckBoxTest::CCheckBoxTest()
+{
+ // Initialize state data
+
+ m_widgetControl = (CWidgetControl *)NULL;
+ m_bgWindow = (CBgWindow *)NULL;
+ m_checkBox = (CCheckBox *)NULL;
+}
+
+// CCheckBoxTest Descriptor
+
+CCheckBoxTest::~CCheckBoxTest(void)
+{
+ disconnect();
+}
+
+// Connect to the NX server
+
+bool CCheckBoxTest::connect(void)
+{
+ // Connect to the server
+
+ bool nxConnected = CNxServer::connect();
+ if (nxConnected)
+ {
+ // Set the background color
+
+ if (!setBackgroundColor(CONFIG_CCHECKBOXTEST_BGCOLOR))
+ {
+ message("CCheckBoxTest::connect: setBackgroundColor failed\n");
+ }
+ }
+
+ return nxConnected;
+}
+
+// Disconnect from the NX server
+
+void CCheckBoxTest::disconnect(void)
+{
+ // Free the radiobutton group
+
+ if (m_checkBox)
+ {
+ delete m_checkBox;
+ m_checkBox = (CCheckBox *)NULL;
+ }
+
+ // Close the window
+
+ if (m_bgWindow)
+ {
+ delete m_bgWindow;
+ m_bgWindow = (CBgWindow *)NULL;
+ }
+
+ // Free the widget control instance
+
+ if (m_widgetControl)
+ {
+ delete m_widgetControl;
+ m_widgetControl = (CWidgetControl *)NULL;
+ }
+
+ // And disconnect from the server
+
+ CNxServer::disconnect();
+}
+
+// Create the background window instance. This function illustrates
+// the basic steps to instantiate any window:
+//
+// 1) Create a dumb CWigetControl instance
+// 2) Pass the dumb CWidgetControl instance to the window constructor
+// that inherits from INxWindow. This will "smarten" the CWidgetControl
+// instance with some window knowlede
+// 3) Call the open() method on the window to display the window.
+// 4) After that, the fully smartened CWidgetControl instance can
+// be used to generate additional widgets by passing it to the
+// widget constructor
+
+bool CCheckBoxTest::createWindow(void)
+{
+ // Initialize the widget control using the default style
+
+ m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL);
+
+ // Get an (uninitialized) instance of the background window as a class
+ // that derives from INxWindow.
+
+ m_bgWindow = getBgWindow(m_widgetControl);
+ if (!m_bgWindow)
+ {
+ message("CCheckBoxTest::createWindow: Failed to create CBgWindow instance\n");
+ disconnect();
+ return false;
+ }
+
+ // Open (and initialize) the window
+
+ bool success = m_bgWindow->open();
+ if (!success)
+ {
+ message("CCheckBoxTest::createWindow: Failed to open background window\n");
+ disconnect();
+ return false;
+ }
+
+ // Get the size of the display
+
+ struct nxgl_size_s windowSize;
+ if (!m_bgWindow->getSize(&windowSize))
+ {
+ printf("CCheckBoxTest::createWindow: Failed to get window size\n");
+ disconnect();
+ return false;
+ }
+
+ // Use the the size of the ON checkbox glyph. (adding twice the border thickness)
+
+ nxgl_coord_t width = g_checkBoxOn.width + 2 * 1;
+ nxgl_coord_t height = g_checkBoxOn.height + 2 * 1;
+
+ nxgl_coord_t checkboxX = (windowSize.w - width) >> 1;
+ nxgl_coord_t checkboxY = (windowSize.h - height) >> 1;
+
+ // Create the checkbox
+
+ m_checkBox = new CCheckBox(m_widgetControl, checkboxX, checkboxY,
+ width, height, (CWidgetStyle *)NULL);
+ if (!m_checkBox)
+ {
+ printf("CCheckBoxTest::createWindow: Failed to create CCheckBox\n");
+ disconnect();
+ return false;
+ }
+
+ return true;
+}
+
+// (Re-)draw the check box.
+
+void CCheckBoxTest::showCheckBox(void)
+{
+ m_checkBox->enable(); // Un-necessary, the widget is enabled by default
+ m_checkBox->enableDrawing();
+ m_checkBox->redraw();
+}
+
+// Push the radio button
+
+void CCheckBoxTest::clickCheckBox(void)
+{
+ // Get the checkbox center coordinates
+
+ nxgl_coord_t checkboxX = m_checkBox->getX() + (m_checkBox->getWidth() >> 1);
+ nxgl_coord_t checkboxY = m_checkBox->getY() + (m_checkBox->getHeight() >> 1);
+
+ // Click the checkbox by calling nx_mousein. nx_mousein is meant to be
+ // called by mouse handling software. Here we just inject a left-button click
+ // directly in the center of the radio button.
+
+ // First, get the server handle. Graphics software will never care
+ // about the server handle. Here we need it to get access to the
+ // low-level mouse interface
+
+ NXHANDLE handle = getServer();
+
+ // Then inject the mouse click
+
+ (void)nx_mousein(handle, checkboxX, checkboxY, NX_MOUSE_LEFTBUTTON);
+
+ // Poll for mouse events
+ //
+ // Widget events are normally handled in a modal loop (by calling goModal()).
+ // However, for this case we know that we just pressed the mouse button
+ // so we don't have to poll. We can just perform a one pass poll then
+ // then check if the mouse event was processed corredly.
+
+ m_widgetControl->pollEvents(m_checkBox);
+
+ // Then inject the mouse release
+
+ (void)nx_mousein(handle, checkboxX, checkboxY, 0);
+
+ // And poll for more mouse events
+
+ m_widgetControl->pollEvents(m_checkBox);
+
+ // And re-draw the buttons (the mouse click event should have automatically
+ // triggered the re-draw)
+ //
+ // showCheckBox();
+}
+
+// Show the state of the radio button group
+
+void CCheckBoxTest::showCheckBoxState(void)
+{
+ CCheckBox::CheckBoxState state = m_checkBox->getState();
+ switch (state)
+ {
+ case CCheckBox::CHECK_BOX_STATE_OFF: // Checkbox is unticked
+ message("CCheckBoxTest::showCheckBoxState Checkbox is in the unticked state\n");
+ break;
+
+ case CCheckBox::CHECK_BOX_STATE_ON: // Checkbox is ticked
+ message("CCheckBoxTest::showCheckBoxState Check is in the ticked state\n");
+ break;
+
+ default:
+ case CCheckBox::CHECK_BOX_STATE_MU: // Checkbox is in the third state
+ message("CCheckBoxTest::showCheckBoxState Checkbox is in the 3rd state\n");
+ break;
+ }
+}
diff --git a/NxWidgets/UnitTests/CCheckBox/ccheckboxtest.hxx b/NxWidgets/UnitTests/CCheckBox/ccheckboxtest.hxx
new file mode 100644
index 000000000..52371ab73
--- /dev/null
+++ b/NxWidgets/UnitTests/CCheckBox/ccheckboxtest.hxx
@@ -0,0 +1,152 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CCheckBox/ccheckboxtest.hxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef __UNITTESTS_CCHECKBOX_CCHECKBOXTEST_HXX
+#define __UNITTESTS_CCHECKBOX_CCHECKBOXTEST_HXX
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <semaphore.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "nxconfig.hxx"
+#include "cwidgetcontrol.hxx"
+#include "ccallback.hxx"
+#include "cbgwindow.hxx"
+#include "cnxserver.hxx"
+#include "ccheckbox.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+// Configuration ////////////////////////////////////////////////////////////
+
+#ifndef CONFIG_HAVE_CXX
+# error "CONFIG_HAVE_CXX must be defined"
+#endif
+
+#ifndef CONFIG_CCHECKBOXTEST_BGCOLOR
+# define CONFIG_CCHECKBOXTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR
+#endif
+
+// What is the entry point called?
+
+#ifdef CONFIG_NSH_BUILTIN_APPS
+# define MAIN_NAME ccheckbox_main
+# define MAIN_STRING "ccheckbox_main: "
+#else
+# define MAIN_NAME user_start
+# define MAIN_STRING "user_start: "
+#endif
+
+// If debug is enabled, use the debug function, lib_rawprintf() instead
+// of printf() so that the output is synchronized.
+
+#ifdef CONFIG_DEBUG
+# define message lib_lowprintf
+#else
+# define message printf
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Classes
+/////////////////////////////////////////////////////////////////////////////
+
+using namespace NXWidgets;
+
+class CCheckBoxTest : public CNxServer
+{
+private:
+ CWidgetControl *m_widgetControl; // The controlling widget for the window
+ CBgWindow *m_bgWindow; // Background window instance
+ CCheckBox *m_checkBox; // Checkgox instance under test
+
+public:
+ // Constructor/destructors
+
+ CCheckBoxTest(void);
+ ~CCheckBoxTest(void);
+
+ // Initializer/unitializer. These methods encapsulate the basic steps for
+ // starting and stopping the NX server
+
+ bool connect(void);
+ void disconnect(void);
+
+ // Create a window. This method provides the general operations for
+ // creating a window that you can draw within.
+ //
+ // Those general operations are:
+ // 1) Create a dumb CWigetControl instance
+ // 2) Pass the dumb CWidgetControl instance to the window constructor
+ // that inherits from INxWindow. This will "smarten" the CWidgetControl
+ // instance with some window knowlede
+ // 3) Call the open() method on the window to display the window.
+ // 4) After that, the fully smartened CWidgetControl instance can
+ // be used to generate additional widgets by passing it to the
+ // widget constructor
+
+ bool createWindow(void);
+
+ // (Re-)draw the checkbox.
+
+ void showCheckBox(void);
+
+ // Simulate pushing and releasing of the radio button
+
+ void clickCheckBox(void);
+
+ // Show the state of the radio button group
+
+ void showCheckBoxState(void);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+#endif // __UNITTESTS_CCHECKBOX_CCHECKBOXTEST_HXX
diff --git a/NxWidgets/UnitTests/CCheckBox/main.cxx b/NxWidgets/UnitTests/CCheckBox/main.cxx
new file mode 100644
index 000000000..e9e8b516f
--- /dev/null
+++ b/NxWidgets/UnitTests/CCheckBox/main.cxx
@@ -0,0 +1,209 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CCheckBox/main.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <unistd.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "crlepalettebitmap.hxx"
+#include "glyphs.hxx"
+#include "ccheckboxtest.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+static unsigned int g_mmInitial;
+static unsigned int g_mmprevious;
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+// Suppress name-mangling
+
+extern "C" int MAIN_NAME(int argc, char *argv[]);
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: updateMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void updateMemoryUsage(unsigned int previous,
+ FAR const char *msg)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ /* Show the change from the previous time */
+
+ message("\n%s:\n", msg);
+ message(" Before: %8d After: %8d Change: %8d\n\n",
+ previous, mmcurrent.uordblks, mmcurrent.uordblks - previous);
+
+ /* Set up for the next test */
+
+ g_mmprevious = mmcurrent.uordblks;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: initMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void initMemoryUsage(void)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ g_mmInitial = mmcurrent.uordblks;
+ g_mmprevious = mmcurrent.uordblks;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: user_start/nxheaders_main
+/////////////////////////////////////////////////////////////////////////////
+
+int MAIN_NAME(int argc, char *argv[])
+{
+ // Initialize memory monitor logic
+
+ initMemoryUsage();
+
+ // Create an instance of the checkbox test
+
+ message(MAIN_STRING "Create CCheckBoxTest instance\n");
+ CCheckBoxTest *test = new CCheckBoxTest();
+ updateMemoryUsage(g_mmprevious, "After creating CCheckBoxTest");
+
+ // Connect the NX server
+
+ message(MAIN_STRING "Connect the CCheckBoxTest instance to the NX server\n");
+ if (!test->connect())
+ {
+ message(MAIN_STRING "Failed to connect the CCheckBoxTest instance to the NX server\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After connecting to the server");
+
+ // Create a window to draw into
+
+ message(MAIN_STRING "Create a Window\n");
+ if (!test->createWindow())
+ {
+ message(MAIN_STRING "Failed to create a window\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating a window");
+
+ // Show the initial state of the checkbox
+
+ test->showCheckBox();
+ test->showCheckBoxState();
+ sleep(1);
+
+ // Now click the checkbox
+
+ message(MAIN_STRING "Click 1\n");
+ test->clickCheckBox();
+ usleep(500*1000);
+ test->showCheckBoxState();
+ updateMemoryUsage(g_mmprevious, "After click 1");
+ usleep(500*1000);
+
+ message(MAIN_STRING "Click 2\n");
+ test->clickCheckBox();
+ usleep(500*1000);
+ test->showCheckBoxState();
+ updateMemoryUsage(g_mmprevious, "After click 2");
+ usleep(500*1000);
+
+ message(MAIN_STRING "Click 3\n");
+ test->clickCheckBox();
+ usleep(500*1000);
+ test->showCheckBoxState();
+ updateMemoryUsage(g_mmprevious, "After click 3");
+ sleep(2);
+
+ // Clean up and exit
+
+ message(MAIN_STRING "Clean-up and exit\n");
+ delete test;
+ updateMemoryUsage(g_mmprevious, "After deleting the test");
+ updateMemoryUsage(g_mmInitial, "Final memory usage");
+ return 0;
+}
+
diff --git a/NxWidgets/UnitTests/CGlyphButton/Makefile b/NxWidgets/UnitTests/CGlyphButton/Makefile
new file mode 100644
index 000000000..527d882fa
--- /dev/null
+++ b/NxWidgets/UnitTests/CGlyphButton/Makefile
@@ -0,0 +1,172 @@
+#################################################################################
+# NxWidgets/UnitTests/CGlyphButton/Makefile
+#
+# Copyright (C) 2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+# me be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#################################################################################
+
+TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'}
+
+-include $(TOPDIR)/.config
+-include $(TOPDIR)/Make.defs
+include $(APPDIR)/Make.defs
+
+# Add the path to the NXWidget include directory to the CFLAGS
+
+NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets"
+NXWIDGETS_INC="$(NXWIDGETS_DIR)/include"
+NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)"
+
+INCDIR=$(TOPDIR)/tools/incdir.sh
+ifeq ($(WINTOOL),y)
+ CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"}
+else
+ CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"}
+endif
+
+# Get the path to the archiver tool
+
+TESTTOOL_DIR="$(TESTDIR)/../tools"
+ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh
+
+# Hello, World! C++ Example
+
+ASRCS =
+CSRCS =
+CXXSRCS = main.cxx cglyphbuttontest.cxx
+
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+COBJS = $(CSRCS:.c=$(OBJEXT))
+CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS)
+OBJS = $(AOBJS) $(COBJS) $(CXXOBJS)
+
+POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)"
+ifeq ($(WINTOOL),y)
+ BIN = "${shell cygpath -w $(POSIX_BIN)}"
+else
+ BIN = $(POSIX_BIN)
+endif
+
+ROOTDEPPATH = --dep-path .
+
+# helloxx built-in application info
+
+APPNAME = cglyphbutton
+PRIORITY = SCHED_PRIORITY_DEFAULT
+STACKSIZE = 2048
+
+# Common build
+
+VPATH =
+
+all: .built
+.PHONY: clean depend context disclean chkcxx chklib
+
+# Object file creation targets
+
+$(AOBJS): %$(OBJEXT): %.S
+ $(call ASSEMBLE, $<, $@)
+
+$(COBJS): %$(OBJEXT): %.c
+ $(call COMPILE, $<, $@)
+
+$(CXXOBJS): %$(OBJEXT): %.cxx
+ $(call COMPILEXX, $<, $@)
+
+# Verify that the NuttX configuration is setup to support C++
+
+chkcxx:
+ifneq ($(CONFIG_HAVE_CXX),y)
+ @echo ""
+ @echo "In order to use this example, you toolchain must support must"
+ @echo ""
+ @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support"
+ @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file"
+ @echo " of the configuration that you are using."
+ @echo ""
+ @exit 1
+endif
+
+# Verify that the NXWidget library has been built
+
+chklib:
+ @( \
+ if [ ! -e "$(NXWIDGETS_LIB)" ]; then \
+ echo "$(NXWIDGETS_LIB) does not exist."; \
+ echo "Please go to $(NXWIDGETS_DIR)"; \
+ echo "and rebuild the library"; \
+ exit 1; \
+ fi; \
+ )
+
+# Library creation targets
+
+$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work.
+
+.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB)
+ @( for obj in $(OBJS) ; do \
+ $(call ARCHIVE, $(BIN), $${obj}); \
+ done ; )
+ifeq ($(WINTOOL),y)
+ @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+else
+ @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+endif
+ @touch .built
+
+# Standard housekeeping targets
+
+.context:
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+ $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
+endif
+ @touch $@
+
+context: .context
+
+.depend: Makefile $(SRCS)
+ @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep
+ @touch $@
+
+depend: .depend
+
+clean:
+ @rm -f *.o *~ .*.swp .built
+ $(call CLEAN)
+
+distclean: clean
+ @rm -f Make.dep .depend
+
+-include Make.dep
diff --git a/NxWidgets/UnitTests/CGlyphButton/cglyphbuttontest.cxx b/NxWidgets/UnitTests/CGlyphButton/cglyphbuttontest.cxx
new file mode 100644
index 000000000..d44238c78
--- /dev/null
+++ b/NxWidgets/UnitTests/CGlyphButton/cglyphbuttontest.cxx
@@ -0,0 +1,307 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CGlyphButton/cglyphbuttontest.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cerrno>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+#include <nuttx/nx/nxfonts.h>
+
+#include "nxconfig.hxx"
+#include "cglyphbuttontest.hxx"
+#include "cbgwindow.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// CGlyphButtonTest Method Implementations
+/////////////////////////////////////////////////////////////////////////////
+
+// CGlyphButtonTest Constructor
+
+CGlyphButtonTest::CGlyphButtonTest()
+{
+ m_widgetControl = (CWidgetControl *)NULL;
+ m_bgWindow = (CBgWindow *)NULL;
+ m_center.x = 0;
+ m_center.y = 0;
+}
+
+// CGlyphButtonTest Descriptor
+
+CGlyphButtonTest::~CGlyphButtonTest()
+{
+ disconnect();
+}
+
+// Connect to the NX server
+
+bool CGlyphButtonTest::connect(void)
+{
+ // Connect to the server
+
+ bool nxConnected = CNxServer::connect();
+ if (nxConnected)
+ {
+ // Set the background color
+
+ if (!setBackgroundColor(CONFIG_CGLYPHBUTTONTEST_BGCOLOR))
+ {
+ message("CGlyphButtonTest::connect: setBackgroundColor failed\n");
+ }
+ }
+
+ return nxConnected;
+}
+
+// Disconnect from the NX server
+
+void CGlyphButtonTest::disconnect(void)
+{
+ // Delete the widget control instance
+
+ if (m_widgetControl)
+ {
+ delete m_widgetControl;
+ }
+
+ // Close the window
+
+ if (m_bgWindow)
+ {
+ delete m_bgWindow;
+ }
+
+ // And disconnect from the server
+
+ CNxServer::disconnect();
+}
+
+// Create the background window instance. This function illustrates
+// the basic steps to instantiate any window:
+//
+// 1) Create a dumb CWigetControl instance
+// 2) Pass the dumb CWidgetControl instance to the window constructor
+// that inherits from INxWindow. This will "smarten" the CWidgetControl
+// instance with some window knowlede
+// 3) Call the open() method on the window to display the window.
+// 4) After that, the fully smartened CWidgetControl instance can
+// be used to generate additional widgets by passing it to the
+// widget constructor
+
+bool CGlyphButtonTest::createWindow(void)
+{
+ // Initialize the widget control using the default style
+
+ m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL);
+
+ // Get an (uninitialized) instance of the background window as a class
+ // that derives from INxWindow.
+
+ m_bgWindow = getBgWindow(m_widgetControl);
+ if (!m_bgWindow)
+ {
+ message("CGlyphButtonTest::createGraphics: Failed to create CBgWindow instance\n");
+ delete m_widgetControl;
+ return false;
+ }
+
+ // Open (and initialize) the window
+
+ bool success = m_bgWindow->open();
+ if (!success)
+ {
+ message("CGlyphButtonTest::createGraphics: Failed to open background window\n");
+ delete m_bgWindow;
+ m_bgWindow = (CBgWindow*)0;
+ return false;
+ }
+
+ return true;
+}
+
+// Create a CGlyphButton instance
+
+CGlyphButton *CGlyphButtonTest::createButton(FAR const struct SBitmap *clickGlyph,
+ FAR const struct SBitmap *unClickedGlyph)
+{
+ // Get the width of the display
+
+ struct nxgl_size_s windowSize;
+ if (!m_bgWindow->getSize(&windowSize))
+ {
+ message("CGlyphButtonTest::createGraphics: Failed to get window size\n");
+ return (CGlyphButton *)NULL;
+ }
+
+ // Get the height and width of the glyph display area
+
+ nxgl_coord_t glyphWidth = MAX(clickGlyph->width, unClickedGlyph->width);
+ nxgl_coord_t glyphHeight = MAX(clickGlyph->height, unClickedGlyph->height);
+
+ // The default CGlyphButton has borders enabled with thickness of the border
+ // width. Add twice the thickness of the border to the width and height. (We
+ // could let CGlyphButton do this for us by calling
+ // CGlyphButton::getPreferredDimensions())
+
+ glyphWidth += 2 * 1;
+ glyphHeight += 2 * 1;
+
+ // Pick an X/Y position such that the button will be centered in the display
+
+ nxgl_coord_t buttonX;
+ if (glyphWidth >= windowSize.w)
+ {
+ buttonX = 0;
+ }
+ else
+ {
+ buttonX = (windowSize.w - glyphWidth) >> 1;
+ }
+
+ nxgl_coord_t buttonY;
+ if (glyphHeight >= windowSize.h)
+ {
+ buttonY = 0;
+ }
+ else
+ {
+ buttonY = (windowSize.h - glyphHeight) >> 1;
+ }
+
+ // Save the center position of the button for use by click and release
+
+ m_center.x = buttonX + (glyphWidth >> 1);
+ m_center.y = buttonY + (glyphHeight >> 1);
+
+ // Now we have enough information to create the button
+
+ return new CGlyphButton(m_widgetControl, buttonX, buttonY,
+ glyphWidth, glyphHeight,
+ unClickedGlyph, clickGlyph);
+}
+
+// Draw the button
+
+void CGlyphButtonTest::showButton(CGlyphButton *button)
+{
+ button->enable(); // Un-necessary, the widget is enabled by default
+ button->enableDrawing();
+ button->redraw();
+}
+
+// Perform a simulated mouse click on the button. This method injects
+// the mouse click through the NX heirarchy just as would real mouse
+// hardward.
+
+void CGlyphButtonTest::click(void)
+{
+ // nx_mousein is meant to be called by mouse handling software.
+ // Here we just inject a left-button click directly in the center of
+ // the button.
+
+ // First, get the server handle. Graphics software will never care
+ // about the server handle. Here we need it to get access to the
+ // low-level mouse interface
+
+ NXHANDLE handle = getServer();
+
+ // Then inject the mouse click
+
+ (void)nx_mousein(handle, m_center.x, m_center.y, NX_MOUSE_LEFTBUTTON);
+}
+
+// The counterpart to click. This simulates a button release through
+// the same mechanism.
+
+void CGlyphButtonTest::release(void)
+{
+ // nx_mousein is meant to be called by mouse handling software.
+ // Here we just inject a left-button click directly in the center of
+ // the button.
+
+ // First, get the server handle. Graphics software will never care
+ // about the server handle. Here we need it to get access to the
+ // low-level mouse interface
+
+ NXHANDLE handle = getServer();
+
+ // Then inject the mouse click
+
+ (void)nx_mousein(handle, m_center.x, m_center.y, NX_MOUSE_NOBUTTONS);
+}
+
+// Widget events are normally handled in a modal loop (by calling goModal()).
+// However, for this case we know when there should be press and release
+// events so we don't have to poll. We can just perform a one pass poll
+// then check if the event was processed corredly.
+
+bool CGlyphButtonTest::poll(CGlyphButton *button)
+{
+ // Poll for mouse events
+
+ m_widgetControl->pollEvents(button);
+
+ // And return the button clicked state
+
+ return button->isClicked();
+}
+
diff --git a/NxWidgets/UnitTests/CGlyphButton/cglyphbuttontest.hxx b/NxWidgets/UnitTests/CGlyphButton/cglyphbuttontest.hxx
new file mode 100644
index 000000000..889ce21ca
--- /dev/null
+++ b/NxWidgets/UnitTests/CGlyphButton/cglyphbuttontest.hxx
@@ -0,0 +1,182 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CGlyphButton/cglyphbuttontest.hxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef __UNITTESTS_CGLYPHBUTTON_CGLYPHBUTTONTEST_HXX
+#define __UNITTESTS_CGLYPHBUTTON_CGLYPHBUTTONTEST_HXX
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <semaphore.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "nxconfig.hxx"
+#include "cwidgetcontrol.hxx"
+#include "ccallback.hxx"
+#include "cbgwindow.hxx"
+#include "cnxserver.hxx"
+#include "cnxfont.hxx"
+#include "cnxstring.hxx"
+#include "cglyphbutton.hxx"
+#include "cbitmap.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+// Configuration ////////////////////////////////////////////////////////////
+
+#ifndef CONFIG_HAVE_CXX
+# error "CONFIG_HAVE_CXX must be defined"
+#endif
+
+#ifndef CONFIG_CGLYPHBUTTONTEST_BGCOLOR
+# define CONFIG_CGLYPHBUTTONTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR
+#endif
+
+#ifndef CONFIG_CGLYPHBUTTONTEST_FONTCOLOR
+# define CONFIG_CGLYPHBUTTONTEST_FONTCOLOR CONFIG_NXWIDGETS_DEFAULT_FONTCOLOR
+#endif
+
+// What is the entry point called?
+
+#ifdef CONFIG_NSH_BUILTIN_APPS
+# define MAIN_NAME cglyphbutton_main
+# define MAIN_STRING "cglyphbutton_main: "
+#else
+# define MAIN_NAME user_start
+# define MAIN_STRING "user_start: "
+#endif
+
+// If debug is enabled, use the debug function, lib_rawprintf() instead
+// of printf() so that the output is synchronized.
+
+#ifdef CONFIG_DEBUG
+# define message lib_lowprintf
+#else
+# define message printf
+#endif
+
+// Helper macros
+
+#ifndef MAX
+# define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Classes
+/////////////////////////////////////////////////////////////////////////////
+
+using namespace NXWidgets;
+
+class CGlyphButtonTest : public CNxServer
+{
+private:
+ CWidgetControl *m_widgetControl; // The controlling widget for the window
+ CBgWindow *m_bgWindow; // Background window instance
+ struct nxgl_point_s m_center; // X, Y position the center of the button
+
+public:
+ // Constructor/destructors
+
+ CGlyphButtonTest();
+ ~CGlyphButtonTest();
+
+ // Initializer/unitializer. These methods encapsulate the basic steps for
+ // starting and stopping the NX server
+
+ bool connect(void);
+ void disconnect(void);
+
+ // Create a window. This method provides the general operations for
+ // creating a window that you can draw within.
+ //
+ // Those general operations are:
+ // 1) Create a dumb CWigetControl instance
+ // 2) Pass the dumb CWidgetControl instance to the window constructor
+ // that inherits from INxWindow. This will "smarten" the CWidgetControl
+ // instance with some window knowlede
+ // 3) Call the open() method on the window to display the window.
+ // 4) After that, the fully smartened CWidgetControl instance can
+ // be used to generate additional widgets by passing it to the
+ // widget constructor
+
+ bool createWindow(void);
+
+ // Create a CGlyphButton instance. This method will show you how to create
+ // a CGlyphButton widget
+
+ CGlyphButton *createButton(FAR const struct SBitmap *clickGlyph,
+ FAR const struct SBitmap *unClickedGlyph);
+
+ // Draw the button. This method illustrates how to draw the CGlyphButton widget.
+
+ void showButton(CGlyphButton *button);
+
+ // Perform a simulated mouse click on the button. This method injects
+ // the mouse click through the NX heirarchy just as would real mouse
+ // hardward.
+
+ void click(void);
+
+ // The counterpart to click. This simulates a button release through
+ // the same mechanism.
+
+ void release(void);
+
+ // Widget events are normally handled in a model loop (by calling goModel()).
+ // However, for this case we know when there should be press and release
+ // events so we don't have to poll. We can just perform a one pass poll
+ // then check if the event was processed corredly.
+
+ bool poll(CGlyphButton *button);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+
+#endif // __UNITTESTS_CGLYPHBUTTON_CGLYPHBUTTONTEST_HXX
diff --git a/NxWidgets/UnitTests/CGlyphButton/main.cxx b/NxWidgets/UnitTests/CGlyphButton/main.cxx
new file mode 100644
index 000000000..7812fa9e9
--- /dev/null
+++ b/NxWidgets/UnitTests/CGlyphButton/main.cxx
@@ -0,0 +1,225 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CGlyphButton/main.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <unistd.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "cglyphbuttontest.hxx"
+#include "glyphs.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+static unsigned int g_mmInitial;
+static unsigned int g_mmprevious;
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+// Suppress name-mangling
+
+extern "C" int MAIN_NAME(int argc, char *argv[]);
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: updateMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void updateMemoryUsage(unsigned int previous,
+ FAR const char *msg)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ /* Show the change from the previous time */
+
+ message("\n%s:\n", msg);
+ message(" Before: %8d After: %8d Change: %8d\n\n",
+ previous, mmcurrent.uordblks, mmcurrent.uordblks - previous);
+
+ /* Set up for the next test */
+
+ g_mmprevious = mmcurrent.uordblks;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: initMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void initMemoryUsage(void)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ g_mmInitial = mmcurrent.uordblks;
+ g_mmprevious = mmcurrent.uordblks;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// user_start/nxheaders_main
+/////////////////////////////////////////////////////////////////////////////
+
+int MAIN_NAME(int argc, char *argv[])
+{
+ // Initialize memory monitor logic
+
+ initMemoryUsage();
+
+ // Create an instance of the font test
+
+ message(MAIN_STRING "Create CGlyphButtonTest instance\n");
+ CGlyphButtonTest *test = new CGlyphButtonTest();
+ updateMemoryUsage(g_mmprevious, "After creating CGlyphButtonTest");
+
+ // Connect the NX server
+
+ message(MAIN_STRING "Connect the CGlyphButtonTest instance to the NX server\n");
+ if (!test->connect())
+ {
+ message(MAIN_STRING "Failed to connect the CGlyphButtonTest instance to the NX server\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, "After connecting to the server");
+
+ // Create a window to draw into
+
+ message(MAIN_STRING "Create a Window\n");
+ if (!test->createWindow())
+ {
+ message(MAIN_STRING "Failed to create a window\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, "After creating a window");
+
+ // Create a CGlyphButton instance
+
+ CGlyphButton *button = test->createButton(&g_arrowDown, &g_arrowUp);
+ if (!button)
+ {
+ message(MAIN_STRING "Failed to create a button\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, "After creating the glyph button");
+
+ // Show the button
+
+ message(MAIN_STRING "Show the button\n");
+ test->showButton(button);
+ updateMemoryUsage(g_mmprevious, "After showing the glyph button");
+
+ // Wait two seconds, then perform a simulated mouse click on the button
+
+ sleep(2);
+ message(MAIN_STRING "Click the button\n");
+ test->click();
+ updateMemoryUsage(g_mmprevious, "After clicking glyph button");
+
+ // Poll for the mouse click event (of course this can hang if something fails)
+
+ bool clicked = test->poll(button);
+ message(MAIN_STRING "Button is %s\n", clicked ? "clicked" : "released");
+
+ // Wait a second, then release the mouse buttone
+
+ sleep(1);
+ test->release();
+ updateMemoryUsage(g_mmprevious, "After releasing glyph button");
+
+ // Poll for the mouse release event (of course this can hang if something fails)
+
+ clicked = test->poll(button);
+ message(MAIN_STRING "Button is %s\n", clicked ? "clicked" : "released");
+
+ // Wait a few more seconds so that the tester can ponder the result
+
+ sleep(3);
+
+ // Clean up and exit
+
+ message(MAIN_STRING "Clean-up and exit\n");
+ delete button;
+ updateMemoryUsage(g_mmprevious, "After deleting the glyph button");
+ delete test;
+ updateMemoryUsage(g_mmprevious, "After deleting the test");
+ updateMemoryUsage(g_mmInitial, "Final memory usage");
+ return 0;
+}
+
diff --git a/NxWidgets/UnitTests/CImage/Makefile b/NxWidgets/UnitTests/CImage/Makefile
new file mode 100644
index 000000000..e248761e7
--- /dev/null
+++ b/NxWidgets/UnitTests/CImage/Makefile
@@ -0,0 +1,172 @@
+#################################################################################
+# NxWidgets/UnitTests/CImage/Makefile
+#
+# Copyright (C) 2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+# me be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#################################################################################
+
+TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'}
+
+-include $(TOPDIR)/.config
+-include $(TOPDIR)/Make.defs
+include $(APPDIR)/Make.defs
+
+# Add the path to the NXWidget include directory to the CFLAGS
+
+NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets"
+NXWIDGETS_INC="$(NXWIDGETS_DIR)/include"
+NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)"
+
+INCDIR=$(TOPDIR)/tools/incdir.sh
+ifeq ($(WINTOOL),y)
+ CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"}
+else
+ CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"}
+endif
+
+# Get the path to the archiver tool
+
+TESTTOOL_DIR="$(TESTDIR)/../tools"
+ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh
+
+# Hello, World! C++ Example
+
+ASRCS =
+CSRCS =
+CXXSRCS = main.cxx cimagetest.cxx
+
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+COBJS = $(CSRCS:.c=$(OBJEXT))
+CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS)
+OBJS = $(AOBJS) $(COBJS) $(CXXOBJS)
+
+POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)"
+ifeq ($(WINTOOL),y)
+ BIN = "${shell cygpath -w $(POSIX_BIN)}"
+else
+ BIN = $(POSIX_BIN)
+endif
+
+ROOTDEPPATH = --dep-path .
+
+# helloxx built-in application info
+
+APPNAME = cimage
+PRIORITY = SCHED_PRIORITY_DEFAULT
+STACKSIZE = 2048
+
+# Common build
+
+VPATH =
+
+all: .built
+.PHONY: clean depend context disclean chkcxx chklib
+
+# Object file creation targets
+
+$(AOBJS): %$(OBJEXT): %.S
+ $(call ASSEMBLE, $<, $@)
+
+$(COBJS): %$(OBJEXT): %.c
+ $(call COMPILE, $<, $@)
+
+$(CXXOBJS): %$(OBJEXT): %.cxx
+ $(call COMPILEXX, $<, $@)
+
+# Verify that the NuttX configuration is setup to support C++
+
+chkcxx:
+ifneq ($(CONFIG_HAVE_CXX),y)
+ @echo ""
+ @echo "In order to use this example, you toolchain must support must"
+ @echo ""
+ @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support"
+ @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file"
+ @echo " of the configuration that you are using."
+ @echo ""
+ @exit 1
+endif
+
+# Verify that the NXWidget library has been built
+
+chklib:
+ @( \
+ if [ ! -e "$(NXWIDGETS_LIB)" ]; then \
+ echo "$(NXWIDGETS_LIB) does not exist."; \
+ echo "Please go to $(NXWIDGETS_DIR)"; \
+ echo "and rebuild the library"; \
+ exit 1; \
+ fi; \
+ )
+
+# Library creation targets
+
+$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work.
+
+.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB)
+ @( for obj in $(OBJS) ; do \
+ $(call ARCHIVE, $(BIN), $${obj}); \
+ done ; )
+ifeq ($(WINTOOL),y)
+ @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+else
+ @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+endif
+ @touch .built
+
+# Standard housekeeping targets
+
+.context:
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+ $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
+endif
+ @touch $@
+
+context: .context
+
+.depend: Makefile $(SRCS)
+ @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep
+ @touch $@
+
+depend: .depend
+
+clean:
+ @rm -f *.o *~ .*.swp .built
+ $(call CLEAN)
+
+distclean: clean
+ @rm -f Make.dep .depend
+
+-include Make.dep
diff --git a/NxWidgets/UnitTests/CImage/cimagetest.cxx b/NxWidgets/UnitTests/CImage/cimagetest.cxx
new file mode 100644
index 000000000..48814c4ce
--- /dev/null
+++ b/NxWidgets/UnitTests/CImage/cimagetest.cxx
@@ -0,0 +1,240 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CImage/cimagetest.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cerrno>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+#include <nuttx/nx/nxfonts.h>
+
+#include "nxconfig.hxx"
+#include "ibitmap.hxx"
+#include "cbgwindow.hxx"
+#include "cimagetest.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// CImageTest Method Implementations
+/////////////////////////////////////////////////////////////////////////////
+
+// CImageTest Constructor
+
+CImageTest::CImageTest()
+{
+ m_widgetControl = (CWidgetControl *)NULL;
+ m_bgWindow = (CBgWindow *)NULL;
+}
+
+// CImageTest Descriptor
+
+CImageTest::~CImageTest()
+{
+ disconnect();
+}
+
+// Connect to the NX server
+
+bool CImageTest::connect(void)
+{
+ // Connect to the server
+
+ bool nxConnected = CNxServer::connect();
+ if (nxConnected)
+ {
+ // Set the background color
+
+ if (!setBackgroundColor(CONFIG_CIMAGETEST_BGCOLOR))
+ {
+ message("CImageTest::connect: setBackgroundColor failed\n");
+ }
+ }
+
+ return nxConnected;
+}
+
+// Disconnect from the NX server
+
+void CImageTest::disconnect(void)
+{
+ // Close the window
+
+ if (m_bgWindow)
+ {
+ delete m_bgWindow;
+ }
+
+ // Free the widget control instance
+
+ if (m_widgetControl)
+ {
+ delete m_widgetControl;
+ }
+
+ // And disconnect from the server
+
+ CNxServer::disconnect();
+}
+
+// Create the background window instance. This function illustrates
+// the basic steps to instantiate any window:
+//
+// 1) Create a dumb CWigetControl instance
+// 2) Pass the dumb CWidgetControl instance to the window constructor
+// that inherits from INxWindow. This will "smarten" the CWidgetControl
+// instance with some window knowlede
+// 3) Call the open() method on the window to display the window.
+// 4) After that, the fully smartened CWidgetControl instance can
+// be used to generate additional widgets by passing it to the
+// widget constructor
+
+bool CImageTest::createWindow(void)
+{
+ // Initialize the widget control using the default style
+
+ m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL);
+
+ // Get an (uninitialized) instance of the background window as a class
+ // that derives from INxWindow.
+
+ m_bgWindow = getBgWindow(m_widgetControl);
+ if (!m_bgWindow)
+ {
+ message("CImageTest::createGraphics: Failed to create CBgWindow instance\n");
+ delete m_widgetControl;
+ return false;
+ }
+
+ // Open (and initialize) the window
+
+ bool success = m_bgWindow->open();
+ if (!success)
+ {
+ message("CImageTest::createGraphics: Failed to open background window\n");
+ delete m_bgWindow;
+ m_bgWindow = (CBgWindow*)0;
+ return false;
+ }
+
+ return true;
+}
+
+// Create a CImage instance
+
+CImage *CImageTest::createImage(IBitmap *bitmap)
+{
+ // Get the width of the display
+
+ struct nxgl_size_s windowSize;
+ if (!m_bgWindow->getSize(&windowSize))
+ {
+ message("CImageTest::createGraphics: Failed to get window size\n");
+ return (CImage *)NULL;
+ }
+
+ // Get the height and width of the image
+
+ nxgl_coord_t imageWidth = bitmap->getWidth();
+ nxgl_coord_t imageHeight = (nxgl_coord_t)bitmap->getHeight();
+
+ // The default CImage has borders enabled with thickness of the border
+ // width. Add twice the thickness of the border to the width and height. (We
+ // could let CImage do this for us by calling CImage::getPreferredDimensions())
+
+ imageWidth += 2 * 1;
+ imageHeight += 2 * 1;
+
+ // Pick an X/Y position such that the image will be centered in the display
+
+ nxgl_coord_t imageX;
+ if (imageWidth >= windowSize.w)
+ {
+ imageX = 0;
+ }
+ else
+ {
+ imageX = (windowSize.w - imageWidth) >> 1;
+ }
+
+ nxgl_coord_t imageY;
+ if (imageHeight >= windowSize.h)
+ {
+ imageY = 0;
+ }
+ else
+ {
+ imageY = (windowSize.h - imageHeight) >> 1;
+ }
+
+ // Now we have enough information to create the image
+
+ return new CImage(m_widgetControl, imageX, imageY, imageWidth, imageHeight, bitmap);
+}
+
+// Draw the image
+
+void CImageTest::showImage(CImage *image)
+{
+ image->enable();
+ image->enableDrawing();
+ image->redraw();
+ image->disableDrawing();
+}
diff --git a/NxWidgets/UnitTests/CImage/cimagetest.hxx b/NxWidgets/UnitTests/CImage/cimagetest.hxx
new file mode 100644
index 000000000..8a8a55556
--- /dev/null
+++ b/NxWidgets/UnitTests/CImage/cimagetest.hxx
@@ -0,0 +1,150 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CImage/cimagetest.hxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef __UNITTESTS_CIMAGE_CIMAGETEST_HXX
+#define __UNITTESTS_CIMAGE_CIMAGETEST_HXX
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <semaphore.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "nxconfig.hxx"
+#include "cwidgetcontrol.hxx"
+#include "ccallback.hxx"
+#include "cbgwindow.hxx"
+#include "cnxserver.hxx"
+#include "cnxfont.hxx"
+#include "cnxstring.hxx"
+#include "cimage.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+// Configuration ////////////////////////////////////////////////////////////
+
+#ifndef CONFIG_HAVE_CXX
+# error "CONFIG_HAVE_CXX must be defined"
+#endif
+
+#ifndef CONFIG_CIMAGETEST_BGCOLOR
+# define CONFIG_CIMAGETEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR
+#endif
+
+// What is the entry point called?
+
+#ifdef CONFIG_NSH_BUILTIN_APPS
+# define MAIN_NAME cimage_main
+# define MAIN_STRING "cimage_main: "
+#else
+# define MAIN_NAME user_start
+# define MAIN_STRING "user_start: "
+#endif
+
+// If debug is enabled, use the debug function, lib_rawprintf() instead
+// of printf() so that the output is synchronized.
+
+#ifdef CONFIG_DEBUG
+# define message lib_lowprintf
+#else
+# define message printf
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Classes
+/////////////////////////////////////////////////////////////////////////////
+
+using namespace NXWidgets;
+
+class CImageTest : public CNxServer
+{
+private:
+ CWidgetControl *m_widgetControl; // The controlling widget for the window
+ CBgWindow *m_bgWindow; // Background window instance
+
+public:
+ // Constructor/destructors
+
+ CImageTest(void);
+ ~CImageTest(void);
+
+ // Initializer/unitializer. These methods encapsulate the basic steps for
+ // starting and stopping the NX server
+
+ bool connect(void);
+ void disconnect(void);
+
+ // Create a window. This method provides the general operations for
+ // creating a window that you can draw within.
+ //
+ // Those general operations are:
+ // 1) Create a dumb CWigetControl instance
+ // 2) Pass the dumb CWidgetControl instance to the window constructor
+ // that inherits from INxWindow. This will "smarten" the CWidgetControl
+ // instance with some window knowlede
+ // 3) Call the open() method on the window to display the window.
+ // 4) After that, the fully smartened CWidgetControl instance can
+ // be used to generate additional widgets by passing it to the
+ // widget constructor
+
+ bool createWindow(void);
+
+ // Create a CImage instance. This method will show you how to create
+ // a CImage widget
+
+ CImage *createImage(IBitmap *bitmap);
+
+ // Draw the image. This method illustrates how to draw the CImage widget.
+
+ void showImage(CImage *image);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+#endif // __UNITTESTS_CIMAGE_CIMAGETEST_HXX
diff --git a/NxWidgets/UnitTests/CImage/main.cxx b/NxWidgets/UnitTests/CImage/main.cxx
new file mode 100644
index 000000000..dd066b809
--- /dev/null
+++ b/NxWidgets/UnitTests/CImage/main.cxx
@@ -0,0 +1,222 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CImage/main.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <unistd.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "crlepalettebitmap.hxx"
+#include "glyphs.hxx"
+#include "cimagetest.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+static struct mallinfo g_mmInitial;
+static struct mallinfo g_mmprevious;
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+// Suppress name-mangling
+
+extern "C" int MAIN_NAME(int argc, char *argv[]);
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: showMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void showMemoryUsage(FAR struct mallinfo *mmbefore,
+ FAR struct mallinfo *mmafter)
+{
+ message("VARIABLE BEFORE AFTER\n");
+ message("======== ======== ========\n");
+ message("arena %8d %8d\n", mmbefore->arena, mmafter->arena);
+ message("ordblks %8d %8d\n", mmbefore->ordblks, mmafter->ordblks);
+ message("mxordblk %8d %8d\n", mmbefore->mxordblk, mmafter->mxordblk);
+ message("uordblks %8d %8d\n", mmbefore->uordblks, mmafter->uordblks);
+ message("fordblks %8d %8d\n", mmbefore->fordblks, mmafter->fordblks);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: updateMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void updateMemoryUsage(FAR struct mallinfo *previous,
+ FAR const char *msg)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ /* Show the change from the previous time */
+
+ message("\n%s:\n", msg);
+ showMemoryUsage(previous, &mmcurrent);
+
+ /* Set up for the next test */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ g_mmprevious = mmcurrent;
+#else
+ memcpy(&g_mmprevious, &mmcurrent, sizeof(struct mallinfo));
+#endif
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: initMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void initMemoryUsage(void)
+{
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ g_mmInitial = mallinfo();
+ g_mmprevious = g_mmInitial;
+#else
+ (void)mallinfo(&g_mmInitial);
+ memcpy(&g_mmprevious, &g_mmInitial, sizeof(struct mallinfo));
+#endif
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: user_start/nxheaders_main
+/////////////////////////////////////////////////////////////////////////////
+
+int MAIN_NAME(int argc, char *argv[])
+{
+ // Initialize memory monitor logic
+
+ initMemoryUsage();
+
+ // Create an instance of the font test
+
+ message(MAIN_STRING "Create CImageTest instance\n");
+ CImageTest *test = new CImageTest();
+ updateMemoryUsage(&g_mmprevious, "After creating CImageTest");
+
+ // Connect the NX server
+
+ message(MAIN_STRING "Connect the CImageTest instance to the NX server\n");
+ if (!test->connect())
+ {
+ message(MAIN_STRING "Failed to connect the CImageTest instance to the NX server\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(&g_mmprevious, "After connecting to the server");
+
+ // Create a window to draw into
+
+ message(MAIN_STRING "Create a Window\n");
+ if (!test->createWindow())
+ {
+ message(MAIN_STRING "Failed to create a window\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(&g_mmprevious, "After creating a window");
+
+ // Create an instance of the NuttX logo
+
+ CRlePaletteBitmap *nuttxBitmap = new CRlePaletteBitmap(&g_nuttxBitmap);
+ updateMemoryUsage(&g_mmprevious, "After creating the bitmap");
+
+ // Create a CImage instance
+
+ CImage *image = test->createImage(static_cast<IBitmap*>(nuttxBitmap));
+ if (!image)
+ {
+ message(MAIN_STRING "Failed to create a image\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(&g_mmprevious, "After creating CImage");
+
+ // Show the image
+
+ test->showImage(image);
+ updateMemoryUsage(&g_mmprevious, "After showing the image");
+ sleep(5);
+
+ // Clean up and exit
+
+ message(MAIN_STRING "Clean-up and exit\n");
+ delete image;
+ updateMemoryUsage(&g_mmprevious, "After deleting CImage");
+
+ delete nuttxBitmap;
+ updateMemoryUsage(&g_mmprevious, "After deleting the bitmap");
+
+ delete test;
+ updateMemoryUsage(&g_mmprevious, "After deleting the test");
+ updateMemoryUsage(&g_mmInitial, "Final memory usage");
+ return 0;
+}
+
diff --git a/NxWidgets/UnitTests/CKeypad/Makefile b/NxWidgets/UnitTests/CKeypad/Makefile
new file mode 100644
index 000000000..631be3b68
--- /dev/null
+++ b/NxWidgets/UnitTests/CKeypad/Makefile
@@ -0,0 +1,172 @@
+#################################################################################
+# NxWidgets/UnitTests/CKeyPad/Makefile
+#
+# Copyright (C) 2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+# me be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#################################################################################
+
+TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'}
+
+-include $(TOPDIR)/.config
+-include $(TOPDIR)/Make.defs
+include $(APPDIR)/Make.defs
+
+# Add the path to the NXWidget include directory to the CFLAGS
+
+NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets"
+NXWIDGETS_INC="$(NXWIDGETS_DIR)/include"
+NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)"
+
+INCDIR=$(TOPDIR)/tools/incdir.sh
+ifeq ($(WINTOOL),y)
+ CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"}
+else
+ CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"}
+endif
+
+# Get the path to the archiver tool
+
+TESTTOOL_DIR="$(TESTDIR)/../tools"
+ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh
+
+# Hello, World! C++ Example
+
+ASRCS =
+CSRCS =
+CXXSRCS = main.cxx ckeypadtest.cxx
+
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+COBJS = $(CSRCS:.c=$(OBJEXT))
+CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS)
+OBJS = $(AOBJS) $(COBJS) $(CXXOBJS)
+
+POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)"
+ifeq ($(WINTOOL),y)
+ BIN = "${shell cygpath -w $(POSIX_BIN)}"
+else
+ BIN = $(POSIX_BIN)
+endif
+
+ROOTDEPPATH = --dep-path .
+
+# helloxx built-in application info
+
+APPNAME = ckeypad
+PRIORITY = SCHED_PRIORITY_DEFAULT
+STACKSIZE = 2048
+
+# Common build
+
+VPATH =
+
+all: .built
+.PHONY: clean depend context disclean chkcxx chklib
+
+# Object file creation targets
+
+$(AOBJS): %$(OBJEXT): %.S
+ $(call ASSEMBLE, $<, $@)
+
+$(COBJS): %$(OBJEXT): %.c
+ $(call COMPILE, $<, $@)
+
+$(CXXOBJS): %$(OBJEXT): %.cxx
+ $(call COMPILEXX, $<, $@)
+
+# Verify that the NuttX configuration is setup to support C++
+
+chkcxx:
+ifneq ($(CONFIG_HAVE_CXX),y)
+ @echo ""
+ @echo "In order to use this example, you toolchain must support must"
+ @echo ""
+ @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support"
+ @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file"
+ @echo " of the configuration that you are using."
+ @echo ""
+ @exit 1
+endif
+
+# Verify that the NXWidget library has been built
+
+chklib:
+ @( \
+ if [ ! -e "$(NXWIDGETS_LIB)" ]; then \
+ echo "$(NXWIDGETS_LIB) does not exist."; \
+ echo "Please go to $(NXWIDGETS_DIR)"; \
+ echo "and rebuild the library"; \
+ exit 1; \
+ fi; \
+ )
+
+# Library creation targets
+
+$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work.
+
+.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB)
+ @( for obj in $(OBJS) ; do \
+ $(call ARCHIVE, $(BIN), $${obj}); \
+ done ; )
+ifeq ($(WINTOOL),y)
+ @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+else
+ @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+endif
+ @touch .built
+
+# Standard housekeeping targets
+
+.context:
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+ $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
+endif
+ @touch $@
+
+context: .context
+
+.depend: Makefile $(SRCS)
+ @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep
+ @touch $@
+
+depend: .depend
+
+clean:
+ @rm -f *.o *~ .*.swp .built
+ $(call CLEAN)
+
+distclean: clean
+ @rm -f Make.dep .depend
+
+-include Make.dep
diff --git a/NxWidgets/UnitTests/CKeypad/ckeypadtest.cxx b/NxWidgets/UnitTests/CKeypad/ckeypadtest.cxx
new file mode 100644
index 000000000..5d3eeda2a
--- /dev/null
+++ b/NxWidgets/UnitTests/CKeypad/ckeypadtest.cxx
@@ -0,0 +1,458 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CKeypad/ckeypadtest.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cerrno>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+#include <nuttx/nx/nxfonts.h>
+
+#include "nxconfig.hxx"
+#include "ckeypadtest.hxx"
+#include "cbgwindow.hxx"
+#include "cnxstring.hxx"
+#include "cnxfont.hxx"
+#include "crect.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// CKeypadTest Method Implementations
+/////////////////////////////////////////////////////////////////////////////
+
+// CKeypadTest Constructor
+
+CKeypadTest::CKeypadTest()
+{
+ m_widgetControl = (CWidgetControl *)NULL;
+ m_bgWindow = (CBgWindow *)NULL;
+ m_buttonWidth = 0;
+ m_buttonHeight = 0;
+ m_displayHeight = 0;
+}
+
+// CKeypadTest Descriptor
+
+CKeypadTest::~CKeypadTest()
+{
+ disconnect();
+}
+
+// Connect to the NX server
+
+bool CKeypadTest::connect(void)
+{
+ // Connect to the server
+
+ bool nxConnected = CNxServer::connect();
+ if (nxConnected)
+ {
+ // Set the background color
+
+ if (!setBackgroundColor(CONFIG_CKEYPADTEST_BGCOLOR))
+ {
+ message("CKeypadTest::connect: setBackgroundColor failed\n");
+ }
+ }
+
+ return nxConnected;
+}
+
+// Disconnect from the NX server
+
+void CKeypadTest::disconnect(void)
+{
+ // Destroy the text box
+
+ if (m_textbox)
+ {
+ delete m_textbox;
+ }
+
+ // Close the window
+
+ if (m_bgWindow)
+ {
+ delete m_bgWindow;
+ }
+
+ // Destroy the widget control
+
+ if (m_widgetControl)
+ {
+ delete m_widgetControl;
+ }
+
+ // And disconnect from the server
+
+ CNxServer::disconnect();
+}
+
+// Create the background window instance. This function illustrates
+// the basic steps to instantiate any window:
+//
+// 1) Create a dumb CWigetControl instance
+// 2) Pass the dumb CWidgetControl instance to the window constructor
+// that inherits from INxWindow. This will "smarten" the CWidgetControl
+// instance with some window knowlede
+// 3) Call the open() method on the window to display the window.
+// 4) After that, the fully smartened CWidgetControl instance can
+// be used to generate additional widgets by passing it to the
+// widget constructor
+
+bool CKeypadTest::createWindow(void)
+{
+ // Initialize the widget control using the default style
+
+ m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL);
+
+ // Get an (uninitialized) instance of the background window as a class
+ // that derives from INxWindow.
+
+ m_bgWindow = getBgWindow(m_widgetControl);
+ if (!m_bgWindow)
+ {
+ message("CKeypadTest::createGraphics: Failed to create CBgWindow instance\n");
+ delete m_widgetControl;
+ return false;
+ }
+
+ // Open (and initialize) the window
+
+ bool success = m_bgWindow->open();
+ if (!success)
+ {
+ message("CKeypadTest::createGraphics: Failed to open background window\n");
+ delete m_bgWindow;
+ m_bgWindow = (CBgWindow*)0;
+ return false;
+ }
+
+ // Then determine the display size
+
+ setDisplaySize();
+ return true;
+}
+
+// Pick size of the display
+
+void CKeypadTest::setDisplaySize(void)
+{
+ // Get the height and width of the display
+
+ struct nxgl_size_s windowSize;
+ if (!m_bgWindow->getSize(&windowSize))
+ {
+ message("CKeypadTest::createGraphics: Failed to get window size\n");
+ return;
+ }
+
+ // Pick a height and width of a button. Here we use inside information
+ // that the number of rows and columns in the keypad. This should not matter in
+ // a "real" application.
+
+ // Lets aim for a width of 4*60 = 240
+
+ if (windowSize.w > KEYPAD_NCOLUMNS*60)
+ {
+ m_buttonWidth = 60;
+ }
+ else
+ {
+ // Otherwise, let's use what we have
+
+ m_buttonWidth = windowSize.w >> 2;
+ }
+
+ // Lets aim for a height of 7*32 = 224. But lets bump up the number of rows
+ // to allow one for the text box.
+
+ if (windowSize.h > (KEYPAD_NROWS+1)*32)
+ {
+ m_buttonHeight = 32;
+ m_displayHeight = (KEYPAD_NROWS+1)*32;
+ }
+ else
+ {
+ // Otherwise, let's use what we have
+
+ m_buttonHeight = windowSize.h >> 3;
+ m_displayHeight = windowSize.h;
+ }
+}
+
+// Create a CKeypad instance
+
+CKeypad *CKeypadTest::createKeypad(void)
+{
+ // Get the height and width of the display
+
+ struct nxgl_size_s windowSize;
+ if (!m_bgWindow->getSize(&windowSize))
+ {
+ message("CKeypadTest::createGraphics: Failed to get window size\n");
+ return (CKeypad *)NULL;
+ }
+
+ // Pick a height and width. Here we use inside information that the number
+ // of rows in the keypad is 7. This should not matter in a "real" application.
+
+ nxgl_coord_t keypadWidth = KEYPAD_NCOLUMNS * m_buttonWidth;
+ nxgl_coord_t keypadHeight = KEYPAD_NROWS * m_buttonHeight;
+
+ // Pick an X/Y position such that the keypad will be centered in the display
+
+ nxgl_coord_t keypadOffset = m_displayHeight - keypadHeight;
+
+ nxgl_coord_t keypadX = (windowSize.w - keypadWidth) >> 1;
+ nxgl_coord_t keypadY = keypadOffset + ((windowSize.h - m_displayHeight) >> 1);
+
+ // Now we have enough information to create the keypad
+
+ CKeypad *keypad = new CKeypad(m_widgetControl, getServer(), keypadX, keypadY,
+ keypadWidth, keypadHeight);
+ if (keypad)
+ {
+ // Create a text box to catch the keyboard inputs
+
+ m_textbox = createTextBox();
+ if (!m_textbox)
+ {
+ delete keypad;
+ keypad = (CKeypad *)NULL;
+ }
+ else
+ {
+ // Always show the cursor and wrap the cursor if it goes past the end
+
+ m_textbox->showCursor(SHOW_CURSOR_ALWAYS);
+ m_textbox->wrapCursor(true);
+
+ // Align text on the left
+
+ m_textbox->setTextAlignmentHoriz(CTextBox::TEXT_ALIGNMENT_HORIZ_LEFT);
+
+ // Configure the text box to receive the keyboard input
+
+ keypad->addWidgetEventHandler(m_textbox);
+ }
+ }
+
+ return keypad;
+}
+
+// Create a CTextBox instance so that we can see the keypad output
+
+CTextBox *CKeypadTest::createTextBox(void)
+{
+ // Get the height and width of the display
+
+ struct nxgl_size_s windowSize;
+ if (!m_bgWindow->getSize(&windowSize))
+ {
+ message("CKeypadTest::createGraphics: Failed to get window size\n");
+ return (CTextBox *)NULL;
+ }
+
+ // Pick a height and width. Here we use inside information that the number
+ // of rows in the keypad is 7. This should not matter in a "real" application.
+
+ nxgl_coord_t textboxWidth = KEYPAD_NCOLUMNS * m_buttonWidth;
+ nxgl_coord_t textboxHeight = m_displayHeight - KEYPAD_NROWS * m_buttonHeight;
+
+ // Pick an X/Y position such that the keypad will be centered in the display
+
+ nxgl_coord_t textboxX = (windowSize.w - textboxWidth) >> 1;
+ nxgl_coord_t textboxY = (windowSize.h - m_displayHeight) >> 1;
+
+ // Now we have enough information to create the TextBox
+
+ return new CTextBox(m_widgetControl, textboxX, textboxY,
+ textboxWidth, textboxHeight, "");
+}
+
+// Draw the keypad
+
+void CKeypadTest::showKeypad(CKeypad *keypad)
+{
+ // Re-draw the keypad
+
+ keypad->enable(); // Un-necessary, the widget is enabled by default
+ keypad->enableDrawing();
+ keypad->redraw();
+
+ // Then redraw the text box
+
+ m_textbox->enable(); // Un-necessary, the widget is enabled by default
+ m_textbox->enableDrawing();
+ m_textbox->redraw();
+}
+
+// Perform a simulated mouse click on a button in the array. This method injects
+// the mouse click through the NX heirarchy just as would real mouse
+// hardward.
+
+void CKeypadTest::click(CKeypad *keypad, int column, int row)
+{
+ // nx_mousein is meant to be called by mouse handling software.
+ // Here we just inject a left-button click directly in the center of
+ // the selected button.
+
+ // First, get the server handle. Graphics software will never care
+ // about the server handle. Here we need it to get access to the
+ // low-level mouse interface
+
+ NXHANDLE handle = getServer();
+
+ // The the coorinates of the center of the button
+
+ nxgl_coord_t buttonX = keypad->getX() + column * m_buttonWidth + (m_buttonWidth >> 1);
+ nxgl_coord_t buttonY = keypad->getY() + row * m_buttonHeight + (m_buttonHeight >> 1);
+
+ // Then inject the mouse click
+
+ (void)nx_mousein(handle, buttonX, buttonY, NX_MOUSE_LEFTBUTTON);
+}
+
+// The counterpart to click. This simulates a button release through
+// the same mechanism.
+
+void CKeypadTest::release(CKeypad *keypad, int column, int row)
+{
+ // nx_mousein is meant to be called by mouse handling software.
+ // Here we just inject a left-button click directly in the center of
+ // the button.
+
+ // First, get the server handle. Graphics software will never care
+ // about the server handle. Here we need it to get access to the
+ // low-level mouse interface
+
+ NXHANDLE handle = getServer();
+
+ // The the coorinates of the center of the button
+
+ nxgl_coord_t buttonX = keypad->getX() +
+ column * m_buttonWidth +
+ m_buttonWidth/2;
+ nxgl_coord_t buttonY = keypad->getY() +
+ row * m_buttonHeight +
+ m_buttonHeight/2;
+
+ // Then inject the mouse release
+
+ (void)nx_mousein(handle, buttonX, buttonY, NX_MOUSE_NOBUTTONS);
+}
+
+// Widget events are normally handled in a modal loop (by calling goModal()).
+// However, for this case we know when there should be press and release
+// events so we don't have to poll. We can just perform a one pass poll
+// then check if the event was processed corredly.
+
+void CKeypadTest::poll(CKeypad *button)
+{
+ // Poll for mouse events
+
+ m_widgetControl->pollEvents(button);
+
+ // Limit the amount of text in the TextBox
+
+ reverseAlignment();
+}
+
+// Start with left text alignment. When the text reaches the right sice
+// of the text box, switch to right text alignment.
+
+void CKeypadTest::reverseAlignment(void)
+{
+ // Get the current horizontal text alignment
+
+ CTextBox::TextAlignmentHoriz hAlign = m_textbox->getTextAlignmentHoriz();
+
+ // Are we still using left text alignment?
+
+ if (hAlign == CTextBox::TEXT_ALIGNMENT_HORIZ_LEFT)
+ {
+ // Yes.. Get the string in the text box
+
+ CNxString string = m_textbox->getText();
+
+ // Get the font
+
+ CNxFont *font = m_textbox->getFont();
+
+ // Get the TextBox bounding box
+
+ CRect rect;
+ m_textbox->getRect(rect);
+
+ // When the length of string approaches the width of the display
+ // region, then switch to right text alignment
+
+ int mxWidth = font->getMaxWidth();
+ if (font->getStringWidth(string) + mxWidth >= rect.getWidth())
+ {
+ // Switch to right text alignment
+
+ m_textbox->setTextAlignmentHoriz(CTextBox::TEXT_ALIGNMENT_HORIZ_RIGHT);
+ }
+ }
+}
+
diff --git a/NxWidgets/UnitTests/CKeypad/ckeypadtest.hxx b/NxWidgets/UnitTests/CKeypad/ckeypadtest.hxx
new file mode 100644
index 000000000..820113960
--- /dev/null
+++ b/NxWidgets/UnitTests/CKeypad/ckeypadtest.hxx
@@ -0,0 +1,192 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CKeypad/ckeypadtest.hxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef __UNITTESTS_CKEYPAD_CKEYPADTEST_HXX
+#define __UNITTESTS_CKEYPAD_CKEYPADTEST_HXX
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <semaphore.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "nxconfig.hxx"
+#include "cwidgetcontrol.hxx"
+#include "ccallback.hxx"
+#include "cbgwindow.hxx"
+#include "cnxserver.hxx"
+#include "cnxfont.hxx"
+#include "cnxstring.hxx"
+#include "ctextbox.hxx"
+#include "ckeypad.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+// Configuration ////////////////////////////////////////////////////////////
+
+#ifndef CONFIG_HAVE_CXX
+# error "CONFIG_HAVE_CXX must be defined"
+#endif
+
+#ifndef CONFIG_CKEYPADTEST_BGCOLOR
+# define CONFIG_CKEYPADTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR
+#endif
+
+// What is the entry point called?
+
+#ifdef CONFIG_NSH_BUILTIN_APPS
+# define MAIN_NAME ckeypad_main
+# define MAIN_STRING "ckeypad_main: "
+#else
+# define MAIN_NAME user_start
+# define MAIN_STRING "user_start: "
+#endif
+
+// If debug is enabled, use the debug function, lib_rawprintf() instead
+// of printf() so that the output is synchronized.
+
+#ifdef CONFIG_DEBUG
+# define message lib_lowprintf
+#else
+# define message printf
+#endif
+
+// This is the size of the keypad
+
+#define KEYPAD_NROWS 7
+#define KEYPAD_NCOLUMNS 4
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Classes
+/////////////////////////////////////////////////////////////////////////////
+
+using namespace NXWidgets;
+
+class CKeypadTest : public CNxServer
+{
+private:
+ CWidgetControl *m_widgetControl; // The widget control for the window
+ CBgWindow *m_bgWindow; // Background window instance
+ CTextBox *m_textbox; // TextBox to show the key presses
+ nxgl_coord_t m_buttonWidth; // The width of one button
+ nxgl_coord_t m_buttonHeight; // The height of one button
+ nxgl_coord_t m_displayHeight; // The height of the display
+
+ // Pick size of the display
+
+ void setDisplaySize(void);
+
+ // Start with left text alignment. When the text reaches the right sice
+ // of the text box, switch to right text alignment.
+
+ void reverseAlignment(void);
+
+ // Create a CTextBox instance so that we can see the keypad output
+
+ CTextBox *createTextBox(void);
+
+public:
+
+ // Constructor/destructors
+
+ CKeypadTest();
+ ~CKeypadTest();
+
+ // Initializer/unitializer. These methods encapsulate the basic steps for
+ // starting and stopping the NX server
+
+ bool connect(void);
+ void disconnect(void);
+
+ // Create a window. This method provides the general operations for
+ // creating a window that you can draw within.
+ //
+ // Those general operations are:
+ // 1) Create a dumb CWigetControl instance
+ // 2) Pass the dumb CWidgetControl instance to the window constructor
+ // that inherits from INxWindow. This will "smarten" the CWidgetControl
+ // instance with some window knowlede
+ // 3) Call the open() method on the window to display the window.
+ // 4) After that, the fully smartened CWidgetControl instance can
+ // be used to generate additional widgets by passing it to the
+ // widget constructor
+
+ bool createWindow(void);
+
+ // Create a CKeypad instance. This method will show you how to create
+ // a CKeypad widget
+
+ CKeypad *createKeypad(void);
+
+ // Draw the keypad. This method illustrates how to draw the CKeypad widget.
+
+ void showKeypad(CKeypad *keypad);
+
+ // Perform a simulated mouse click on a button in the array. This method injects
+ // the mouse click through the NX heirarchy just as would real mouse
+ // hardward.
+
+ void click(CKeypad *keypad, int column, int row);
+
+ // The counterpart to click. This simulates a button release through
+ // the same mechanism.
+
+ void release(CKeypad *keypad, int column, int row);
+
+ // Widget events are normally handled in a model loop (by calling goModel()).
+ // However, for this case we know when there should be press and release
+ // events so we don't have to poll. We can just perform a one pass poll
+ // then check if the event was processed corredly.
+
+ void poll(CKeypad *keypad);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+#endif // __UNITTESTS_CKEYPAD_CKEYPADTEST_HXX
diff --git a/NxWidgets/UnitTests/CKeypad/main.cxx b/NxWidgets/UnitTests/CKeypad/main.cxx
new file mode 100644
index 000000000..1c7679ee2
--- /dev/null
+++ b/NxWidgets/UnitTests/CKeypad/main.cxx
@@ -0,0 +1,274 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CKeypad/main.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cstdlib>
+#include <unistd.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "cnxstring.hxx"
+#include "ckeypadtest.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+static unsigned int g_mmInitial;
+static unsigned int g_mmPrevious;
+static unsigned int g_mmPeak;
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+// Suppress name-mangling
+
+extern "C" int MAIN_NAME(int argc, char *argv[]);
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: updateMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void updateMemoryUsage(unsigned int previous,
+ FAR const char *msg)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ /* Show the change from the previous time */
+
+ message("%s: Before: %8d After: %8d Change: %8d\n",
+ msg, previous, mmcurrent.uordblks, mmcurrent.uordblks - previous);
+
+ /* Set up for the next test */
+
+ g_mmPrevious = mmcurrent.uordblks;
+ if ((unsigned int)mmcurrent.uordblks > g_mmPeak)
+ {
+ g_mmPeak = mmcurrent.uordblks;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: initMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void initMemoryUsage(void)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ g_mmInitial = mmcurrent.uordblks;
+ g_mmPrevious = mmcurrent.uordblks;
+ g_mmPeak = mmcurrent.uordblks;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: clickButtons
+/////////////////////////////////////////////////////////////////////////////
+
+static void clickButtons(CKeypadTest *test, CKeypad *keypad)
+{
+ // Perform a simulated mouse click on a button in the keypad
+
+ for (int j = 0; j < KEYPAD_NROWS; j++)
+ {
+ for (int i = 0; i < KEYPAD_NCOLUMNS; i++)
+ {
+ printf(MAIN_STRING "Click the button (%d,%d)\n", i, j);
+ test->click(keypad, i, j);
+
+ // Poll for the mouse click event
+
+ test->poll(keypad);
+
+ // Is anything clicked?
+
+ int clickColumn;
+ int clickRow;
+ if (keypad->isButtonClicked(clickColumn, clickRow))
+ {
+ printf(MAIN_STRING "%s: Button (%d, %d) is clicked\n",
+ clickColumn == i && clickRow == j ? "OK" : "ERROR",
+ clickColumn, clickRow);
+ }
+ else
+ {
+ printf(MAIN_STRING "ERROR: No button is clicked\n");
+ }
+
+ // Wait a bit, then release the mouse button
+
+ usleep(250*1000);
+ test->release(keypad, i, j);
+
+ // Poll for the mouse release event (of course this can hang if something fails)
+
+ test->poll(keypad);
+ if (keypad->isButtonClicked(clickColumn, clickRow))
+ {
+ printf(MAIN_STRING "ERROR: Button (%d, %d) is clicked\n",
+ clickColumn, clickRow);
+ }
+
+ usleep(500*1000);
+ }
+ }
+ updateMemoryUsage(g_mmPrevious, "After pushing buttons");
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// user_start/nxheaders_main
+/////////////////////////////////////////////////////////////////////////////
+
+int MAIN_NAME(int argc, char *argv[])
+{
+ // Initialize memory monitor logic
+
+ initMemoryUsage();
+
+ // Create an instance of the keypad test
+
+ printf(MAIN_STRING "Create CKeypadTest instance\n");
+ CKeypadTest *test = new CKeypadTest();
+ updateMemoryUsage(g_mmPrevious, "After creating CKeypadTest");
+
+ // Connect the NX server
+
+ printf(MAIN_STRING "Connect the CKeypadTest instance to the NX server\n");
+ if (!test->connect())
+ {
+ printf(MAIN_STRING "Failed to connect the CKeypadTest instance to the NX server\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmPrevious, "After connecting to the server");
+
+ // Create a window to draw into
+
+ printf(MAIN_STRING "Create a Window\n");
+ if (!test->createWindow())
+ {
+ printf(MAIN_STRING "Failed to create a window\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmPrevious, "After creating a window");
+
+ // Create a CKeypad instance
+
+ CKeypad *keypad = test->createKeypad();
+ if (!keypad)
+ {
+ printf(MAIN_STRING "Failed to create a keypad\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmPrevious, "After creating CKeypad");
+
+ // Show the keypad in alphabetic mode
+
+ printf(MAIN_STRING "Show the keypad in alphabetic mode\n");
+ keypad->setKeypadMode(false);
+ test->showKeypad(keypad);
+ sleep(1);
+
+ // Then click some buttons
+
+ clickButtons(test, keypad);
+ sleep(1);
+
+ // Show the keypad in numeric mode
+
+ printf(MAIN_STRING "Show the keypad in numeric mode\n");
+ keypad->setKeypadMode(true);
+ sleep(1);
+
+ // Then click some buttons
+
+ clickButtons(test, keypad);
+ sleep(1);
+
+ // Clean up and exit
+
+ printf(MAIN_STRING "Clean-up and exit\n");
+ delete keypad;
+ updateMemoryUsage(g_mmPrevious, "After deleting the keypad");
+ delete test;
+ updateMemoryUsage(g_mmPrevious, "After deleting the test");
+ updateMemoryUsage(g_mmInitial, "Final memory usage");
+ message("Peak memory usage: %8d\n", g_mmPeak - g_mmInitial);
+ return 0;
+}
+
diff --git a/NxWidgets/UnitTests/CLabel/Makefile b/NxWidgets/UnitTests/CLabel/Makefile
new file mode 100644
index 000000000..163d04175
--- /dev/null
+++ b/NxWidgets/UnitTests/CLabel/Makefile
@@ -0,0 +1,172 @@
+#################################################################################
+# NxWidgets/UnitTests/CLabel/Makefile
+#
+# Copyright (C) 2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+# me be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#################################################################################
+
+TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'}
+
+-include $(TOPDIR)/.config
+-include $(TOPDIR)/Make.defs
+include $(APPDIR)/Make.defs
+
+# Add the path to the NXWidget include directory to the CFLAGS
+
+NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets"
+NXWIDGETS_INC="$(NXWIDGETS_DIR)/include"
+NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)"
+
+INCDIR=$(TOPDIR)/tools/incdir.sh
+ifeq ($(WINTOOL),y)
+ CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"}
+else
+ CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"}
+endif
+
+# Get the path to the archiver tool
+
+TESTTOOL_DIR="$(TESTDIR)/../tools"
+ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh
+
+# Hello, World! C++ Example
+
+ASRCS =
+CSRCS =
+CXXSRCS = main.cxx clabeltest.cxx
+
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+COBJS = $(CSRCS:.c=$(OBJEXT))
+CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS)
+OBJS = $(AOBJS) $(COBJS) $(CXXOBJS)
+
+POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)"
+ifeq ($(WINTOOL),y)
+ BIN = "${shell cygpath -w $(POSIX_BIN)}"
+else
+ BIN = $(POSIX_BIN)
+endif
+
+ROOTDEPPATH = --dep-path .
+
+# helloxx built-in application info
+
+APPNAME = clabel
+PRIORITY = SCHED_PRIORITY_DEFAULT
+STACKSIZE = 2048
+
+# Common build
+
+VPATH =
+
+all: .built
+.PHONY: clean depend context disclean chkcxx chklib
+
+# Object file creation targets
+
+$(AOBJS): %$(OBJEXT): %.S
+ $(call ASSEMBLE, $<, $@)
+
+$(COBJS): %$(OBJEXT): %.c
+ $(call COMPILE, $<, $@)
+
+$(CXXOBJS): %$(OBJEXT): %.cxx
+ $(call COMPILEXX, $<, $@)
+
+# Verify that the NuttX configuration is setup to support C++
+
+chkcxx:
+ifneq ($(CONFIG_HAVE_CXX),y)
+ @echo ""
+ @echo "In order to use this example, you toolchain must support must"
+ @echo ""
+ @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support"
+ @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file"
+ @echo " of the configuration that you are using."
+ @echo ""
+ @exit 1
+endif
+
+# Verify that the NXWidget library has been built
+
+chklib:
+ @( \
+ if [ ! -e "$(NXWIDGETS_LIB)" ]; then \
+ echo "$(NXWIDGETS_LIB) does not exist."; \
+ echo "Please go to $(NXWIDGETS_DIR)"; \
+ echo "and rebuild the library"; \
+ exit 1; \
+ fi; \
+ )
+
+# Library creation targets
+
+$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work.
+
+.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB)
+ @( for obj in $(OBJS) ; do \
+ $(call ARCHIVE, $(BIN), $${obj}); \
+ done ; )
+ifeq ($(WINTOOL),y)
+ @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+else
+ @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+endif
+ @touch .built
+
+# Standard housekeeping targets
+
+.context:
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+ $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
+endif
+ @touch $@
+
+context: .context
+
+.depend: Makefile $(SRCS)
+ @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep
+ @touch $@
+
+depend: .depend
+
+clean:
+ @rm -f *.o *~ .*.swp .built
+ $(call CLEAN)
+
+distclean: clean
+ @rm -f Make.dep .depend
+
+-include Make.dep
diff --git a/NxWidgets/UnitTests/CLabel/clabeltest.cxx b/NxWidgets/UnitTests/CLabel/clabeltest.cxx
new file mode 100644
index 000000000..ef78cc3ce
--- /dev/null
+++ b/NxWidgets/UnitTests/CLabel/clabeltest.cxx
@@ -0,0 +1,263 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CLabel/clabeltest.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cerrno>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+#include <nuttx/nx/nxfonts.h>
+
+#include "nxconfig.hxx"
+#include "clabeltest.hxx"
+#include "cbgwindow.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// CLabelTest Method Implementations
+/////////////////////////////////////////////////////////////////////////////
+
+// CLabelTest Constructor
+
+CLabelTest::CLabelTest()
+{
+ m_bgWindow = (CBgWindow *)NULL;
+ m_nxFont = (CNxFont *)NULL;
+ m_text = (CNxString *)NULL;
+}
+
+// CLabelTest Descriptor
+
+CLabelTest::~CLabelTest()
+{
+ disconnect();
+}
+
+// Connect to the NX server
+
+bool CLabelTest::connect(void)
+{
+ // Connect to the server
+
+ bool nxConnected = CNxServer::connect();
+ if (nxConnected)
+ {
+ // Create the default font instance
+
+ m_nxFont = new CNxFont(NXFONT_DEFAULT,
+ CONFIG_NXWIDGETS_DEFAULT_FONTCOLOR,
+ CONFIG_NXWIDGETS_TRANSPARENT_COLOR);
+ if (!m_nxFont)
+ {
+ printf("CLabelTest::connect: Failed to create the default font\n");
+ }
+
+ // Set the background color
+
+ if (!setBackgroundColor(CONFIG_CLABELTEST_BGCOLOR))
+ {
+ printf("CLabelTest::connect: setBackgroundColor failed\n");
+ }
+ }
+
+ return nxConnected;
+}
+
+// Disconnect from the NX server
+
+void CLabelTest::disconnect(void)
+{
+ // Close the window
+
+ if (m_bgWindow)
+ {
+ delete m_bgWindow;
+ }
+
+ // Free the display string
+
+ if (m_text)
+ {
+ delete m_text;
+ m_text = (CNxString *)NULL;
+ }
+
+ // Free the default font
+
+ if (m_nxFont)
+ {
+ delete m_nxFont;
+ m_nxFont = (CNxFont *)NULL;
+ }
+
+ // And disconnect from the server
+
+ CNxServer::disconnect();
+}
+
+// Create the background window instance. This function illustrates
+// the basic steps to instantiate any window:
+//
+// 1) Create a dumb CWigetControl instance
+// 2) Pass the dumb CWidgetControl instance to the window constructor
+// that inherits from INxWindow. This will "smarten" the CWidgetControl
+// instance with some window knowlede
+// 3) Call the open() method on the window to display the window.
+// 4) After that, the fully smartened CWidgetControl instance can
+// be used to generate additional widgets by passing it to the
+// widget constructor
+
+bool CLabelTest::createWindow(void)
+{
+ // Initialize the widget control using the default style
+
+ m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL);
+
+ // Get an (uninitialized) instance of the background window as a class
+ // that derives from INxWindow.
+
+ m_bgWindow = getBgWindow(m_widgetControl);
+ if (!m_bgWindow)
+ {
+ printf("CLabelTest::createGraphics: Failed to create CBgWindow instance\n");
+ delete m_widgetControl;
+ return false;
+ }
+
+ // Open (and initialize) the window
+
+ bool success = m_bgWindow->open();
+ if (!success)
+ {
+ printf("CLabelTest::createGraphics: Failed to open background window\n");
+ delete m_bgWindow;
+ m_bgWindow = (CBgWindow*)0;
+ return false;
+ }
+
+ return true;
+}
+
+// Create a CLabel instance
+
+CLabel *CLabelTest::createLabel(FAR const char *text)
+{
+ // Get the width of the display
+
+ struct nxgl_size_s windowSize;
+ if (!m_bgWindow->getSize(&windowSize))
+ {
+ printf("CLabelTest::createGraphics: Failed to get window size\n");
+ return (CLabel *)NULL;
+ }
+
+ // Create a CNxString instance to contain the C string
+
+ m_text = new CNxString(text);
+
+ // Get the height and width of the text display area
+
+ nxgl_coord_t stringWidth = m_nxFont->getStringWidth(*m_text);
+ nxgl_coord_t stringHeight = (nxgl_coord_t)m_nxFont->getHeight();
+
+ // The default CLabel has borders enabled with thickness of the border
+ // width. Add twice the thickness of the border to the width and height. (We
+ // could let CLabel do this for us by calling CLabel::getPreferredDimensions())
+
+ stringWidth += 2 * 1;
+ stringHeight += 2 * 1;
+
+ // Pick an X/Y position such that the label will be centered in the display
+
+ nxgl_coord_t labelX;
+ if (stringWidth >= windowSize.w)
+ {
+ labelX = 0;
+ }
+ else
+ {
+ labelX = (windowSize.w - stringWidth) >> 1;
+ }
+
+ nxgl_coord_t labelY;
+ if (stringHeight >= windowSize.h)
+ {
+ labelY = 0;
+ }
+ else
+ {
+ labelY = (windowSize.h - stringHeight) >> 1;
+ }
+
+ // Now we have enough information to create the label
+
+ return new CLabel(m_widgetControl, labelX, labelY, stringWidth, stringHeight, *m_text);
+}
+
+// Draw the label
+
+void CLabelTest::showLabel(CLabel *label)
+{
+ label->enable();
+ label->enableDrawing();
+ label->redraw();
+ label->disableDrawing();
+}
diff --git a/NxWidgets/UnitTests/CLabel/clabeltest.hxx b/NxWidgets/UnitTests/CLabel/clabeltest.hxx
new file mode 100644
index 000000000..2d404b2df
--- /dev/null
+++ b/NxWidgets/UnitTests/CLabel/clabeltest.hxx
@@ -0,0 +1,148 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CLabel/clabeltest.hxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef __UNITTESTS_CLABEL_CLABELTEST_HXX
+#define __UNITTESTS_CLABEL_CLABELTEST_HXX
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <semaphore.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "nxconfig.hxx"
+#include "cwidgetcontrol.hxx"
+#include "ccallback.hxx"
+#include "cbgwindow.hxx"
+#include "cnxserver.hxx"
+#include "cnxfont.hxx"
+#include "cnxstring.hxx"
+#include "clabel.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+// Configuration ////////////////////////////////////////////////////////////
+
+#ifndef CONFIG_HAVE_CXX
+# error "CONFIG_HAVE_CXX must be defined"
+#endif
+
+#ifndef CONFIG_CLABELTEST_BGCOLOR
+# define CONFIG_CLABELTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR
+#endif
+
+#ifndef CONFIG_CLABELTEST_FONTCOLOR
+# define CONFIG_CLABELTEST_FONTCOLOR CONFIG_NXWIDGETS_DEFAULT_FONTCOLOR
+#endif
+
+// What is the entry point called?
+
+#ifdef CONFIG_NSH_BUILTIN_APPS
+# define MAIN_NAME clabel_main
+# define MAIN_STRING "clabel_main: "
+#else
+# define MAIN_NAME user_start
+# define MAIN_STRING "user_start: "
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Classes
+/////////////////////////////////////////////////////////////////////////////
+
+using namespace NXWidgets;
+
+class CLabelTest : public CNxServer
+{
+private:
+ CWidgetControl *m_widgetControl; // The controlling widget for the window
+ CNxFont *m_nxFont; // Default font
+ CBgWindow *m_bgWindow; // Background window instance
+ CNxString *m_text; // The label string
+
+public:
+ // Constructor/destructors
+
+ CLabelTest();
+ ~CLabelTest();
+
+ // Initializer/unitializer. These methods encapsulate the basic steps for
+ // starting and stopping the NX server
+
+ bool connect(void);
+ void disconnect(void);
+
+ // Create a window. This method provides the general operations for
+ // creating a window that you can draw within.
+ //
+ // Those general operations are:
+ // 1) Create a dumb CWigetControl instance
+ // 2) Pass the dumb CWidgetControl instance to the window constructor
+ // that inherits from INxWindow. This will "smarten" the CWidgetControl
+ // instance with some window knowlede
+ // 3) Call the open() method on the window to display the window.
+ // 4) After that, the fully smartened CWidgetControl instance can
+ // be used to generate additional widgets by passing it to the
+ // widget constructor
+
+ bool createWindow(void);
+
+ // Create a CLabel instance. This method will show you how to create
+ // a CLabel widget
+
+ CLabel *createLabel(FAR const char *text);
+
+ // Draw the label. This method illustrates how to draw the CLabel widget.
+
+ void showLabel(CLabel *label);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+
+#endif // __UNITTESTS_CLABEL_CLABELTEST_HXX
diff --git a/NxWidgets/UnitTests/CLabel/main.cxx b/NxWidgets/UnitTests/CLabel/main.cxx
new file mode 100644
index 000000000..953e6afbc
--- /dev/null
+++ b/NxWidgets/UnitTests/CLabel/main.cxx
@@ -0,0 +1,130 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CLabel/main.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <unistd.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "clabeltest.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+static const char g_hello[] = "Hello, World!";
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+// Suppress name-mangling
+
+extern "C" int MAIN_NAME(int argc, char *argv[]);
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// user_start/nxheaders_main
+/////////////////////////////////////////////////////////////////////////////
+
+int MAIN_NAME(int argc, char *argv[])
+{
+ // Create an instance of the font test
+
+ printf(MAIN_STRING "Create CLabelTest instance\n");
+ CLabelTest *test = new CLabelTest();
+
+ // Connect the NX server
+
+ printf(MAIN_STRING "Connect the CLabelTest instance to the NX server\n");
+ if (!test->connect())
+ {
+ printf(MAIN_STRING "Failed to connect the CLabelTest instance to the NX server\n");
+ delete test;
+ return 1;
+ }
+
+ // Create a window to draw into
+
+ printf(MAIN_STRING "Create a Window\n");
+ if (!test->createWindow())
+ {
+ printf(MAIN_STRING "Failed to create a window\n");
+ delete test;
+ return 1;
+ }
+
+ // Create a CLabel instance
+
+ CLabel *label = test->createLabel(g_hello);
+ if (!label)
+ {
+ printf(MAIN_STRING "Failed to create a label\n");
+ delete test;
+ return 1;
+ }
+
+ // Show the label
+
+ test->showLabel(label);
+ sleep(5);
+
+ // Clean up and exit
+
+ printf(MAIN_STRING "Clean-up and exit\n");
+ delete label;
+ delete test;
+ return 0;
+}
+
diff --git a/NxWidgets/UnitTests/CLatchButton/Makefile b/NxWidgets/UnitTests/CLatchButton/Makefile
new file mode 100644
index 000000000..ea6e7d662
--- /dev/null
+++ b/NxWidgets/UnitTests/CLatchButton/Makefile
@@ -0,0 +1,172 @@
+#################################################################################
+# NxWidgets/UnitTests/CLatchButton/Makefile
+#
+# Copyright (C) 2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+# me be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#################################################################################
+
+TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'}
+
+-include $(TOPDIR)/.config
+-include $(TOPDIR)/Make.defs
+include $(APPDIR)/Make.defs
+
+# Add the path to the NXWidget include directory to the CFLAGS
+
+NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets"
+NXWIDGETS_INC="$(NXWIDGETS_DIR)/include"
+NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)"
+
+INCDIR=$(TOPDIR)/tools/incdir.sh
+ifeq ($(WINTOOL),y)
+ CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"}
+else
+ CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"}
+endif
+
+# Get the path to the archiver tool
+
+TESTTOOL_DIR="$(TESTDIR)/../tools"
+ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh
+
+# Hello, World! C++ Example
+
+ASRCS =
+CSRCS =
+CXXSRCS = main.cxx clatchbuttontest.cxx
+
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+COBJS = $(CSRCS:.c=$(OBJEXT))
+CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS)
+OBJS = $(AOBJS) $(COBJS) $(CXXOBJS)
+
+POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)"
+ifeq ($(WINTOOL),y)
+ BIN = "${shell cygpath -w $(POSIX_BIN)}"
+else
+ BIN = $(POSIX_BIN)
+endif
+
+ROOTDEPPATH = --dep-path .
+
+# helloxx built-in application info
+
+APPNAME = clatchbutton
+PRIORITY = SCHED_PRIORITY_DEFAULT
+STACKSIZE = 2048
+
+# Common build
+
+VPATH =
+
+all: .built
+.PHONY: clean depend context disclean chkcxx chklib
+
+# Object file creation targets
+
+$(AOBJS): %$(OBJEXT): %.S
+ $(call ASSEMBLE, $<, $@)
+
+$(COBJS): %$(OBJEXT): %.c
+ $(call COMPILE, $<, $@)
+
+$(CXXOBJS): %$(OBJEXT): %.cxx
+ $(call COMPILEXX, $<, $@)
+
+# Verify that the NuttX configuration is setup to support C++
+
+chkcxx:
+ifneq ($(CONFIG_HAVE_CXX),y)
+ @echo ""
+ @echo "In order to use this example, you toolchain must support must"
+ @echo ""
+ @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support"
+ @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file"
+ @echo " of the configuration that you are using."
+ @echo ""
+ @exit 1
+endif
+
+# Verify that the NXWidget library has been built
+
+chklib:
+ @( \
+ if [ ! -e "$(NXWIDGETS_LIB)" ]; then \
+ echo "$(NXWIDGETS_LIB) does not exist."; \
+ echo "Please go to $(NXWIDGETS_DIR)"; \
+ echo "and rebuild the library"; \
+ exit 1; \
+ fi; \
+ )
+
+# Library creation targets
+
+$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work.
+
+.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB)
+ @( for obj in $(OBJS) ; do \
+ $(call ARCHIVE, $(BIN), $${obj}); \
+ done ; )
+ifeq ($(WINTOOL),y)
+ @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+else
+ @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+endif
+ @touch .built
+
+# Standard housekeeping targets
+
+.context:
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+ $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
+endif
+ @touch $@
+
+context: .context
+
+.depend: Makefile $(SRCS)
+ @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep
+ @touch $@
+
+depend: .depend
+
+clean:
+ @rm -f *.o *~ .*.swp .built
+ $(call CLEAN)
+
+distclean: clean
+ @rm -f Make.dep .depend
+
+-include Make.dep
diff --git a/NxWidgets/UnitTests/CLatchButton/clatchbuttontest.cxx b/NxWidgets/UnitTests/CLatchButton/clatchbuttontest.cxx
new file mode 100644
index 000000000..2b41eca63
--- /dev/null
+++ b/NxWidgets/UnitTests/CLatchButton/clatchbuttontest.cxx
@@ -0,0 +1,321 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CLatchButton/clatchbuttontest.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cerrno>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+#include <nuttx/nx/nxfonts.h>
+
+#include "nxconfig.hxx"
+#include "clatchbuttontest.hxx"
+#include "cbgwindow.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// CLatchButtonTest Method Implementations
+/////////////////////////////////////////////////////////////////////////////
+
+// CLatchButtonTest Constructor
+
+CLatchButtonTest::CLatchButtonTest()
+{
+ m_bgWindow = (CBgWindow *)NULL;
+ m_nxFont = (CNxFont *)NULL;
+ m_text = (CNxString *)NULL;
+}
+
+// CLatchButtonTest Descriptor
+
+CLatchButtonTest::~CLatchButtonTest()
+{
+ disconnect();
+}
+
+// Connect to the NX server
+
+bool CLatchButtonTest::connect(void)
+{
+ // Connect to the server
+
+ bool nxConnected = CNxServer::connect();
+ if (nxConnected)
+ {
+ // Create the default font instance
+
+ m_nxFont = new CNxFont(NXFONT_DEFAULT,
+ CONFIG_NXWIDGETS_DEFAULT_FONTCOLOR,
+ CONFIG_NXWIDGETS_TRANSPARENT_COLOR);
+ if (!m_nxFont)
+ {
+ printf("CLatchButtonTest::connect: Failed to create the default font\n");
+ }
+
+ // Set the background color
+
+ if (!setBackgroundColor(CONFIG_CLATCHBUTTONTEST_BGCOLOR))
+ {
+ printf("CLatchButtonTest::connect: setBackgroundColor failed\n");
+ }
+ }
+
+ return nxConnected;
+}
+
+// Disconnect from the NX server
+
+void CLatchButtonTest::disconnect(void)
+{
+ // Close the window
+
+ if (m_bgWindow)
+ {
+ delete m_bgWindow;
+ }
+
+ // Free the display string
+
+ if (m_text)
+ {
+ delete m_text;
+ m_text = (CNxString *)NULL;
+ }
+
+ // Free the default font
+
+ if (m_nxFont)
+ {
+ delete m_nxFont;
+ m_nxFont = (CNxFont *)NULL;
+ }
+
+ // And disconnect from the server
+
+ CNxServer::disconnect();
+}
+
+// Create the background window instance. This function illustrates
+// the basic steps to instantiate any window:
+//
+// 1) Create a dumb CWigetControl instance
+// 2) Pass the dumb CWidgetControl instance to the window constructor
+// that inherits from INxWindow. This will "smarten" the CWidgetControl
+// instance with some window knowlede
+// 3) Call the open() method on the window to display the window.
+// 4) After that, the fully smartened CWidgetControl instance can
+// be used to generate additional widgets by passing it to the
+// widget constructor
+
+bool CLatchButtonTest::createWindow(void)
+{
+ // Initialize the widget control using the default style
+
+ m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL);
+
+ // Get an (uninitialized) instance of the background window as a class
+ // that derives from INxWindow.
+
+ m_bgWindow = getBgWindow(m_widgetControl);
+ if (!m_bgWindow)
+ {
+ printf("CLatchButtonTest::createGraphics: Failed to create CBgWindow instance\n");
+ delete m_widgetControl;
+ return false;
+ }
+
+ // Open (and initialize) the window
+
+ bool success = m_bgWindow->open();
+ if (!success)
+ {
+ printf("CLatchButtonTest::createGraphics: Failed to open background window\n");
+ delete m_bgWindow;
+ m_bgWindow = (CBgWindow*)0;
+ return false;
+ }
+
+ return true;
+}
+
+// Create a CLatchButton instance
+
+CLatchButton *CLatchButtonTest::createButton(FAR const char *text)
+{
+ // Get the width of the display
+
+ struct nxgl_size_s windowSize;
+ if (!m_bgWindow->getSize(&windowSize))
+ {
+ printf("CLatchButtonTest::createGraphics: Failed to get window size\n");
+ return (CLatchButton *)NULL;
+ }
+
+ // Create a CNxString instance to contain the C string
+
+ m_text = new CNxString(text);
+
+ // Get the height and width of the text display area
+
+ nxgl_coord_t stringWidth = m_nxFont->getStringWidth(*m_text);
+ nxgl_coord_t stringHeight = (nxgl_coord_t)m_nxFont->getHeight();
+
+ // The default CLatchButton has borders enabled with thickness of the border
+ // width. Add twice the thickness of border the to the width and height. (We
+ // could let CLatchButton do this for us by calling
+ // CLatchButton::getPreferredDimensions())
+
+ stringWidth += 2 * 1;
+ stringHeight += 2 * 1;
+
+ // Pick an X/Y position such that the button will be centered in the display
+
+ nxgl_coord_t buttonX;
+ if (stringWidth >= windowSize.w)
+ {
+ buttonX = 0;
+ }
+ else
+ {
+ buttonX = (windowSize.w - stringWidth) >> 1;
+ }
+
+ nxgl_coord_t buttonY;
+ if (stringHeight >= windowSize.h)
+ {
+ buttonY = 0;
+ }
+ else
+ {
+ buttonY = (windowSize.h - stringHeight) >> 1;
+ }
+
+ // Save the center position of the button for use by click and release
+
+ m_center.x = buttonX + (stringWidth >> 1);
+ m_center.y = buttonY + (stringHeight >> 1);
+
+ // Now we have enough information to create the button
+
+ return new CLatchButton(m_widgetControl, buttonX, buttonY, stringWidth, stringHeight, *m_text);
+}
+
+// Draw the button
+
+void CLatchButtonTest::showButton(CLatchButton *button)
+{
+ button->enable(); // Un-necessary, the widget is enabled by default
+ button->enableDrawing();
+ button->redraw();
+}
+
+// Perform a simulated mouse click on the button. This method injects
+// the mouse click through the NX heirarchy just as would real mouse
+// hardward.
+
+void CLatchButtonTest::click(void)
+{
+ // nx_mousein is meant to be called by mouse handling software.
+ // Here we just inject a left-button click directly in the center of
+ // the button.
+
+ // First, get the server handle. Graphics software will never care
+ // about the server handle. Here we need it to get access to the
+ // low-level mouse interface
+
+ NXHANDLE handle = getServer();
+
+ // Then inject the mouse click
+
+ (void)nx_mousein(handle, m_center.x, m_center.y, NX_MOUSE_LEFTBUTTON);
+}
+
+// The counterpart to click. This simulates a button release through
+// the same mechanism.
+
+void CLatchButtonTest::release(void)
+{
+ // nx_mousein is meant to be called by mouse handling software.
+ // Here we just inject a left-button click directly in the center of
+ // the button.
+
+ // First, get the server handle. Graphics software will never care
+ // about the server handle. Here we need it to get access to the
+ // low-level mouse interface
+
+ NXHANDLE handle = getServer();
+
+ // Then inject the mouse click
+
+ (void)nx_mousein(handle, m_center.x, m_center.y, NX_MOUSE_NOBUTTONS);
+}
+
+// Widget events are normally handled in a modal loop (by calling goModal()).
+// However, for this case we know when there should be press and release
+// events so we don't have to poll. We can just perform a one pass poll.
+
+void CLatchButtonTest::poll(CLatchButton *button)
+{
+ // Poll for mouse events
+
+ m_widgetControl->pollEvents(button);
+}
+
diff --git a/NxWidgets/UnitTests/CLatchButton/clatchbuttontest.hxx b/NxWidgets/UnitTests/CLatchButton/clatchbuttontest.hxx
new file mode 100644
index 000000000..22ded3d77
--- /dev/null
+++ b/NxWidgets/UnitTests/CLatchButton/clatchbuttontest.hxx
@@ -0,0 +1,165 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CLatchButton/clatchbuttontest.hxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef __UNITTESTS_CLATCHBUTTON_CLATCHBUTTONTEST_HXX
+#define __UNITTESTS_CLATCHBUTTON_CLATCHBUTTONTEST_HXX
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <semaphore.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "nxconfig.hxx"
+#include "cwidgetcontrol.hxx"
+#include "ccallback.hxx"
+#include "cbgwindow.hxx"
+#include "cnxserver.hxx"
+#include "cnxfont.hxx"
+#include "cnxstring.hxx"
+#include "clatchbutton.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+// Configuration ////////////////////////////////////////////////////////////
+
+#ifndef CONFIG_HAVE_CXX
+# error "CONFIG_HAVE_CXX must be defined"
+#endif
+
+#ifndef CONFIG_CLATCHBUTTONTEST_BGCOLOR
+# define CONFIG_CLATCHBUTTONTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR
+#endif
+
+#ifndef CONFIG_CLATCHBUTTONTEST_FONTCOLOR
+# define CONFIG_CLATCHBUTTONTEST_FONTCOLOR CONFIG_NXWIDGETS_DEFAULT_FONTCOLOR
+#endif
+
+// What is the entry point called?
+
+#ifdef CONFIG_NSH_BUILTIN_APPS
+# define MAIN_NAME clatchbutton_main
+# define MAIN_STRING "clatchbutton_main: "
+#else
+# define MAIN_NAME user_start
+# define MAIN_STRING "user_start: "
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Classes
+/////////////////////////////////////////////////////////////////////////////
+
+using namespace NXWidgets;
+
+class CLatchButtonTest : public CNxServer
+{
+private:
+ CWidgetControl *m_widgetControl; // The controlling widget for the window
+ CNxFont *m_nxFont; // Default font
+ CBgWindow *m_bgWindow; // Background window instance
+ CNxString *m_text; // The button string
+ struct nxgl_point_s m_center; // X, Y position the center of the button
+
+public:
+ // Constructor/destructors
+
+ CLatchButtonTest(void);
+ ~CLatchButtonTest(void);
+
+ // Initializer/unitializer. These methods encapsulate the basic steps for
+ // starting and stopping the NX server
+
+ bool connect(void);
+ void disconnect(void);
+
+ // Create a window. This method provides the general operations for
+ // creating a window that you can draw within.
+ //
+ // Those general operations are:
+ // 1) Create a dumb CWigetControl instance
+ // 2) Pass the dumb CWidgetControl instance to the window constructor
+ // that inherits from INxWindow. This will "smarten" the CWidgetControl
+ // instance with some window knowlede
+ // 3) Call the open() method on the window to display the window.
+ // 4) After that, the fully smartened CWidgetControl instance can
+ // be used to generate additional widgets by passing it to the
+ // widget constructor
+
+ bool createWindow(void);
+
+ // Create a CLatchButton instance. This method will show you how to create
+ // a CLatchButton widget
+
+ CLatchButton *createButton(FAR const char *text);
+
+ // Draw the button. This method illustrates how to draw the CLatchButton widget.
+
+ void showButton(CLatchButton *button);
+
+ // Perform a simulated mouse click on the button. This method injects
+ // the mouse click through the NX heirarchy just as would real mouse
+ // hardward.
+
+ void click(void);
+
+ // The counterpart to click. This simulates a button release through
+ // the same mechanism.
+
+ void release(void);
+
+ // Widget events are normally handled in a model loop (by calling goModel()).
+ // However, for this case we know when there should be press and release
+ // events so we don't have to poll. We can just perform a one pass poll.
+
+ void poll(CLatchButton *button);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+#endif // __UNITTESTS_CLATCHBUTTON_CLATCHBUTTONTEST_HXX
diff --git a/NxWidgets/UnitTests/CLatchButton/main.cxx b/NxWidgets/UnitTests/CLatchButton/main.cxx
new file mode 100644
index 000000000..d51f613c1
--- /dev/null
+++ b/NxWidgets/UnitTests/CLatchButton/main.cxx
@@ -0,0 +1,199 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CLatchButton/main.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <unistd.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "clatchbuttontest.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+static const char g_pushme[] = "Push Me";
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+// Suppress name-mangling
+
+extern "C" int MAIN_NAME(int argc, char *argv[]);
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: showButtonState
+/////////////////////////////////////////////////////////////////////////////
+
+static void showButtonState(CLatchButton *button, bool &clicked, bool &latched)
+{
+ bool nowClicked = button->isClicked();
+ bool nowLatched = button->isLatched();
+
+ printf(MAIN_STRING "Button state: %s and %s\n",
+ nowClicked ? "clicked" : "released",
+ nowLatched ? "latched" : "unlatched");
+
+ if (clicked != nowClicked || latched != nowLatched)
+ {
+ printf(MAIN_STRING "ERROR: Expected %s and %s\n",
+ clicked ? "clicked" : "released",
+ latched ? "latched" : "unlatched");
+
+ clicked = nowClicked;
+ latched = nowLatched;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// user_start/nxheaders_main
+/////////////////////////////////////////////////////////////////////////////
+
+int MAIN_NAME(int argc, char *argv[])
+{
+ // Create an instance of the font test
+
+ printf(MAIN_STRING "Create CLatchButtonTest instance\n");
+ CLatchButtonTest *test = new CLatchButtonTest();
+
+ // Connect the NX server
+
+ printf(MAIN_STRING "Connect the CLatchButtonTest instance to the NX server\n");
+ if (!test->connect())
+ {
+ printf(MAIN_STRING "Failed to connect the CLatchButtonTest instance to the NX server\n");
+ delete test;
+ return 1;
+ }
+
+ // Create a window to draw into
+
+ printf(MAIN_STRING "Create a Window\n");
+ if (!test->createWindow())
+ {
+ printf(MAIN_STRING "Failed to create a window\n");
+ delete test;
+ return 1;
+ }
+
+ // Create a CLatchButton instance
+
+ CLatchButton *button = test->createButton(g_pushme);
+ if (!button)
+ {
+ printf(MAIN_STRING "Failed to create a button\n");
+ delete test;
+ return 1;
+ }
+
+ // Show the button
+
+ printf(MAIN_STRING "Show the button\n");
+ test->showButton(button);
+
+ bool clicked = false;
+ bool latched = false;
+ showButtonState(button, clicked, latched);
+
+ // Toggle the button state a few times
+
+ for (int i = 0; i < 8; i++)
+ {
+ // Wait two seconds, then perform a simulated mouse click on the button
+
+ sleep(2);
+ printf(MAIN_STRING "Click the button\n");
+ test->click();
+ test->poll(button);
+
+ // Test the button state it should be clicked with the latch state
+ // toggled
+
+ clicked = true;
+ latched = !latched;
+ showButtonState(button, clicked, latched);
+
+ // And release the button after 0.5 seconds
+
+ usleep(500 * 1000);
+ printf(MAIN_STRING "Release the button\n");
+ test->release();
+ test->poll(button);
+
+ // Test the button state it should be unclicked with the latch state
+ // unchanged
+
+ clicked = false;
+ showButtonState(button, clicked, latched);
+ fflush(stdout);
+ }
+
+ // Wait a few more seconds so that the tester can ponder the result
+
+ sleep(3);
+
+ // Clean up and exit
+
+ printf(MAIN_STRING "Clean-up and exit\n");
+ delete button;
+ delete test;
+ return 0;
+}
+
diff --git a/NxWidgets/UnitTests/CLatchButtonArray/Makefile b/NxWidgets/UnitTests/CLatchButtonArray/Makefile
new file mode 100644
index 000000000..faa9d8fd9
--- /dev/null
+++ b/NxWidgets/UnitTests/CLatchButtonArray/Makefile
@@ -0,0 +1,172 @@
+#################################################################################
+# NxWidgets/UnitTests/CLatchButtonArray/Makefile
+#
+# Copyright (C) 2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+# me be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#################################################################################
+
+TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'}
+
+-include $(TOPDIR)/.config
+-include $(TOPDIR)/Make.defs
+include $(APPDIR)/Make.defs
+
+# Add the path to the NXWidget include directory to the CFLAGS
+
+NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets"
+NXWIDGETS_INC="$(NXWIDGETS_DIR)/include"
+NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)"
+
+INCDIR=$(TOPDIR)/tools/incdir.sh
+ifeq ($(WINTOOL),y)
+ CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"}
+else
+ CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"}
+endif
+
+# Get the path to the archiver tool
+
+TESTTOOL_DIR="$(TESTDIR)/../tools"
+ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh
+
+# Hello, World! C++ Example
+
+ASRCS =
+CSRCS =
+CXXSRCS = main.cxx clatchbuttonarraytest.cxx
+
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+COBJS = $(CSRCS:.c=$(OBJEXT))
+CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS)
+OBJS = $(AOBJS) $(COBJS) $(CXXOBJS)
+
+POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)"
+ifeq ($(WINTOOL),y)
+ BIN = "${shell cygpath -w $(POSIX_BIN)}"
+else
+ BIN = $(POSIX_BIN)
+endif
+
+ROOTDEPPATH = --dep-path .
+
+# helloxx built-in application info
+
+APPNAME = clatchbuttonarray
+PRIORITY = SCHED_PRIORITY_DEFAULT
+STACKSIZE = 2048
+
+# Common build
+
+VPATH =
+
+all: .built
+.PHONY: clean depend context disclean chkcxx chklib
+
+# Object file creation targets
+
+$(AOBJS): %$(OBJEXT): %.S
+ $(call ASSEMBLE, $<, $@)
+
+$(COBJS): %$(OBJEXT): %.c
+ $(call COMPILE, $<, $@)
+
+$(CXXOBJS): %$(OBJEXT): %.cxx
+ $(call COMPILEXX, $<, $@)
+
+# Verify that the NuttX configuration is setup to support C++
+
+chkcxx:
+ifneq ($(CONFIG_HAVE_CXX),y)
+ @echo ""
+ @echo "In order to use this example, you toolchain must support must"
+ @echo ""
+ @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support"
+ @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file"
+ @echo " of the configuration that you are using."
+ @echo ""
+ @exit 1
+endif
+
+# Verify that the NXWidget library has been built
+
+chklib:
+ @( \
+ if [ ! -e "$(NXWIDGETS_LIB)" ]; then \
+ echo "$(NXWIDGETS_LIB) does not exist."; \
+ echo "Please go to $(NXWIDGETS_DIR)"; \
+ echo "and rebuild the library"; \
+ exit 1; \
+ fi; \
+ )
+
+# Library creation targets
+
+$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work.
+
+.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB)
+ @( for obj in $(OBJS) ; do \
+ $(call ARCHIVE, $(BIN), $${obj}); \
+ done ; )
+ifeq ($(WINTOOL),y)
+ @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+else
+ @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+endif
+ @touch .built
+
+# Standard housekeeping targets
+
+.context:
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+ $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
+endif
+ @touch $@
+
+context: .context
+
+.depend: Makefile $(SRCS)
+ @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep
+ @touch $@
+
+depend: .depend
+
+clean:
+ @rm -f *.o *~ .*.swp .built
+ $(call CLEAN)
+
+distclean: clean
+ @rm -f Make.dep .depend
+
+-include Make.dep
diff --git a/NxWidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.cxx b/NxWidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.cxx
new file mode 100644
index 000000000..5b1737e06
--- /dev/null
+++ b/NxWidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.cxx
@@ -0,0 +1,301 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cerrno>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+#include <nuttx/nx/nxfonts.h>
+
+#include "nxconfig.hxx"
+#include "clatchbuttonarraytest.hxx"
+#include "cbgwindow.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// CLatchButtonArrayTest Method Implementations
+/////////////////////////////////////////////////////////////////////////////
+
+// CLatchButtonArrayTest Constructor
+
+CLatchButtonArrayTest::CLatchButtonArrayTest()
+{
+ m_widgetControl = (CWidgetControl *)NULL;
+ m_bgWindow = (CBgWindow *)NULL;
+}
+
+// CLatchButtonArrayTest Descriptor
+
+CLatchButtonArrayTest::~CLatchButtonArrayTest()
+{
+ disconnect();
+}
+
+// Connect to the NX server
+
+bool CLatchButtonArrayTest::connect(void)
+{
+ // Connect to the server
+
+ bool nxConnected = CNxServer::connect();
+ if (nxConnected)
+ {
+ // Set the background color
+
+ if (!setBackgroundColor(CONFIG_CLATCHBUTTONARRAYTEST_BGCOLOR))
+ {
+ message("CLatchButtonArrayTest::connect: setBackgroundColor failed\n");
+ }
+ }
+
+ return nxConnected;
+}
+
+// Disconnect from the NX server
+
+void CLatchButtonArrayTest::disconnect(void)
+{
+ // Close the window
+
+ if (m_bgWindow)
+ {
+ delete m_bgWindow;
+ }
+
+ // Destroy the widget control
+
+ if (m_widgetControl)
+ {
+ delete m_widgetControl;
+ }
+
+ // And disconnect from the server
+
+ CNxServer::disconnect();
+}
+
+// Create the background window instance. This function illustrates
+// the basic steps to instantiate any window:
+//
+// 1) Create a dumb CWigetControl instance
+// 2) Pass the dumb CWidgetControl instance to the window constructor
+// that inherits from INxWindow. This will "smarten" the CWidgetControl
+// instance with some window knowlede
+// 3) Call the open() method on the window to display the window.
+// 4) After that, the fully smartened CWidgetControl instance can
+// be used to generate additional widgets by passing it to the
+// widget constructor
+
+bool CLatchButtonArrayTest::createWindow(void)
+{
+ // Initialize the widget control using the default style
+
+ m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL);
+
+ // Get an (uninitialized) instance of the background window as a class
+ // that derives from INxWindow.
+
+ m_bgWindow = getBgWindow(m_widgetControl);
+ if (!m_bgWindow)
+ {
+ message("CLatchButtonArrayTest::createGraphics: Failed to create CBgWindow instance\n");
+ delete m_widgetControl;
+ return false;
+ }
+
+ // Open (and initialize) the window
+
+ bool success = m_bgWindow->open();
+ if (!success)
+ {
+ message("CLatchButtonArrayTest::createGraphics: Failed to open background window\n");
+ delete m_bgWindow;
+ m_bgWindow = (CBgWindow*)0;
+ return false;
+ }
+
+ return true;
+}
+
+// Create a CLatchButtonArray instance
+
+CLatchButtonArray *CLatchButtonArrayTest::createButtonArray(void)
+{
+ // Get the width of the display
+
+ struct nxgl_size_s windowSize;
+ if (!m_bgWindow->getSize(&windowSize))
+ {
+ message("CLatchButtonArrayTest::createGraphics: Failed to get window size\n");
+ return (CLatchButtonArray *)NULL;
+ }
+
+ // Pick an X/Y position such that the button array will be centered in the display
+
+ nxgl_coord_t buttonArrayX;
+ if (BUTTONARRAY_WIDTH >= windowSize.w)
+ {
+ buttonArrayX = 0;
+ }
+ else
+ {
+ buttonArrayX = (windowSize.w - BUTTONARRAY_WIDTH) >> 1;
+ }
+
+ nxgl_coord_t buttonArrayY;
+ if (BUTTONARRAY_HEIGHT >= windowSize.h)
+ {
+ buttonArrayY = 0;
+ }
+ else
+ {
+ buttonArrayY = (windowSize.h - BUTTONARRAY_HEIGHT) >> 1;
+ }
+
+ // Now we have enough information to create the button array
+
+ return new CLatchButtonArray(m_widgetControl,
+ buttonArrayX, buttonArrayY,
+ BUTTONARRAY_NCOLUMNS, BUTTONARRAY_NROWS,
+ BUTTONARRAY_BUTTONWIDTH, BUTTONARRAY_BUTTONHEIGHT);
+}
+
+// Draw the button array
+
+void CLatchButtonArrayTest::showButton(CLatchButtonArray *buttonArray)
+{
+ buttonArray->enable(); // Un-necessary, the widget is enabled by default
+ buttonArray->enableDrawing();
+ buttonArray->redraw();
+}
+
+// Perform a simulated mouse click on a button in the array. This method injects
+// the mouse click through the NX heirarchy just as would real mouse
+// hardward.
+
+void CLatchButtonArrayTest::click(CLatchButtonArray *buttonArray, int column, int row)
+{
+ // nx_mousein is meant to be called by mouse handling software.
+ // Here we just inject a left-button click directly in the center of
+ // the selected button.
+
+ // First, get the server handle. Graphics software will never care
+ // about the server handle. Here we need it to get access to the
+ // low-level mouse interface
+
+ NXHANDLE handle = getServer();
+
+ // The the coorinates of the center of the button
+
+ nxgl_coord_t buttonX = buttonArray->getX() +
+ column * BUTTONARRAY_BUTTONWIDTH +
+ BUTTONARRAY_BUTTONWIDTH/2;
+ nxgl_coord_t buttonY = buttonArray->getY() +
+ row * BUTTONARRAY_BUTTONHEIGHT +
+ BUTTONARRAY_BUTTONHEIGHT/2;
+
+ // Then inject the mouse click
+
+ (void)nx_mousein(handle, buttonX, buttonY, NX_MOUSE_LEFTBUTTON);
+}
+
+// The counterpart to click. This simulates a button release through
+// the same mechanism.
+
+void CLatchButtonArrayTest::release(CLatchButtonArray *buttonArray, int column, int row)
+{
+ // nx_mousein is meant to be called by mouse handling software.
+ // Here we just inject a left-button click directly in the center of
+ // the button.
+
+ // First, get the server handle. Graphics software will never care
+ // about the server handle. Here we need it to get access to the
+ // low-level mouse interface
+
+ NXHANDLE handle = getServer();
+
+ // The the coorinates of the center of the button
+
+ nxgl_coord_t buttonX = buttonArray->getX() +
+ column * BUTTONARRAY_BUTTONWIDTH +
+ BUTTONARRAY_BUTTONWIDTH/2;
+ nxgl_coord_t buttonY = buttonArray->getY() +
+ row * BUTTONARRAY_BUTTONHEIGHT +
+ BUTTONARRAY_BUTTONHEIGHT/2;
+
+ // Then inject the mouse release
+
+ (void)nx_mousein(handle, buttonX, buttonY, NX_MOUSE_NOBUTTONS);
+}
+
+// Widget events are normally handled in a modal loop (by calling goModal()).
+// However, for this case we know when there should be press and release
+// events so we don't have to poll. We can just perform a one pass poll
+// then check if the event was processed corredly.
+
+void CLatchButtonArrayTest::poll(CLatchButtonArray *button)
+{
+ // Poll for mouse events
+
+ m_widgetControl->pollEvents(button);
+}
+
diff --git a/NxWidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.hxx b/NxWidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.hxx
new file mode 100644
index 000000000..89ed242e7
--- /dev/null
+++ b/NxWidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.hxx
@@ -0,0 +1,182 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.hxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef __UNITTESTS_CLATCHBUTTONARRAY_CLATCHBUTTONARRAYTEST_HXX
+#define __UNITTESTS_CLATCHBUTTONARRAY_CLATCHBUTTONARRAYTEST_HXX
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <semaphore.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "nxconfig.hxx"
+#include "cwidgetcontrol.hxx"
+#include "ccallback.hxx"
+#include "cbgwindow.hxx"
+#include "cnxserver.hxx"
+#include "cnxfont.hxx"
+#include "cnxstring.hxx"
+#include "clatchbuttonarray.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+// Configuration ////////////////////////////////////////////////////////////
+
+#ifndef CONFIG_HAVE_CXX
+# error "CONFIG_HAVE_CXX must be defined"
+#endif
+
+#ifndef CONFIG_CLATCHBUTTONARRAYTEST_BGCOLOR
+# define CONFIG_CLATCHBUTTONARRAYTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR
+#endif
+
+#ifndef CONFIG_CLATCHBUTTONARRAYTEST_FONTCOLOR
+# define CONFIG_CLATCHBUTTONARRAYTEST_FONTCOLOR CONFIG_NXWIDGETS_DEFAULT_FONTCOLOR
+#endif
+
+// What is the entry point called?
+
+#ifdef CONFIG_NSH_BUILTIN_APPS
+# define MAIN_NAME clatchbuttonarray_main
+# define MAIN_STRING "clatchbuttonarray_main: "
+#else
+# define MAIN_NAME user_start
+# define MAIN_STRING "user_start: "
+#endif
+
+// If debug is enabled, use the debug function, lib_rawprintf() instead
+// of printf() so that the output is synchronized.
+
+#ifdef CONFIG_DEBUG
+# define message lib_lowprintf
+#else
+# define message printf
+#endif
+
+// The geometry of the button array
+
+#define BUTTONARRAY_NCOLUMNS 4
+#define BUTTONARRAY_NROWS 7
+#define BUTTONARRAY_BUTTONWIDTH 60
+#define BUTTONARRAY_BUTTONHEIGHT 32
+#define BUTTONARRAY_WIDTH (BUTTONARRAY_BUTTONWIDTH * BUTTONARRAY_NCOLUMNS)
+#define BUTTONARRAY_HEIGHT (BUTTONARRAY_BUTTONHEIGHT * BUTTONARRAY_NROWS)
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Classes
+/////////////////////////////////////////////////////////////////////////////
+
+using namespace NXWidgets;
+
+class CLatchButtonArrayTest : public CNxServer
+{
+private:
+ CWidgetControl *m_widgetControl; // The widget control for the window
+ CBgWindow *m_bgWindow; // Background window instance
+
+public:
+ // Constructor/destructors
+
+ CLatchButtonArrayTest();
+ ~CLatchButtonArrayTest();
+
+ // Initializer/unitializer. These methods encapsulate the basic steps for
+ // starting and stopping the NX server
+
+ bool connect(void);
+ void disconnect(void);
+
+ // Create a window. This method provides the general operations for
+ // creating a window that you can draw within.
+ //
+ // Those general operations are:
+ // 1) Create a dumb CWigetControl instance
+ // 2) Pass the dumb CWidgetControl instance to the window constructor
+ // that inherits from INxWindow. This will "smarten" the CWidgetControl
+ // instance with some window knowlede
+ // 3) Call the open() method on the window to display the window.
+ // 4) After that, the fully smartened CWidgetControl instance can
+ // be used to generate additional widgets by passing it to the
+ // widget constructor
+
+ bool createWindow(void);
+
+ // Create a CLatchButtonArray instance. This method will show you how to create
+ // a CLatchButtonArray widget
+
+ CLatchButtonArray *createButtonArray(void);
+
+ // Draw the button array. This method illustrates how to draw the CLatchButtonArray widget.
+
+ void showButton(CLatchButtonArray *buttonArray);
+
+ // Perform a simulated mouse click on a button in the array. This method injects
+ // the mouse click through the NX heirarchy just as would real mouse
+ // hardward.
+
+ void click(CLatchButtonArray *buttonArray, int column, int row);
+
+ // The counterpart to click. This simulates a button release through
+ // the same mechanism.
+
+ void release(CLatchButtonArray *buttonArray, int column, int row);
+
+ // Widget events are normally handled in a model loop (by calling goModel()).
+ // However, for this case we know when there should be press and release
+ // events so we don't have to poll. We can just perform a one pass poll
+ // then check if the event was processed corredly.
+
+ void poll(CLatchButtonArray *buttonArray);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+
+#endif // __UNITTESTS_CLATCHBUTTONARRAY_CLATCHBUTTONARRAYTEST_HXX
diff --git a/NxWidgets/UnitTests/CLatchButtonArray/main.cxx b/NxWidgets/UnitTests/CLatchButtonArray/main.cxx
new file mode 100644
index 000000000..d38651ae9
--- /dev/null
+++ b/NxWidgets/UnitTests/CLatchButtonArray/main.cxx
@@ -0,0 +1,301 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CLatchButtonArray/main.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cstdlib>
+#include <unistd.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "cnxstring.hxx"
+#include "clatchbuttonarraytest.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+static unsigned int g_mmInitial;
+static unsigned int g_mmPrevious;
+static unsigned int g_mmPeak;
+
+static FAR const char *g_buttonLabels[BUTTONARRAY_NCOLUMNS*BUTTONARRAY_NROWS] = {
+ "=>", "A", "B", "<DEL",
+ "C", "D", "E", "F",
+ "G", "H", "I", "J",
+ "K", "L", "M", "N",
+ "O", "P", "Q", "R",
+ "S", "T", "U", "V",
+ "W", "X", "Y", "Z"
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+// Suppress name-mangling
+
+extern "C" int MAIN_NAME(int argc, char *argv[]);
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: showButtonState
+/////////////////////////////////////////////////////////////////////////////
+
+static void showButtonState(CLatchButtonArray *buttonArray, int i, int j,
+ bool &clicked, bool &latched)
+{
+ bool nowClicked = buttonArray->isThisButtonClicked(i,j);
+ bool nowLatched = buttonArray->isThisButtonLatched(i,j);
+
+ printf(MAIN_STRING "Button(%d,%d) state: %s and %s\n",
+ i, j,
+ nowClicked ? "clicked" : "released",
+ nowLatched ? "latched" : "unlatched");
+
+ if (clicked != nowClicked || latched != nowLatched)
+ {
+ printf(MAIN_STRING "ERROR: Expected %s and %s\n",
+ clicked ? "clicked" : "released",
+ latched ? "latched" : "unlatched");
+
+ clicked = nowClicked;
+ latched = nowLatched;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: updateMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void updateMemoryUsage(unsigned int previous,
+ FAR const char *msg)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ /* Show the change from the previous time */
+
+ message("%s: Before: %8d After: %8d Change: %8d\n",
+ msg, previous, mmcurrent.uordblks, mmcurrent.uordblks - previous);
+
+ /* Set up for the next test */
+
+ g_mmPrevious = mmcurrent.uordblks;
+ if ((unsigned int)mmcurrent.uordblks > g_mmPeak)
+ {
+ g_mmPeak = mmcurrent.uordblks;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: initMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void initMemoryUsage(void)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ g_mmInitial = mmcurrent.uordblks;
+ g_mmPrevious = mmcurrent.uordblks;
+ g_mmPeak = mmcurrent.uordblks;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// user_start/nxheaders_main
+/////////////////////////////////////////////////////////////////////////////
+
+int MAIN_NAME(int argc, char *argv[])
+{
+ // Initialize memory monitor logic
+
+ initMemoryUsage();
+
+ // Create an instance of the button array test
+
+ printf(MAIN_STRING "Create CLatchButtonArrayTest instance\n");
+ CLatchButtonArrayTest *test = new CLatchButtonArrayTest();
+ updateMemoryUsage(g_mmPrevious, "After creating CLatchButtonArrayTest");
+
+ // Connect the NX server
+
+ printf(MAIN_STRING "Connect the CLatchButtonArrayTest instance to the NX server\n");
+ if (!test->connect())
+ {
+ printf(MAIN_STRING "Failed to connect the CLatchButtonArrayTest instance to the NX server\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmPrevious, "After connecting to the server");
+
+ // Create a window to draw into
+
+ printf(MAIN_STRING "Create a Window\n");
+ if (!test->createWindow())
+ {
+ printf(MAIN_STRING "Failed to create a window\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmPrevious, "After creating a window");
+
+ // Create a CLatchButtonArray instance
+
+ CLatchButtonArray *buttonArray = test->createButtonArray();
+ if (!buttonArray)
+ {
+ printf(MAIN_STRING "Failed to create a button array\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmPrevious, "After creating CLatchButtonArray");
+
+ // Add the labels to each button
+
+ FAR const char **ptr = g_buttonLabels;
+ for (int j = 0; j < BUTTONARRAY_NROWS; j++)
+ {
+ for (int i = 0; i < BUTTONARRAY_NCOLUMNS; i++)
+ {
+ printf(MAIN_STRING "Label (%d,%d): %s\n", i, j, *ptr);
+ CNxString string = *ptr++;
+ buttonArray->setText(i, j, string);
+ }
+ }
+ updateMemoryUsage(g_mmPrevious, "After adding labels to the buttons");
+
+ // Show the button array
+
+ printf(MAIN_STRING "Show the button array\n");
+ test->showButton(buttonArray);
+ sleep(1);
+
+ // Then perform a simulated mouse click on a button in the array
+
+ bool clicked = false;
+ bool latched = false;
+
+ for (int j = 0; j < BUTTONARRAY_NROWS; j++)
+ {
+ for (int i = 0; i < BUTTONARRAY_NCOLUMNS; i++)
+ {
+ // Initially, this button should be neither clicked nor latched
+
+ clicked = false;
+ latched = false;
+ showButtonState(buttonArray, i, j, clicked, latched);
+
+ printf(MAIN_STRING "Click the button (%d,%d)\n", i, j);
+ test->click(buttonArray, i, j);
+
+ // Poll for the mouse click event
+
+ test->poll(buttonArray);
+
+ // Now it should be clicked and latched
+
+ clicked = true;
+ latched = true;
+ showButtonState(buttonArray, i, j, clicked, latched);
+
+ // Wait a bit, then release the mouse button
+
+ usleep(200*1000);
+ test->release(buttonArray, i, j);
+
+ // Poll for the mouse release event (of course this can hang if something fails)
+
+ test->poll(buttonArray);
+
+ // Now it should be un-clicked and latched
+
+ clicked = false;
+ latched = true;
+ showButtonState(buttonArray, i, j, clicked, latched);
+
+ usleep(300*1000);
+ }
+ }
+ updateMemoryUsage(g_mmPrevious, "After pushing buttons");
+
+ // Clean up and exit
+
+ printf(MAIN_STRING "Clean-up and exit\n");
+ delete buttonArray;
+ updateMemoryUsage(g_mmPrevious, "After deleting the button array");
+ delete test;
+ updateMemoryUsage(g_mmPrevious, "After deleting the test");
+ updateMemoryUsage(g_mmInitial, "Final memory usage");
+ message("Peak memory usage: %8d\n", g_mmPeak - g_mmInitial);
+ return 0;
+}
+
diff --git a/NxWidgets/UnitTests/CListBox/Makefile b/NxWidgets/UnitTests/CListBox/Makefile
new file mode 100644
index 000000000..9f3d5721d
--- /dev/null
+++ b/NxWidgets/UnitTests/CListBox/Makefile
@@ -0,0 +1,172 @@
+#################################################################################
+# NxWidgets/UnitTests/CListBox/Makefile
+#
+# Copyright (C) 2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+# me be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#################################################################################
+
+TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'}
+
+-include $(TOPDIR)/.config
+-include $(TOPDIR)/Make.defs
+include $(APPDIR)/Make.defs
+
+# Add the path to the NXWidget include directory to the CFLAGS
+
+NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets"
+NXWIDGETS_INC="$(NXWIDGETS_DIR)/include"
+NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)"
+
+INCDIR=$(TOPDIR)/tools/incdir.sh
+ifeq ($(WINTOOL),y)
+ CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"}
+else
+ CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"}
+endif
+
+# Get the path to the archiver tool
+
+TESTTOOL_DIR="$(TESTDIR)/../tools"
+ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh
+
+# Hello, World! C++ Example
+
+ASRCS =
+CSRCS =
+CXXSRCS = main.cxx clistboxtest.cxx
+
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+COBJS = $(CSRCS:.c=$(OBJEXT))
+CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS)
+OBJS = $(AOBJS) $(COBJS) $(CXXOBJS)
+
+POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)"
+ifeq ($(WINTOOL),y)
+ BIN = "${shell cygpath -w $(POSIX_BIN)}"
+else
+ BIN = $(POSIX_BIN)
+endif
+
+ROOTDEPPATH = --dep-path .
+
+# helloxx built-in application info
+
+APPNAME = clistbox
+PRIORITY = SCHED_PRIORITY_DEFAULT
+STACKSIZE = 2048
+
+# Common build
+
+VPATH =
+
+all: .built
+.PHONY: clean depend context disclean chkcxx chklib
+
+# Object file creation targets
+
+$(AOBJS): %$(OBJEXT): %.S
+ $(call ASSEMBLE, $<, $@)
+
+$(COBJS): %$(OBJEXT): %.c
+ $(call COMPILE, $<, $@)
+
+$(CXXOBJS): %$(OBJEXT): %.cxx
+ $(call COMPILEXX, $<, $@)
+
+# Verify that the NuttX configuration is setup to support C++
+
+chkcxx:
+ifneq ($(CONFIG_HAVE_CXX),y)
+ @echo ""
+ @echo "In order to use this example, you toolchain must support must"
+ @echo ""
+ @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support"
+ @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file"
+ @echo " of the configuration that you are using."
+ @echo ""
+ @exit 1
+endif
+
+# Verify that the NXWidget library has been built
+
+chklib:
+ @( \
+ if [ ! -e "$(NXWIDGETS_LIB)" ]; then \
+ echo "$(NXWIDGETS_LIB) does not exist."; \
+ echo "Please go to $(NXWIDGETS_DIR)"; \
+ echo "and rebuild the library"; \
+ exit 1; \
+ fi; \
+ )
+
+# Library creation targets
+
+$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work.
+
+.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB)
+ @( for obj in $(OBJS) ; do \
+ $(call ARCHIVE, $(BIN), $${obj}); \
+ done ; )
+ifeq ($(WINTOOL),y)
+ @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+else
+ @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+endif
+ @touch .built
+
+# Standard housekeeping targets
+
+.context:
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+ $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
+endif
+ @touch $@
+
+context: .context
+
+.depend: Makefile $(SRCS)
+ @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep
+ @touch $@
+
+depend: .depend
+
+clean:
+ @rm -f *.o *~ .*.swp .built
+ $(call CLEAN)
+
+distclean: clean
+ @rm -f Make.dep .depend
+
+-include Make.dep
diff --git a/NxWidgets/UnitTests/CListBox/clistboxtest.cxx b/NxWidgets/UnitTests/CListBox/clistboxtest.cxx
new file mode 100644
index 000000000..cd41dacc7
--- /dev/null
+++ b/NxWidgets/UnitTests/CListBox/clistboxtest.cxx
@@ -0,0 +1,224 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CListBox/clistboxtest.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cerrno>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+#include <nuttx/nx/nxfonts.h>
+
+#include "nxconfig.hxx"
+#include "cbgwindow.hxx"
+#include "clistboxtest.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// CListBoxTest Method Implementations
+/////////////////////////////////////////////////////////////////////////////
+
+// CListBoxTest Constructor
+
+CListBoxTest::CListBoxTest()
+{
+ // Initialize state data
+
+ m_widgetControl = (CWidgetControl *)NULL;
+ m_bgWindow = (CBgWindow *)NULL;
+}
+
+// CListBoxTest Descriptor
+
+CListBoxTest::~CListBoxTest(void)
+{
+ disconnect();
+}
+
+// Connect to the NX server
+
+bool CListBoxTest::connect(void)
+{
+ // Connect to the server
+
+ bool nxConnected = CNxServer::connect();
+ if (nxConnected)
+ {
+ // Set the background color
+
+ if (!setBackgroundColor(CONFIG_CLISTBOXTEST_BGCOLOR))
+ {
+ message("CListBoxTest::connect: setBackgroundColor failed\n");
+ }
+ }
+
+ return nxConnected;
+}
+
+// Disconnect from the NX server
+
+void CListBoxTest::disconnect(void)
+{
+ // Close the window
+
+ if (m_bgWindow)
+ {
+ delete m_bgWindow;
+ m_bgWindow = (CBgWindow *)NULL;
+ }
+
+ // Free the widget control instance
+
+ if (m_widgetControl)
+ {
+ delete m_widgetControl;
+ m_widgetControl = (CWidgetControl *)NULL;
+ }
+
+ // And disconnect from the server
+
+ CNxServer::disconnect();
+}
+
+// Create the background window instance. This function illustrates
+// the basic steps to instantiate any window:
+//
+// 1) Create a dumb CWigetControl instance
+// 2) Pass the dumb CWidgetControl instance to the window constructor
+// that inherits from INxWindow. This will "smarten" the CWidgetControl
+// instance with some window knowlede
+// 3) Call the open() method on the window to display the window.
+// 4) After that, the fully smartened CWidgetControl instance can
+// be used to generate additional widgets by passing it to the
+// widget constructor
+
+bool CListBoxTest::createWindow(void)
+{
+ // Initialize the widget control using the default style
+
+ m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL);
+
+ // Get an (uninitialized) instance of the background window as a class
+ // that derives from INxWindow.
+
+ m_bgWindow = getBgWindow(m_widgetControl);
+ if (!m_bgWindow)
+ {
+ message("CListBoxTest::createWindow: Failed to create CBgWindow instance\n");
+ disconnect();
+ return false;
+ }
+
+ // Open (and initialize) the window
+
+ bool success = m_bgWindow->open();
+ if (!success)
+ {
+ message("CListBoxTest::createWindow: Failed to open background window\n");
+ disconnect();
+ return false;
+ }
+
+ return true;
+}
+
+// Create a listbox in the center of the window
+
+CListBox *CListBoxTest::createListBox(void)
+{
+ // Get the size of the display
+
+ struct nxgl_size_s windowSize;
+ if (!m_bgWindow->getSize(&windowSize))
+ {
+ printf("CListBoxTest::createListBox: Failed to get window size\n");
+ disconnect();
+ return false;
+ }
+
+ // Put the listbox in the center of the display
+
+ nxgl_coord_t listboxWidth = windowSize.w >> 1;
+ nxgl_coord_t listboxX = windowSize.w >> 2;
+
+ nxgl_coord_t listboxHeight = windowSize.h >> 1;
+ nxgl_coord_t listboxY = windowSize.h >> 2;
+
+ // Create the listbox
+
+ CListBox *listbox = new CListBox(m_widgetControl,
+ listboxX, listboxY,
+ listboxWidth, listboxHeight);
+ if (!listbox)
+ {
+ printf("CListBoxTest::createListBox: Failed to create CListBox\n");
+ disconnect();
+ }
+ return listbox;
+}
+
+// (Re-)draw the listbox.
+
+void CListBoxTest::showListBox(CListBox *listbox)
+{
+ listbox->enable(); // Un-necessary, the widget is enabled by default
+ listbox->enableDrawing();
+ listbox->redraw();
+}
diff --git a/NxWidgets/UnitTests/CListBox/clistboxtest.hxx b/NxWidgets/UnitTests/CListBox/clistboxtest.hxx
new file mode 100644
index 000000000..5cc356849
--- /dev/null
+++ b/NxWidgets/UnitTests/CListBox/clistboxtest.hxx
@@ -0,0 +1,147 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CListBox/clistboxtest.hxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef __UNITTESTS_CLISTBOX_CLISTBOXTEST_HXX
+#define __UNITTESTS_CLISTBOX_CLISTBOXTEST_HXX
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <semaphore.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "nxconfig.hxx"
+#include "cwidgetcontrol.hxx"
+#include "ccallback.hxx"
+#include "cbgwindow.hxx"
+#include "cnxserver.hxx"
+#include "clistbox.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+// Configuration ////////////////////////////////////////////////////////////
+
+#ifndef CONFIG_HAVE_CXX
+# error "CONFIG_HAVE_CXX must be defined"
+#endif
+
+#ifndef CONFIG_CLISTBOXTEST_BGCOLOR
+# define CONFIG_CLISTBOXTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR
+#endif
+
+// What is the entry point called?
+
+#ifdef CONFIG_NSH_BUILTIN_APPS
+# define MAIN_NAME clistbox_main
+# define MAIN_STRING "clistbox_main: "
+#else
+# define MAIN_NAME user_start
+# define MAIN_STRING "user_start: "
+#endif
+
+// If debug is enabled, use the debug function, lib_rawprintf() instead
+// of printf() so that the output is synchronized.
+
+#ifdef CONFIG_DEBUG
+# define message lib_lowprintf
+#else
+# define message printf
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Classes
+/////////////////////////////////////////////////////////////////////////////
+
+using namespace NXWidgets;
+
+class CListBoxTest : public CNxServer
+{
+private:
+ CWidgetControl *m_widgetControl; // The controlling widget for the window
+ CBgWindow *m_bgWindow; // Background window instance
+
+public:
+ // Constructor/destructors
+
+ CListBoxTest(void);
+ ~CListBoxTest(void);
+
+ // Initializer/unitializer. These methods encapsulate the basic steps for
+ // starting and stopping the NX server
+
+ bool connect(void);
+ void disconnect(void);
+
+ // Create a window. This method provides the general operations for
+ // creating a window that you can draw within.
+ //
+ // Those general operations are:
+ // 1) Create a dumb CWigetControl instance
+ // 2) Pass the dumb CWidgetControl instance to the window constructor
+ // that inherits from INxWindow. This will "smarten" the CWidgetControl
+ // instance with some window knowlede
+ // 3) Call the open() method on the window to display the window.
+ // 4) After that, the fully smartened CWidgetControl instance can
+ // be used to generate additional widgets by passing it to the
+ // widget constructor
+
+ bool createWindow(void);
+
+ // Create a listbox in the center of the window
+
+ CListBox *createListBox(void);
+
+ // (Re-)draw the listbox.
+
+ void showListBox(CListBox *listbox);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+#endif // __UNITTESTS_CLISTBOX_CLISTBOXTEST_HXX
diff --git a/NxWidgets/UnitTests/CListBox/main.cxx b/NxWidgets/UnitTests/CListBox/main.cxx
new file mode 100644
index 000000000..5783e255d
--- /dev/null
+++ b/NxWidgets/UnitTests/CListBox/main.cxx
@@ -0,0 +1,327 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CListBox/main.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <unistd.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "clistboxtest.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+static unsigned int g_mmInitial;
+static unsigned int g_mmPrevious;
+static unsigned int g_mmPeak;
+
+static FAR const char *g_options[] =
+{
+ "American groundnut (Apios americana)",
+ "Azuki bean (Vigna angularis)",
+ "Black-eyed pea (Vigna unguiculata subsp. unguiculata)",
+ "Chickpea (Cicer arietinum)",
+ "Common bean (Phaseolus vulgaris)",
+ "Drumstick (Moringa oleifera)",
+ "Dolichos bean (Lablab purpureus)",
+ "Fava bean (Vicia faba)",
+ "Garbanzo (Cicer arietinum)",
+ "Green bean (Phaseolus vulgaris)",
+ "Guar (Cyamopsis tetragonoloba)",
+ "Gumbo (Abelmoschus esculentus)",
+ "Horse gram (Macrotyloma uniflorum)",
+ "Indian pea (Lathyrus sativus)",
+ "Lentil (Lens culinaris)",
+ "Lima Bean (Phaseolus lunatus)",
+ "Moth bean (Vigna acontifolia)",
+ "Mung bean (Vigna radiata)",
+ "Okra (Abelmoschus esculentus)",
+ "Pea (Pisum sativum)",
+ "Peanut (Arachis hypogaea)",
+ "Pigeon pea (Cajanus cajan)",
+ "Ricebean (Vigna umbellata)",
+ "Runner bean (Phaseolus coccineus)",
+ "Soybean (Glycine max)",
+ "Tarwi (tarhui, chocho; Lupinus mutabilis)",
+ "Tepary bean (Phaseolus acutifolius)",
+ "Urad bean (Vigna mungo)",
+ "Velvet bean (Mucuna pruriens)",
+ "Winged bean (Psophocarpus tetragonolobus)",
+ "Yardlong bean (Vigna unguiculata subsp. sesquipedalis)"
+};
+#define NOPTIONS (sizeof(g_options)/sizeof(FAR const char *))
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+// Suppress name-mangling
+
+extern "C" int MAIN_NAME(int argc, char *argv[]);
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: updateMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void updateMemoryUsage(unsigned int previous,
+ FAR const char *msg)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ /* Show the change from the previous time */
+
+ message("%s: Before: %8d After: %8d Change: %8d\n",
+ msg, previous, mmcurrent.uordblks, mmcurrent.uordblks - previous);
+
+ /* Set up for the next test */
+
+ g_mmPrevious = mmcurrent.uordblks;
+ if ((unsigned int)mmcurrent.uordblks > g_mmPeak)
+ {
+ g_mmPeak = mmcurrent.uordblks;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: initMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void initMemoryUsage(void)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ g_mmInitial = mmcurrent.uordblks;
+ g_mmPrevious = mmcurrent.uordblks;
+ g_mmPeak = mmcurrent.uordblks;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: user_start/nxheaders_main
+/////////////////////////////////////////////////////////////////////////////
+
+int MAIN_NAME(int argc, char *argv[])
+{
+ // Initialize memory monitor logic
+
+ initMemoryUsage();
+
+ // Create an instance of the listbox test
+
+ message(MAIN_STRING "Create CListBoxTest instance\n");
+ CListBoxTest *test = new CListBoxTest();
+ updateMemoryUsage(g_mmPrevious, "After creating CListBoxTest");
+
+ // Connect the NX server
+
+ message(MAIN_STRING "Connect the CListBoxTest instance to the NX server\n");
+ if (!test->connect())
+ {
+ message(MAIN_STRING "Failed to connect the CListBoxTest instance to the NX server\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmPrevious, MAIN_STRING "After connecting to the server");
+
+ // Create a window to draw into
+
+ message(MAIN_STRING "Create a Window\n");
+ if (!test->createWindow())
+ {
+ message(MAIN_STRING "Failed to create a window\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmPrevious, MAIN_STRING "After creating a window");
+
+ // Create a listbox
+
+ message(MAIN_STRING "Create a ListBox\n");
+ CListBox *listbox = test->createListBox();
+ if (!listbox)
+ {
+ message(MAIN_STRING "Failed to create a listbox\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmPrevious, MAIN_STRING "After creating a listbox");
+
+ // Show the initial state of the listbox
+
+ listbox->setAllowMultipleSelections(true);
+ test->showListBox(listbox);
+ sleep(1);
+
+ // Now add items to the list box (in reverse alphabetical order)
+
+ message(MAIN_STRING "Add options to the ListBox\n");
+ for (int i = NOPTIONS - 1; i >= 0; i--)
+ {
+ listbox->addOption(g_options[i],i);
+ test->showListBox(listbox);
+ message(MAIN_STRING "%d. New option %s\n", i, g_options[i]);
+ usleep(500000); // The simulation needs this to let the X11 event loop run
+ }
+ updateMemoryUsage(g_mmPrevious, MAIN_STRING "After adding the listbox items");
+ sleep(1);
+
+ // Sort the list box
+
+ message(MAIN_STRING "Sort the ListBox\n");
+ listbox->sort();
+ test->showListBox(listbox);
+ updateMemoryUsage(g_mmPrevious, MAIN_STRING "After sorting the listbox");
+ sleep(1);
+
+ // Select and remove items from the listbox
+
+ srand(1978);
+ int nOptions;
+ while ((nOptions = listbox->getOptionCount()) > 0)
+ {
+ message(MAIN_STRING "Option count: %d\n", nOptions);
+ if (nOptions <= 5)
+ {
+ message(MAIN_STRING "Selecting all remaining options\n");
+ listbox->selectAllOptions();
+ test->showListBox(listbox);
+ updateMemoryUsage(g_mmPrevious, MAIN_STRING "After selecting all options");
+ sleep(1);
+
+ message(MAIN_STRING "Removing all remaining options\n");
+ listbox->removeAllOptions();
+ updateMemoryUsage(g_mmPrevious, MAIN_STRING "After removing all options");
+ test->showListBox(listbox);
+ }
+ else
+ {
+ int selected[5];
+
+ message(MAIN_STRING "Selecting five options\n");
+ for (int i = 0; i < 5; i++)
+ {
+ selected[i] = ((nOptions - 1) * rand()) / MAX_RAND;
+ message(MAIN_STRING "Selecting option %d\n", selected[i]);
+ listbox->removeOption(selected[i]);
+ test->showListBox(listbox);
+ usleep(500000);
+ }
+ updateMemoryUsage(g_mmPrevious, MAIN_STRING "After selecting five options");
+
+ message(MAIN_STRING "De-selecting options\n");
+ int index;
+ int count = 0;
+ while ((index = listbox->getSelectedIndex()) >= 0)
+ {
+ message(MAIN_STRING "De-selecting option %d\n", index);
+ listbox->deselectOption(index);
+ test->showListBox(listbox);
+ count++;
+ usleep(500000);
+ }
+
+ message(MAIN_STRING "%s: %d options de-selected\n",
+ count == 5 ? "OK" : "ERROR", count);
+ updateMemoryUsage(g_mmPrevious, MAIN_STRING "After de-selecting options");
+
+ message(MAIN_STRING "Removing the selected options\n");
+ for (int i = 0; i < 5; i++)
+ {
+ message(MAIN_STRING "Removing option %d\n", selected[i]);
+ listbox->removeOption(selected[i]);
+ test->showListBox(listbox);
+ usleep(500000);
+ }
+ updateMemoryUsage(g_mmPrevious, MAIN_STRING "After removing five options");
+ }
+ sleep(1);
+ }
+ updateMemoryUsage(g_mmPrevious, MAIN_STRING "After the listbox is empty again");
+ sleep(1);
+
+ // Clean up and exit
+
+ message(MAIN_STRING "Clean-up and exit\n");
+ delete listbox;
+ updateMemoryUsage(g_mmPrevious, "After deleting the listbox");
+ delete test;
+ updateMemoryUsage(g_mmPrevious, "After deleting the test");
+ updateMemoryUsage(g_mmInitial, "Final memory usage");
+ message("Peak memory usage: %8d\n", g_mmPeak - g_mmInitial);
+ return 0;
+}
+
diff --git a/NxWidgets/UnitTests/CProgressBar/Makefile b/NxWidgets/UnitTests/CProgressBar/Makefile
new file mode 100644
index 000000000..53d66fefa
--- /dev/null
+++ b/NxWidgets/UnitTests/CProgressBar/Makefile
@@ -0,0 +1,172 @@
+#################################################################################
+# NxWidgets/UnitTests/CProgressBar/Makefile
+#
+# Copyright (C) 2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+# me be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#################################################################################
+
+TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'}
+
+-include $(TOPDIR)/.config
+-include $(TOPDIR)/Make.defs
+include $(APPDIR)/Make.defs
+
+# Add the path to the NXWidget include directory to the CFLAGS
+
+NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets"
+NXWIDGETS_INC="$(NXWIDGETS_DIR)/include"
+NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)"
+
+INCDIR=$(TOPDIR)/tools/incdir.sh
+ifeq ($(WINTOOL),y)
+ CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"}
+else
+ CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"}
+endif
+
+# Get the path to the archiver tool
+
+TESTTOOL_DIR="$(TESTDIR)/../tools"
+ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh
+
+# Hello, World! C++ Example
+
+ASRCS =
+CSRCS =
+CXXSRCS = main.cxx cprogressbartest.cxx
+
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+COBJS = $(CSRCS:.c=$(OBJEXT))
+CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS)
+OBJS = $(AOBJS) $(COBJS) $(CXXOBJS)
+
+POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)"
+ifeq ($(WINTOOL),y)
+ BIN = "${shell cygpath -w $(POSIX_BIN)}"
+else
+ BIN = $(POSIX_BIN)
+endif
+
+ROOTDEPPATH = --dep-path .
+
+# helloxx built-in application info
+
+APPNAME = cprogressbar
+PRIORITY = SCHED_PRIORITY_DEFAULT
+STACKSIZE = 2048
+
+# Common build
+
+VPATH =
+
+all: .built
+.PHONY: clean depend context disclean chkcxx chklib
+
+# Object file creation targets
+
+$(AOBJS): %$(OBJEXT): %.S
+ $(call ASSEMBLE, $<, $@)
+
+$(COBJS): %$(OBJEXT): %.c
+ $(call COMPILE, $<, $@)
+
+$(CXXOBJS): %$(OBJEXT): %.cxx
+ $(call COMPILEXX, $<, $@)
+
+# Verify that the NuttX configuration is setup to support C++
+
+chkcxx:
+ifneq ($(CONFIG_HAVE_CXX),y)
+ @echo ""
+ @echo "In order to use this example, you toolchain must support must"
+ @echo ""
+ @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support"
+ @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file"
+ @echo " of the configuration that you are using."
+ @echo ""
+ @exit 1
+endif
+
+# Verify that the NXWidget library has been built
+
+chklib:
+ @( \
+ if [ ! -e "$(NXWIDGETS_LIB)" ]; then \
+ echo "$(NXWIDGETS_LIB) does not exist."; \
+ echo "Please go to $(NXWIDGETS_DIR)"; \
+ echo "and rebuild the library"; \
+ exit 1; \
+ fi; \
+ )
+
+# Library creation targets
+
+$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work.
+
+.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB)
+ @( for obj in $(OBJS) ; do \
+ $(call ARCHIVE, $(BIN), $${obj}); \
+ done ; )
+ifeq ($(WINTOOL),y)
+ @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+else
+ @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+endif
+ @touch .built
+
+# Standard housekeeping targets
+
+.context:
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+ $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
+endif
+ @touch $@
+
+context: .context
+
+.depend: Makefile $(SRCS)
+ @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep
+ @touch $@
+
+depend: .depend
+
+clean:
+ @rm -f *.o *~ .*.swp .built
+ $(call CLEAN)
+
+distclean: clean
+ @rm -f Make.dep .depend
+
+-include Make.dep
diff --git a/NxWidgets/UnitTests/CProgressBar/cprogressbartest.cxx b/NxWidgets/UnitTests/CProgressBar/cprogressbartest.cxx
new file mode 100644
index 000000000..60821d751
--- /dev/null
+++ b/NxWidgets/UnitTests/CProgressBar/cprogressbartest.cxx
@@ -0,0 +1,224 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/ProgressBar/cprogressbartest.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cerrno>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+#include <nuttx/nx/nxfonts.h>
+
+#include "nxconfig.hxx"
+#include "cbgwindow.hxx"
+#include "cprogressbartest.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// CProgressBarTest Method Implementations
+/////////////////////////////////////////////////////////////////////////////
+
+// CProgressBarTest Constructor
+
+CProgressBarTest::CProgressBarTest()
+{
+ // Initialize state data
+
+ m_widgetControl = (CWidgetControl *)NULL;
+ m_bgWindow = (CBgWindow *)NULL;
+}
+
+// CProgressBarTest Descriptor
+
+CProgressBarTest::~CProgressBarTest(void)
+{
+ disconnect();
+}
+
+// Connect to the NX server
+
+bool CProgressBarTest::connect(void)
+{
+ // Connect to the server
+
+ bool nxConnected = CNxServer::connect();
+ if (nxConnected)
+ {
+ // Set the background color
+
+ if (!setBackgroundColor(CONFIG_CPROGRESSBARTEST_BGCOLOR))
+ {
+ message("CProgressBarTest::connect: setBackgroundColor failed\n");
+ }
+ }
+
+ return nxConnected;
+}
+
+// Disconnect from the NX server
+
+void CProgressBarTest::disconnect(void)
+{
+ // Close the window
+
+ if (m_bgWindow)
+ {
+ delete m_bgWindow;
+ m_bgWindow = (CBgWindow *)NULL;
+ }
+
+ // Free the widget control instance
+
+ if (m_widgetControl)
+ {
+ delete m_widgetControl;
+ m_widgetControl = (CWidgetControl *)NULL;
+ }
+
+ // And disconnect from the server
+
+ CNxServer::disconnect();
+}
+
+// Create the background window instance. This function illustrates
+// the basic steps to instantiate any window:
+//
+// 1) Create a dumb CWigetControl instance
+// 2) Pass the dumb CWidgetControl instance to the window constructor
+// that inherits from INxWindow. This will "smarten" the CWidgetControl
+// instance with some window knowlede
+// 3) Call the open() method on the window to display the window.
+// 4) After that, the fully smartened CWidgetControl instance can
+// be used to generate additional widgets by passing it to the
+// widget constructor
+
+bool CProgressBarTest::createWindow(void)
+{
+ // Initialize the widget control using the default style
+
+ m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL);
+
+ // Get an (uninitialized) instance of the background window as a class
+ // that derives from INxWindow.
+
+ m_bgWindow = getBgWindow(m_widgetControl);
+ if (!m_bgWindow)
+ {
+ message("CProgressBarTest::createWindow: Failed to create CBgWindow instance\n");
+ disconnect();
+ return false;
+ }
+
+ // Open (and initialize) the window
+
+ bool success = m_bgWindow->open();
+ if (!success)
+ {
+ message("CProgressBarTest::createWindow: Failed to open background window\n");
+ disconnect();
+ return false;
+ }
+
+ return true;
+}
+
+// Create a bar in the center of the window
+
+CProgressBar *CProgressBarTest::createProgressBar(void)
+{
+ // Get the size of the display
+
+ struct nxgl_size_s windowSize;
+ if (!m_bgWindow->getSize(&windowSize))
+ {
+ printf("CProgressBarTest::createProgressBar: Failed to get window size\n");
+ disconnect();
+ return false;
+ }
+
+ // Put the bar in the center of the display
+
+ nxgl_coord_t barWidth = windowSize.w >> 1;
+ nxgl_coord_t barX = windowSize.w >> 2;
+
+ nxgl_coord_t barHeight = 16;
+ nxgl_coord_t barY = (windowSize.h - barHeight) >> 1;
+
+ // Create the bar
+
+ CProgressBar *bar = new CProgressBar(m_widgetControl,
+ barX, barY,
+ barWidth, barHeight);
+ if (!bar)
+ {
+ printf("CProgressBarTest::createProgressBar: Failed to create CProgressBar\n");
+ disconnect();
+ }
+ return bar;
+}
+
+// (Re-)draw the bar.
+
+void CProgressBarTest::showProgressBar(CProgressBar *bar)
+{
+ bar->enable(); // Un-necessary, the widget is enabled by default
+ bar->enableDrawing();
+ bar->redraw();
+}
diff --git a/NxWidgets/UnitTests/CProgressBar/cprogressbartest.hxx b/NxWidgets/UnitTests/CProgressBar/cprogressbartest.hxx
new file mode 100644
index 000000000..f5058a0c4
--- /dev/null
+++ b/NxWidgets/UnitTests/CProgressBar/cprogressbartest.hxx
@@ -0,0 +1,147 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CProgressBar/cprogressbartest.hxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef __UNITTESTS_CPROGRESSBAR_CPROGRESSBARTEST_HXX
+#define __UNITTESTS_CPROGRESSBAR_CPROGRESSBARTEST_HXX
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <semaphore.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "nxconfig.hxx"
+#include "cwidgetcontrol.hxx"
+#include "ccallback.hxx"
+#include "cbgwindow.hxx"
+#include "cnxserver.hxx"
+#include "cprogressbar.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+// Configuration ////////////////////////////////////////////////////////////
+
+#ifndef CONFIG_HAVE_CXX
+# error "CONFIG_HAVE_CXX must be defined"
+#endif
+
+#ifndef CONFIG_CPROGRESSBARTEST_BGCOLOR
+# define CONFIG_CPROGRESSBARTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR
+#endif
+
+// What is the entry point called?
+
+#ifdef CONFIG_NSH_BUILTIN_APPS
+# define MAIN_NAME cprogressbar_main
+# define MAIN_STRING "cprogressbar_main: "
+#else
+# define MAIN_NAME user_start
+# define MAIN_STRING "user_start: "
+#endif
+
+// If debug is enabled, use the debug function, lib_rawprintf() instead
+// of printf() so that the output is synchronized.
+
+#ifdef CONFIG_DEBUG
+# define message lib_lowprintf
+#else
+# define message printf
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Classes
+/////////////////////////////////////////////////////////////////////////////
+
+using namespace NXWidgets;
+
+class CProgressBarTest : public CNxServer
+{
+private:
+ CWidgetControl *m_widgetControl; // The controlling widget for the window
+ CBgWindow *m_bgWindow; // Background window instance
+
+public:
+ // Constructor/destructors
+
+ CProgressBarTest(void);
+ ~CProgressBarTest(void);
+
+ // Initializer/unitializer. These methods encapsulate the basic steps for
+ // starting and stopping the NX server
+
+ bool connect(void);
+ void disconnect(void);
+
+ // Create a window. This method provides the general operations for
+ // creating a window that you can draw within.
+ //
+ // Those general operations are:
+ // 1) Create a dumb CWigetControl instance
+ // 2) Pass the dumb CWidgetControl instance to the window constructor
+ // that inherits from INxWindow. This will "smarten" the CWidgetControl
+ // instance with some window knowlede
+ // 3) Call the open() method on the window to display the window.
+ // 4) After that, the fully smartened CWidgetControl instance can
+ // be used to generate additional widgets by passing it to the
+ // widget constructor
+
+ bool createWindow(void);
+
+ // Create a progress bar in the center of the window
+
+ CProgressBar *createProgressBar(void);
+
+ // (Re-)draw the progress bar.
+
+ void showProgressBar(CProgressBar *bar);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+#endif // __UNITTESTS_CPROGRESSBAR_CPROGRESSBARTEST_HXX
diff --git a/NxWidgets/UnitTests/CProgressBar/main.cxx b/NxWidgets/UnitTests/CProgressBar/main.cxx
new file mode 100644
index 000000000..525c509d3
--- /dev/null
+++ b/NxWidgets/UnitTests/CProgressBar/main.cxx
@@ -0,0 +1,238 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CProgressBar/main.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <unistd.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "cprogressbartest.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+#define MAX_PROGRESSBAR 50
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+static unsigned int g_mmInitial;
+static unsigned int g_mmprevious;
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+// Suppress name-mangling
+
+extern "C" int MAIN_NAME(int argc, char *argv[]);
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: updateMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void updateMemoryUsage(unsigned int previous,
+ FAR const char *msg)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ /* Show the change from the previous time */
+
+ message("\n%s:\n", msg);
+ message(" Before: %8d After: %8d Change: %8d\n\n",
+ previous, mmcurrent.uordblks, mmcurrent.uordblks - previous);
+
+ /* Set up for the next test */
+
+ g_mmprevious = mmcurrent.uordblks;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: initMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void initMemoryUsage(void)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ g_mmInitial = mmcurrent.uordblks;
+ g_mmprevious = mmcurrent.uordblks;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: user_start/nxheaders_main
+/////////////////////////////////////////////////////////////////////////////
+
+int MAIN_NAME(int argc, char *argv[])
+{
+ // Initialize memory monitor logic
+
+ initMemoryUsage();
+
+ // Create an instance of the checkbox test
+
+ message(MAIN_STRING "Create CProgressBarTest instance\n");
+ CProgressBarTest *test = new CProgressBarTest();
+ updateMemoryUsage(g_mmprevious, "After creating CProgressBarTest");
+
+ // Connect the NX server
+
+ message(MAIN_STRING "Connect the CProgressBarTest instance to the NX server\n");
+ if (!test->connect())
+ {
+ message(MAIN_STRING "Failed to connect the CProgressBarTest instance to the NX server\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After connecting to the server");
+
+ // Create a window to draw into
+
+ message(MAIN_STRING "Create a Window\n");
+ if (!test->createWindow())
+ {
+ message(MAIN_STRING "Failed to create a window\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating a window");
+
+ // Create a progress bar
+
+ message(MAIN_STRING "Create a ProgressBar\n");
+ CProgressBar *bar = test->createProgressBar();
+ if (!bar)
+ {
+ message(MAIN_STRING "Failed to create a progress bar\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating a progress bar");
+
+ // Set the progress bar minimum and maximum values
+
+ bar->setMinimumValue(0);
+ bar->setMaximumValue(MAX_PROGRESSBAR);
+ bar->setValue(0);
+ bar->hidePercentageText();
+ message(MAIN_STRING "ProgressBar range %d->%d Initial value %d\n",
+ bar->getMinimumValue(), bar->getMaximumValue(),
+ bar->getValue());
+
+ // Show the initial state of the checkbox
+
+ test->showProgressBar(bar);
+ sleep(1);
+
+ // Now move the progress bar up from 0 to 100% (with percentages off)
+
+ for (int i = 0; i <= MAX_PROGRESSBAR; i++)
+ {
+ bar->setValue(i);
+ test->showProgressBar(bar);
+ message(MAIN_STRING "%d. New value %d\n", i, bar->getValue());
+ usleep(1000); // The simulation needs this to let the X11 event loop run
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After moving the progress bar up #1");
+ usleep(500*1000);
+
+ // Now move the progress bar up from 0 to 100% (with percentages off)
+
+ bar->showPercentageText();
+ bar->setValue(0);
+ test->showProgressBar(bar);
+ usleep(500*1000);
+
+ for (int i = 0; i <= MAX_PROGRESSBAR; i++)
+ {
+ bar->setValue(i);
+ test->showProgressBar(bar);
+ message(MAIN_STRING "%d. New value %d\n", i, bar->getValue());
+ usleep(1000); // The simulation needs this to let the X11 event loop run
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After moving the progress bar up #2");
+ sleep(1);
+
+ // Clean up and exit
+
+ message(MAIN_STRING "Clean-up and exit\n");
+ delete bar;
+ updateMemoryUsage(g_mmprevious, "After deleting the progress bar");
+ delete test;
+ updateMemoryUsage(g_mmprevious, "After deleting the test");
+ updateMemoryUsage(g_mmInitial, "Final memory usage");
+ return 0;
+}
+
diff --git a/NxWidgets/UnitTests/CRadioButton/Makefile b/NxWidgets/UnitTests/CRadioButton/Makefile
new file mode 100644
index 000000000..0b4906dd8
--- /dev/null
+++ b/NxWidgets/UnitTests/CRadioButton/Makefile
@@ -0,0 +1,172 @@
+#################################################################################
+# NxWidgets/UnitTests/CRadioButton/Makefile
+#
+# Copyright (C) 2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+# me be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#################################################################################
+
+TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'}
+
+-include $(TOPDIR)/.config
+-include $(TOPDIR)/Make.defs
+include $(APPDIR)/Make.defs
+
+# Add the path to the NXWidget include directory to the CFLAGS
+
+NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets"
+NXWIDGETS_INC="$(NXWIDGETS_DIR)/include"
+NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)"
+
+INCDIR=$(TOPDIR)/tools/incdir.sh
+ifeq ($(WINTOOL),y)
+ CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"}
+else
+ CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"}
+endif
+
+# Get the path to the archiver tool
+
+TESTTOOL_DIR="$(TESTDIR)/../tools"
+ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh
+
+# Hello, World! C++ Example
+
+ASRCS =
+CSRCS =
+CXXSRCS = main.cxx cradiobuttontest.cxx
+
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+COBJS = $(CSRCS:.c=$(OBJEXT))
+CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS)
+OBJS = $(AOBJS) $(COBJS) $(CXXOBJS)
+
+POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)"
+ifeq ($(WINTOOL),y)
+ BIN = "${shell cygpath -w $(POSIX_BIN)}"
+else
+ BIN = $(POSIX_BIN)
+endif
+
+ROOTDEPPATH = --dep-path .
+
+# helloxx built-in application info
+
+APPNAME = cradiobutton
+PRIORITY = SCHED_PRIORITY_DEFAULT
+STACKSIZE = 2048
+
+# Common build
+
+VPATH =
+
+all: .built
+.PHONY: clean depend context disclean chkcxx chklib
+
+# Object file creation targets
+
+$(AOBJS): %$(OBJEXT): %.S
+ $(call ASSEMBLE, $<, $@)
+
+$(COBJS): %$(OBJEXT): %.c
+ $(call COMPILE, $<, $@)
+
+$(CXXOBJS): %$(OBJEXT): %.cxx
+ $(call COMPILEXX, $<, $@)
+
+# Verify that the NuttX configuration is setup to support C++
+
+chkcxx:
+ifneq ($(CONFIG_HAVE_CXX),y)
+ @echo ""
+ @echo "In order to use this example, you toolchain must support must"
+ @echo ""
+ @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support"
+ @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file"
+ @echo " of the configuration that you are using."
+ @echo ""
+ @exit 1
+endif
+
+# Verify that the NXWidget library has been built
+
+chklib:
+ @( \
+ if [ ! -e "$(NXWIDGETS_LIB)" ]; then \
+ echo "$(NXWIDGETS_LIB) does not exist."; \
+ echo "Please go to $(NXWIDGETS_DIR)"; \
+ echo "and rebuild the library"; \
+ exit 1; \
+ fi; \
+ )
+
+# Library creation targets
+
+$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work.
+
+.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB)
+ @( for obj in $(OBJS) ; do \
+ $(call ARCHIVE, $(BIN), $${obj}); \
+ done ; )
+ifeq ($(WINTOOL),y)
+ @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+else
+ @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+endif
+ @touch .built
+
+# Standard housekeeping targets
+
+.context:
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+ $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
+endif
+ @touch $@
+
+context: .context
+
+.depend: Makefile $(SRCS)
+ @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep
+ @touch $@
+
+depend: .depend
+
+clean:
+ @rm -f *.o *~ .*.swp .built
+ $(call CLEAN)
+
+distclean: clean
+ @rm -f Make.dep .depend
+
+-include Make.dep
diff --git a/NxWidgets/UnitTests/CRadioButton/cradiobuttontest.cxx b/NxWidgets/UnitTests/CRadioButton/cradiobuttontest.cxx
new file mode 100644
index 000000000..f97089ce7
--- /dev/null
+++ b/NxWidgets/UnitTests/CRadioButton/cradiobuttontest.cxx
@@ -0,0 +1,305 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CRadioButton/cradiobuttontest.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cerrno>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+#include <nuttx/nx/nxfonts.h>
+
+#include "nxconfig.hxx"
+#include "cbgwindow.hxx"
+#include "cradiobuttontest.hxx"
+#include "cbitmap.hxx"
+#include "glyphs.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// CRadioButtonTest Method Implementations
+/////////////////////////////////////////////////////////////////////////////
+
+// CRadioButtonTest Constructor
+
+CRadioButtonTest::CRadioButtonTest()
+{
+ // Initialize state data
+
+ m_widgetControl = (CWidgetControl *)NULL;
+ m_bgWindow = (CBgWindow *)NULL;
+
+ // Peek at the radio button glyph to get a good estimate of the size
+
+ m_size.w = g_radioButtonOn.width;
+ m_size.h = g_radioButtonOn.height;
+}
+
+// CRadioButtonTest Descriptor
+
+CRadioButtonTest::~CRadioButtonTest(void)
+{
+ disconnect();
+}
+
+// Connect to the NX server
+
+bool CRadioButtonTest::connect(void)
+{
+ // Connect to the server
+
+ bool nxConnected = CNxServer::connect();
+ if (nxConnected)
+ {
+ // Set the background color
+
+ if (!setBackgroundColor(CONFIG_CRADIOBUTTONTEST_BGCOLOR))
+ {
+ message("CRadioButtonTest::connect: setBackgroundColor failed\n");
+ }
+ }
+
+ return nxConnected;
+}
+
+// Disconnect from the NX server
+
+void CRadioButtonTest::disconnect(void)
+{
+ // Free the radiobutton group
+
+ if (m_radioButtonGroup)
+ {
+ delete m_radioButtonGroup;
+ m_radioButtonGroup = (CRadioButtonGroup *)NULL;
+ }
+
+ // Close the window
+
+ if (m_bgWindow)
+ {
+ delete m_bgWindow;
+ }
+
+ // Free the widget control instance
+
+ if (m_widgetControl)
+ {
+ delete m_widgetControl;
+ }
+
+ // And disconnect from the server
+
+ CNxServer::disconnect();
+}
+
+// Create the background window instance. This function illustrates
+// the basic steps to instantiate any window:
+//
+// 1) Create a dumb CWigetControl instance
+// 2) Pass the dumb CWidgetControl instance to the window constructor
+// that inherits from INxWindow. This will "smarten" the CWidgetControl
+// instance with some window knowlede
+// 3) Call the open() method on the window to display the window.
+// 4) After that, the fully smartened CWidgetControl instance can
+// be used to generate additional widgets by passing it to the
+// widget constructor
+
+bool CRadioButtonTest::createWindow(void)
+{
+ // Initialize the widget control using the default style
+
+ m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL);
+
+ // Get an (uninitialized) instance of the background window as a class
+ // that derives from INxWindow.
+
+ m_bgWindow = getBgWindow(m_widgetControl);
+ if (!m_bgWindow)
+ {
+ message("CRadioButtonTest::createGraphics: Failed to create CBgWindow instance\n");
+ delete m_widgetControl;
+ return false;
+ }
+
+ // Open (and initialize) the window
+
+ bool success = m_bgWindow->open();
+ if (!success)
+ {
+ message("CRadioButtonTest::createGraphics: Failed to open background window\n");
+ delete m_bgWindow;
+ m_bgWindow = (CBgWindow*)0;
+ return false;
+ }
+
+ return true;
+}
+
+// Create a CRadioButton instance
+
+CRadioButton *CRadioButtonTest::newRadioButton(void)
+{
+ // Get the width of the display
+
+ struct nxgl_size_s windowSize;
+ if (!m_bgWindow->getSize(&windowSize))
+ {
+ message("CRadioButtonTest::newRadioButton: Failed to get window size\n");
+ return (CRadioButton *)NULL;
+ }
+
+ // Create the radio button group, if we have not already done so
+
+ if (!m_radioButtonGroup)
+ {
+ // Start the radio button group in the center of the upper, left
+ // quadrant. The initial size is 0,0 and the default style is used.
+
+ nxgl_coord_t groupX = windowSize.w >> 2;
+ nxgl_coord_t groupY = windowSize.h >> 2;
+
+ m_radioButtonGroup = new CRadioButtonGroup(m_widgetControl, groupX, groupY);
+ if (!m_radioButtonGroup)
+ {
+ message("CRadioButtonTest::newRadioButton: Failed to create the radio button group\n");
+ return (CRadioButton *)NULL;
+ }
+ }
+
+ // Create the new radio button at the botton of the radio button group and
+ // with the size of the ON radio button glyph (they all need to be the same
+ // size!). Note that coordinates are relative to the parent bounding box.
+
+ nxgl_coord_t buttonX = 0;
+ nxgl_coord_t buttonY = m_radioButtonGroup->getHeight();
+
+ return m_radioButtonGroup->newRadioButton(buttonX, buttonY, m_size.w, m_size.h);
+}
+
+// (Re-)draw the buttons.
+
+void CRadioButtonTest::showButtons(void)
+{
+ m_radioButtonGroup->enable(); // Un-necessary, the widget is enabled by default
+ m_radioButtonGroup->enableDrawing();
+ m_radioButtonGroup->redraw();
+}
+
+// Push the radio button
+
+void CRadioButtonTest::pushButton(CRadioButton *button)
+{
+ // Get the button center coordinates
+
+ nxgl_coord_t buttonX = button->getX() + (button->getWidth() >> 1);
+ nxgl_coord_t buttonY = button->getY() + (button->getHeight() >> 1);
+
+ // Then push the button by calling nx_mousein. nx_mousein is meant to be
+ // called by mouse handling software. Here we just inject a left-button click
+ // directly in the center of the radio button.
+
+ // First, get the server handle. Graphics software will never care
+ // about the server handle. Here we need it to get access to the
+ // low-level mouse interface
+
+ NXHANDLE handle = getServer();
+
+ // Then inject the mouse click
+
+ (void)nx_mousein(handle, buttonX, buttonY, NX_MOUSE_LEFTBUTTON);
+
+ // Poll for mouse events
+ //
+ // Widget events are normally handled in a modal loop (by calling goModal()).
+ // However, for this case we know that we just pressed the mouse button
+ // so we don't have to poll. We can just perform a one pass poll then
+ // then check if the mouse event was processed corredly.
+
+ m_widgetControl->pollEvents(m_radioButtonGroup);
+
+ // Then inject the mouse release
+
+ (void)nx_mousein(handle, buttonX, buttonY, 0);
+
+ // And poll for more mouse events
+
+ m_widgetControl->pollEvents(m_radioButtonGroup);
+
+ // And re-draw the buttons (the mouse click event should have automatically
+ // triggered the re-draw)
+ //
+ // showButtons();
+}
+
+// Show the state of the radio button group
+
+void CRadioButtonTest::showButtonState(void)
+{
+ int index = m_radioButtonGroup->getSelectedIndex();
+ if (index < 0)
+ {
+ message("CRadioButtonTest::showButtonState No button is pressed\n");
+ }
+ else
+ {
+ message("CRadioButtonTest::showButtonState button%d is selected\n", index+1);
+ }
+}
diff --git a/NxWidgets/UnitTests/CRadioButton/cradiobuttontest.hxx b/NxWidgets/UnitTests/CRadioButton/cradiobuttontest.hxx
new file mode 100644
index 000000000..563049dcf
--- /dev/null
+++ b/NxWidgets/UnitTests/CRadioButton/cradiobuttontest.hxx
@@ -0,0 +1,162 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CRadioButton/cradiobuttontest.hxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef __UNITTESTS_CRADIOBUTTON_CRADIOBUTTONTEST_HXX
+#define __UNITTESTS_CRADIOBUTTON_CRADIOBUTTONTEST_HXX
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <semaphore.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "nxconfig.hxx"
+#include "cwidgetcontrol.hxx"
+#include "ccallback.hxx"
+#include "cbgwindow.hxx"
+#include "cnxserver.hxx"
+#include "cradiobutton.hxx"
+#include "cradiobuttongroup.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+// Configuration ////////////////////////////////////////////////////////////
+
+#ifndef CONFIG_HAVE_CXX
+# error "CONFIG_HAVE_CXX must be defined"
+#endif
+
+#ifndef CONFIG_CRADIOBUTTONTEST_BGCOLOR
+# define CONFIG_CRADIOBUTTONTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR
+#endif
+
+// What is the entry point called?
+
+#ifdef CONFIG_NSH_BUILTIN_APPS
+# define MAIN_NAME cradiobutton_main
+# define MAIN_STRING "cradiobutton_main: "
+#else
+# define MAIN_NAME user_start
+# define MAIN_STRING "user_start: "
+#endif
+
+// If debug is enabled, use the debug function, lib_rawprintf() instead
+// of printf() so that the output is synchronized.
+
+#ifdef CONFIG_DEBUG
+# define message lib_lowprintf
+#else
+# define message printf
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Classes
+/////////////////////////////////////////////////////////////////////////////
+
+using namespace NXWidgets;
+
+class CRadioButtonTest : public CNxServer
+{
+private:
+ CWidgetControl *m_widgetControl; // The controlling widget for the window
+ CBgWindow *m_bgWindow; // Background window instance
+ CRadioButtonGroup *m_radioButtonGroup; // The radio button group
+
+ // These are the dimensions that we will use for creating new radio buttons
+
+ struct nxgl_size_s m_size; // The size of each radio button
+
+public:
+ // Constructor/destructors
+
+ CRadioButtonTest(void);
+ ~CRadioButtonTest(void);
+
+ // Initializer/unitializer. These methods encapsulate the basic steps for
+ // starting and stopping the NX server
+
+ bool connect(void);
+ void disconnect(void);
+
+ // Create a window. This method provides the general operations for
+ // creating a window that you can draw within.
+ //
+ // Those general operations are:
+ // 1) Create a dumb CWigetControl instance
+ // 2) Pass the dumb CWidgetControl instance to the window constructor
+ // that inherits from INxWindow. This will "smarten" the CWidgetControl
+ // instance with some window knowlede
+ // 3) Call the open() method on the window to display the window.
+ // 4) After that, the fully smartened CWidgetControl instance can
+ // be used to generate additional widgets by passing it to the
+ // widget constructor
+
+ bool createWindow(void);
+
+ // (Re-)draw the buttons.
+
+ void showButtons(void);
+
+ // Create a CRadioButton instance. This method will show you how to create
+ // a CRadioButton widget
+
+ CRadioButton *newRadioButton(void);
+
+ // Simulate pushing and releasing of the radio button
+
+ void pushButton(CRadioButton *button);
+
+ // Show the state of the radio button group
+
+ void showButtonState(void);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+#endif // __UNITTESTS_CRADIOBUTTON_CRADIOBUTTONTEST_HXX
diff --git a/NxWidgets/UnitTests/CRadioButton/main.cxx b/NxWidgets/UnitTests/CRadioButton/main.cxx
new file mode 100644
index 000000000..d53cd4a09
--- /dev/null
+++ b/NxWidgets/UnitTests/CRadioButton/main.cxx
@@ -0,0 +1,238 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CRadioButton/main.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <unistd.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "crlepalettebitmap.hxx"
+#include "glyphs.hxx"
+#include "cradiobuttontest.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+static unsigned int g_mmInitial;
+static unsigned int g_mmprevious;
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+// Suppress name-mangling
+
+extern "C" int MAIN_NAME(int argc, char *argv[]);
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: updateMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void updateMemoryUsage(unsigned int previous,
+ FAR const char *msg)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ /* Show the change from the previous time */
+
+ message("\n%s:\n", msg);
+ message(" Before: %8d After: %8d Change: %8d\n\n",
+ previous, mmcurrent.uordblks, mmcurrent.uordblks - previous);
+
+ /* Set up for the next test */
+
+ g_mmprevious = mmcurrent.uordblks;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: initMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void initMemoryUsage(void)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ g_mmInitial = mmcurrent.uordblks;
+ g_mmprevious = mmcurrent.uordblks;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: user_start/nxheaders_main
+/////////////////////////////////////////////////////////////////////////////
+
+int MAIN_NAME(int argc, char *argv[])
+{
+ // Initialize memory monitor logic
+
+ initMemoryUsage();
+
+ // Create an instance of the radio button test
+
+ message(MAIN_STRING "Create CRadioButtonTest instance\n");
+ CRadioButtonTest *test = new CRadioButtonTest();
+ updateMemoryUsage(g_mmprevious, "After creating CRadioButtonTest");
+
+ // Connect the NX server
+
+ message(MAIN_STRING "Connect the CRadioButtonTest instance to the NX server\n");
+ if (!test->connect())
+ {
+ message(MAIN_STRING "Failed to connect the CRadioButtonTest instance to the NX server\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After connecting to the server");
+
+ // Create a window to draw into
+
+ message(MAIN_STRING "Create a Window\n");
+ if (!test->createWindow())
+ {
+ message(MAIN_STRING "Failed to create a window\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating a window");
+
+ // Create three radio buttons
+
+ CRadioButton *button1 = test->newRadioButton();
+ if (!button1)
+ {
+ message(MAIN_STRING "Failed to create radio button 1\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating radio button 1");
+
+ CRadioButton *button2 = test->newRadioButton();
+ if (!button2)
+ {
+ message(MAIN_STRING "Failed to create radio button 2\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating radio button 2");
+
+ CRadioButton *button3 = test->newRadioButton();
+ if (!button3)
+ {
+ message(MAIN_STRING "Failed to create radio button 3\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating radio button 3");
+
+ // Show the initial state of the buttons
+
+ test->showButtons();
+ test->showButtonState();
+ sleep(1);
+
+ // Now push some buttons
+
+ message(MAIN_STRING "Pushing button 1\n");
+ test->pushButton(button1);
+ usleep(500*1000);
+ test->showButtonState();
+ updateMemoryUsage(g_mmprevious, "After pushing button 1");
+ usleep(500*1000);
+
+ message(MAIN_STRING "Pushing button 2\n");
+ test->pushButton(button2);
+ usleep(500*1000);
+ test->showButtonState();
+ updateMemoryUsage(g_mmprevious, "After pushing button 2");
+ usleep(500*1000);
+
+ message(MAIN_STRING "Pushing button 3\n");
+ test->pushButton(button3);
+ usleep(500*1000);
+ test->showButtonState();
+ updateMemoryUsage(g_mmprevious, "After pushing button 3");
+ sleep(2);
+
+ // Clean up and exit
+
+ message(MAIN_STRING "Clean-up and exit\n");
+ delete test;
+ updateMemoryUsage(g_mmprevious, "After deleting the test");
+ updateMemoryUsage(g_mmInitial, "Final memory usage");
+ return 0;
+}
+
diff --git a/NxWidgets/UnitTests/CScrollbarHorizontal/Makefile b/NxWidgets/UnitTests/CScrollbarHorizontal/Makefile
new file mode 100644
index 000000000..6be8f7cd6
--- /dev/null
+++ b/NxWidgets/UnitTests/CScrollbarHorizontal/Makefile
@@ -0,0 +1,172 @@
+#################################################################################
+# NxWidgets/UnitTests/CScrollbarHorizontal/Makefile
+#
+# Copyright (C) 2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+# me be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#################################################################################
+
+TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'}
+
+-include $(TOPDIR)/.config
+-include $(TOPDIR)/Make.defs
+include $(APPDIR)/Make.defs
+
+# Add the path to the NXWidget include directory to the CFLAGS
+
+NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets"
+NXWIDGETS_INC="$(NXWIDGETS_DIR)/include"
+NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)"
+
+INCDIR=$(TOPDIR)/tools/incdir.sh
+ifeq ($(WINTOOL),y)
+ CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"}
+else
+ CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"}
+endif
+
+# Get the path to the archiver tool
+
+TESTTOOL_DIR="$(TESTDIR)/../tools"
+ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh
+
+# Hello, World! C++ Example
+
+ASRCS =
+CSRCS =
+CXXSRCS = main.cxx cscrollbarhorizontaltest.cxx
+
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+COBJS = $(CSRCS:.c=$(OBJEXT))
+CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS)
+OBJS = $(AOBJS) $(COBJS) $(CXXOBJS)
+
+POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)"
+ifeq ($(WINTOOL),y)
+ BIN = "${shell cygpath -w $(POSIX_BIN)}"
+else
+ BIN = $(POSIX_BIN)
+endif
+
+ROOTDEPPATH = --dep-path .
+
+# helloxx built-in application info
+
+APPNAME = cscrollbarhorizontal
+PRIORITY = SCHED_PRIORITY_DEFAULT
+STACKSIZE = 2048
+
+# Common build
+
+VPATH =
+
+all: .built
+.PHONY: clean depend context disclean chkcxx chklib
+
+# Object file creation targets
+
+$(AOBJS): %$(OBJEXT): %.S
+ $(call ASSEMBLE, $<, $@)
+
+$(COBJS): %$(OBJEXT): %.c
+ $(call COMPILE, $<, $@)
+
+$(CXXOBJS): %$(OBJEXT): %.cxx
+ $(call COMPILEXX, $<, $@)
+
+# Verify that the NuttX configuration is setup to support C++
+
+chkcxx:
+ifneq ($(CONFIG_HAVE_CXX),y)
+ @echo ""
+ @echo "In order to use this example, you toolchain must support must"
+ @echo ""
+ @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support"
+ @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file"
+ @echo " of the configuration that you are using."
+ @echo ""
+ @exit 1
+endif
+
+# Verify that the NXWidget library has been built
+
+chklib:
+ @( \
+ if [ ! -e "$(NXWIDGETS_LIB)" ]; then \
+ echo "$(NXWIDGETS_LIB) does not exist."; \
+ echo "Please go to $(NXWIDGETS_DIR)"; \
+ echo "and rebuild the library"; \
+ exit 1; \
+ fi; \
+ )
+
+# Library creation targets
+
+$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work.
+
+.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB)
+ @( for obj in $(OBJS) ; do \
+ $(call ARCHIVE, $(BIN), $${obj}); \
+ done ; )
+ifeq ($(WINTOOL),y)
+ @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+else
+ @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+endif
+ @touch .built
+
+# Standard housekeeping targets
+
+.context:
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+ $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
+endif
+ @touch $@
+
+context: .context
+
+.depend: Makefile $(SRCS)
+ @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep
+ @touch $@
+
+depend: .depend
+
+clean:
+ @rm -f *.o *~ .*.swp .built
+ $(call CLEAN)
+
+distclean: clean
+ @rm -f Make.dep .depend
+
+-include Make.dep
diff --git a/NxWidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.cxx b/NxWidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.cxx
new file mode 100644
index 000000000..06673f080
--- /dev/null
+++ b/NxWidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.cxx
@@ -0,0 +1,225 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cerrno>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+#include <nuttx/nx/nxfonts.h>
+
+#include "nxconfig.hxx"
+#include "cbgwindow.hxx"
+#include "cscrollbarhorizontaltest.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// CScrollbarHorizontalTest Method Implementations
+/////////////////////////////////////////////////////////////////////////////
+
+// CScrollbarHorizontalTest Constructor
+
+CScrollbarHorizontalTest::CScrollbarHorizontalTest()
+{
+ // Initialize state data
+
+ m_widgetControl = (CWidgetControl *)NULL;
+ m_bgWindow = (CBgWindow *)NULL;
+}
+
+// CScrollbarHorizontalTest Descriptor
+
+CScrollbarHorizontalTest::~CScrollbarHorizontalTest(void)
+{
+ disconnect();
+}
+
+// Connect to the NX server
+
+bool CScrollbarHorizontalTest::connect(void)
+{
+ // Connect to the server
+
+ bool nxConnected = CNxServer::connect();
+ if (nxConnected)
+ {
+ // Set the background color
+
+ if (!setBackgroundColor(CONFIG_CSCROLLBARHORIZONTALTEST_BGCOLOR))
+ {
+ message("CScrollbarHorizontalTest::connect: setBackgroundColor failed\n");
+ }
+ }
+
+ return nxConnected;
+}
+
+// Disconnect from the NX server
+
+void CScrollbarHorizontalTest::disconnect(void)
+{
+ // Close the window
+
+ if (m_bgWindow)
+ {
+ delete m_bgWindow;
+ m_bgWindow = (CBgWindow *)NULL;
+ }
+
+ // Free the widget control instance
+
+ if (m_widgetControl)
+ {
+ delete m_widgetControl;
+ m_widgetControl = (CWidgetControl *)NULL;
+ }
+
+ // And disconnect from the server
+
+ CNxServer::disconnect();
+}
+
+// Create the background window instance. This function illustrates
+// the basic steps to instantiate any window:
+//
+// 1) Create a dumb CWigetControl instance
+// 2) Pass the dumb CWidgetControl instance to the window constructor
+// that inherits from INxWindow. This will "smarten" the CWidgetControl
+// instance with some window knowlede
+// 3) Call the open() method on the window to display the window.
+// 4) After that, the fully smartened CWidgetControl instance can
+// be used to generate additional widgets by passing it to the
+// widget constructor
+
+bool CScrollbarHorizontalTest::createWindow(void)
+{
+ // Initialize the widget control using the default style
+
+ m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL);
+
+ // Get an (uninitialized) instance of the background window as a class
+ // that derives from INxWindow.
+
+ m_bgWindow = getBgWindow(m_widgetControl);
+ if (!m_bgWindow)
+ {
+ message("CScrollbarHorizontalTest::createWindow: Failed to create CBgWindow instance\n");
+ disconnect();
+ return false;
+ }
+
+ // Open (and initialize) the window
+
+ bool success = m_bgWindow->open();
+ if (!success)
+ {
+ message("CScrollbarHorizontalTest::createWindow: Failed to open background window\n");
+ disconnect();
+ return false;
+ }
+
+ return true;
+}
+
+// Create a scrollbar in the center of the window
+
+CScrollbarHorizontal *CScrollbarHorizontalTest::createScrollbar(void)
+{
+ // Get the size of the display
+
+ struct nxgl_size_s windowSize;
+ if (!m_bgWindow->getSize(&windowSize))
+ {
+ printf("CScrollbarHorizontalTest::createScrollbar: Failed to get window size\n");
+ disconnect();
+ return false;
+ }
+
+ // Put the scrollbar in the center of the display
+
+ nxgl_coord_t scrollbarWidth = windowSize.w >> 1;
+ nxgl_coord_t scrollbarX = windowSize.w >> 2;
+
+ nxgl_coord_t scrollbarHeight = 10;
+ nxgl_coord_t scrollbarY = (windowSize.h - scrollbarHeight) >> 1;
+
+ // Create the scrollbar
+
+ CScrollbarHorizontal *scrollbar =
+ new CScrollbarHorizontal(m_widgetControl,
+ scrollbarX, scrollbarY,
+ scrollbarWidth, scrollbarHeight);
+ if (!scrollbar)
+ {
+ printf("CScrollbarHorizontalTest::createScrollbar: Failed to create CScrollbarHorizontal\n");
+ disconnect();
+ }
+ return scrollbar;
+}
+
+// (Re-)draw the scrollbar.
+
+void CScrollbarHorizontalTest::showScrollbar(CScrollbarHorizontal *scrollbar)
+{
+ scrollbar->enable(); // Un-necessary, the widget is enabled by default
+ scrollbar->enableDrawing();
+ scrollbar->redraw();
+}
diff --git a/NxWidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.hxx b/NxWidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.hxx
new file mode 100644
index 000000000..feae319d0
--- /dev/null
+++ b/NxWidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.hxx
@@ -0,0 +1,147 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.hxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef __UNITTESTS_CSCROLLBARHORIZONTAL_CSCROLLBARHORIZONTALTEST_HXX
+#define __UNITTESTS_CSCROLLBARHORIZONTAL_CSCROLLBARHORIZONTALTEST_HXX
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <semaphore.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "nxconfig.hxx"
+#include "cwidgetcontrol.hxx"
+#include "ccallback.hxx"
+#include "cbgwindow.hxx"
+#include "cnxserver.hxx"
+#include "cscrollbarhorizontal.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+// Configuration ////////////////////////////////////////////////////////////
+
+#ifndef CONFIG_HAVE_CXX
+# error "CONFIG_HAVE_CXX must be defined"
+#endif
+
+#ifndef CONFIG_CSCROLLBARHORIZONTALTEST_BGCOLOR
+# define CONFIG_CSCROLLBARHORIZONTALTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR
+#endif
+
+// What is the entry point called?
+
+#ifdef CONFIG_NSH_BUILTIN_APPS
+# define MAIN_NAME cscrollbarhorizontal_main
+# define MAIN_STRING "cscrollbarhorizontal_main: "
+#else
+# define MAIN_NAME user_start
+# define MAIN_STRING "user_start: "
+#endif
+
+// If debug is enabled, use the debug function, lib_rawprintf() instead
+// of printf() so that the output is synchronized.
+
+#ifdef CONFIG_DEBUG
+# define message lib_lowprintf
+#else
+# define message printf
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Classes
+/////////////////////////////////////////////////////////////////////////////
+
+using namespace NXWidgets;
+
+class CScrollbarHorizontalTest : public CNxServer
+{
+private:
+ CWidgetControl *m_widgetControl; // The controlling widget for the window
+ CBgWindow *m_bgWindow; // Background window instance
+
+public:
+ // Constructor/destructors
+
+ CScrollbarHorizontalTest(void);
+ ~CScrollbarHorizontalTest(void);
+
+ // Initializer/unitializer. These methods encapsulate the basic steps for
+ // starting and stopping the NX server
+
+ bool connect(void);
+ void disconnect(void);
+
+ // Create a window. This method provides the general operations for
+ // creating a window that you can draw within.
+ //
+ // Those general operations are:
+ // 1) Create a dumb CWigetControl instance
+ // 2) Pass the dumb CWidgetControl instance to the window constructor
+ // that inherits from INxWindow. This will "smarten" the CWidgetControl
+ // instance with some window knowlede
+ // 3) Call the open() method on the window to display the window.
+ // 4) After that, the fully smartened CWidgetControl instance can
+ // be used to generate additional widgets by passing it to the
+ // widget constructor
+
+ bool createWindow(void);
+
+ // Create a scrollbar in the center of the window
+
+ CScrollbarHorizontal *createScrollbar(void);
+
+ // (Re-)draw the scrollbar.
+
+ void showScrollbar(CScrollbarHorizontal *scrollbar);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+#endif // __UNITTESTS_CSCROLLBARHORIZONTAL_CSCROLLBARHORIZONTALTEST_HXX
diff --git a/NxWidgets/UnitTests/CScrollbarHorizontal/main.cxx b/NxWidgets/UnitTests/CScrollbarHorizontal/main.cxx
new file mode 100644
index 000000000..a6a08cdbd
--- /dev/null
+++ b/NxWidgets/UnitTests/CScrollbarHorizontal/main.cxx
@@ -0,0 +1,231 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CScrollbarHorizontal/main.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <unistd.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "cscrollbarhorizontaltest.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+#define MAX_SCROLLBAR 50
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+static unsigned int g_mmInitial;
+static unsigned int g_mmprevious;
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+// Suppress name-mangling
+
+extern "C" int MAIN_NAME(int argc, char *argv[]);
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: updateMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void updateMemoryUsage(unsigned int previous,
+ FAR const char *msg)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ /* Show the change from the previous time */
+
+ message("\n%s:\n", msg);
+ message(" Before: %8d After: %8d Change: %8d\n\n",
+ previous, mmcurrent.uordblks, mmcurrent.uordblks - previous);
+
+ /* Set up for the next test */
+
+ g_mmprevious = mmcurrent.uordblks;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: initMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void initMemoryUsage(void)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ g_mmInitial = mmcurrent.uordblks;
+ g_mmprevious = mmcurrent.uordblks;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: user_start/nxheaders_main
+/////////////////////////////////////////////////////////////////////////////
+
+int MAIN_NAME(int argc, char *argv[])
+{
+ // Initialize memory monitor logic
+
+ initMemoryUsage();
+
+ // Create an instance of the checkbox test
+
+ message(MAIN_STRING "Create CScrollbarHorizontalTest instance\n");
+ CScrollbarHorizontalTest *test = new CScrollbarHorizontalTest();
+ updateMemoryUsage(g_mmprevious, "After creating CScrollbarHorizontalTest");
+
+ // Connect the NX server
+
+ message(MAIN_STRING "Connect the CScrollbarHorizontalTest instance to the NX server\n");
+ if (!test->connect())
+ {
+ message(MAIN_STRING "Failed to connect the CScrollbarHorizontalTest instance to the NX server\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After connecting to the server");
+
+ // Create a window to draw into
+
+ message(MAIN_STRING "Create a Window\n");
+ if (!test->createWindow())
+ {
+ message(MAIN_STRING "Failed to create a window\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating a window");
+
+ // Create a scrollbar
+
+ message(MAIN_STRING "Create a Scrollbar\n");
+ CScrollbarHorizontal *scrollbar = test->createScrollbar();
+ if (!scrollbar)
+ {
+ message(MAIN_STRING "Failed to create a scrollbar\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating a scrollbar");
+
+ // Set the scrollbar minimum and maximum values
+
+ scrollbar->setMinimumValue(0);
+ scrollbar->setMaximumValue(MAX_SCROLLBAR);
+ scrollbar->setValue(0);
+ message(MAIN_STRING "Scrollbar range %d->%d Initial value %d\n",
+ scrollbar->getMinimumValue(), scrollbar->getMaximumValue(),
+ scrollbar->getValue());
+
+ // Show the initial state of the checkbox
+
+ test->showScrollbar(scrollbar);
+ sleep(1);
+
+ // Now move the scrollbar up
+
+ for (int i = 0; i <= MAX_SCROLLBAR; i++)
+ {
+ scrollbar->setValue(i);
+ test->showScrollbar(scrollbar);
+ message(MAIN_STRING "%d. New value %d\n", i, scrollbar->getValue());
+ usleep(1000); // The simulation needs this to let the X11 event loop run
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After moving the scrollbar up");
+
+ // And move the scrollbar down
+
+ for (int i = MAX_SCROLLBAR; i >= 0; i--)
+ {
+ scrollbar->setValue(i);
+ test->showScrollbar(scrollbar);
+ message(MAIN_STRING "%d. New value %d\n", i, scrollbar->getValue());
+ usleep(1000); // The simulation needs this to let the X11 event loop run
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After moving the scrollbar down");
+ sleep(1);
+
+ // Clean up and exit
+
+ message(MAIN_STRING "Clean-up and exit\n");
+ delete scrollbar;
+ updateMemoryUsage(g_mmprevious, "After deleting the scrollbar");
+ delete test;
+ updateMemoryUsage(g_mmprevious, "After deleting the test");
+ updateMemoryUsage(g_mmInitial, "Final memory usage");
+ return 0;
+}
+
diff --git a/NxWidgets/UnitTests/CScrollbarVertical/Makefile b/NxWidgets/UnitTests/CScrollbarVertical/Makefile
new file mode 100644
index 000000000..a2c404aad
--- /dev/null
+++ b/NxWidgets/UnitTests/CScrollbarVertical/Makefile
@@ -0,0 +1,172 @@
+#################################################################################
+# NxWidgets/UnitTests/CScrollbarVertical/Makefile
+#
+# Copyright (C) 2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+# me be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#################################################################################
+
+TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'}
+
+-include $(TOPDIR)/.config
+-include $(TOPDIR)/Make.defs
+include $(APPDIR)/Make.defs
+
+# Add the path to the NXWidget include directory to the CFLAGS
+
+NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets"
+NXWIDGETS_INC="$(NXWIDGETS_DIR)/include"
+NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)"
+
+INCDIR=$(TOPDIR)/tools/incdir.sh
+ifeq ($(WINTOOL),y)
+ CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"}
+else
+ CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"}
+endif
+
+# Get the path to the archiver tool
+
+TESTTOOL_DIR="$(TESTDIR)/../tools"
+ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh
+
+# Hello, World! C++ Example
+
+ASRCS =
+CSRCS =
+CXXSRCS = main.cxx cscrollbarverticaltest.cxx
+
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+COBJS = $(CSRCS:.c=$(OBJEXT))
+CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS)
+OBJS = $(AOBJS) $(COBJS) $(CXXOBJS)
+
+POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)"
+ifeq ($(WINTOOL),y)
+ BIN = "${shell cygpath -w $(POSIX_BIN)}"
+else
+ BIN = $(POSIX_BIN)
+endif
+
+ROOTDEPPATH = --dep-path .
+
+# helloxx built-in application info
+
+APPNAME = cscrollbarvertical
+PRIORITY = SCHED_PRIORITY_DEFAULT
+STACKSIZE = 2048
+
+# Common build
+
+VPATH =
+
+all: .built
+.PHONY: clean depend context disclean chkcxx chklib
+
+# Object file creation targets
+
+$(AOBJS): %$(OBJEXT): %.S
+ $(call ASSEMBLE, $<, $@)
+
+$(COBJS): %$(OBJEXT): %.c
+ $(call COMPILE, $<, $@)
+
+$(CXXOBJS): %$(OBJEXT): %.cxx
+ $(call COMPILEXX, $<, $@)
+
+# Verify that the NuttX configuration is setup to support C++
+
+chkcxx:
+ifneq ($(CONFIG_HAVE_CXX),y)
+ @echo ""
+ @echo "In order to use this example, you toolchain must support must"
+ @echo ""
+ @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support"
+ @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file"
+ @echo " of the configuration that you are using."
+ @echo ""
+ @exit 1
+endif
+
+# Verify that the NXWidget library has been built
+
+chklib:
+ @( \
+ if [ ! -e "$(NXWIDGETS_LIB)" ]; then \
+ echo "$(NXWIDGETS_LIB) does not exist."; \
+ echo "Please go to $(NXWIDGETS_DIR)"; \
+ echo "and rebuild the library"; \
+ exit 1; \
+ fi; \
+ )
+
+# Library creation targets
+
+$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work.
+
+.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB)
+ @( for obj in $(OBJS) ; do \
+ $(call ARCHIVE, $(BIN), $${obj}); \
+ done ; )
+ifeq ($(WINTOOL),y)
+ @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+else
+ @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+endif
+ @touch .built
+
+# Standard housekeeping targets
+
+.context:
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+ $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
+endif
+ @touch $@
+
+context: .context
+
+.depend: Makefile $(SRCS)
+ @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep
+ @touch $@
+
+depend: .depend
+
+clean:
+ @rm -f *.o *~ .*.swp .built
+ $(call CLEAN)
+
+distclean: clean
+ @rm -f Make.dep .depend
+
+-include Make.dep
diff --git a/NxWidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.cxx b/NxWidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.cxx
new file mode 100644
index 000000000..df317adcd
--- /dev/null
+++ b/NxWidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.cxx
@@ -0,0 +1,225 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cerrno>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+#include <nuttx/nx/nxfonts.h>
+
+#include "nxconfig.hxx"
+#include "cbgwindow.hxx"
+#include "cscrollbarverticaltest.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// CScrollbarVerticalTest Method Implementations
+/////////////////////////////////////////////////////////////////////////////
+
+// CScrollbarVerticalTest Constructor
+
+CScrollbarVerticalTest::CScrollbarVerticalTest()
+{
+ // Initialize state data
+
+ m_widgetControl = (CWidgetControl *)NULL;
+ m_bgWindow = (CBgWindow *)NULL;
+}
+
+// CScrollbarVerticalTest Descriptor
+
+CScrollbarVerticalTest::~CScrollbarVerticalTest(void)
+{
+ disconnect();
+}
+
+// Connect to the NX server
+
+bool CScrollbarVerticalTest::connect(void)
+{
+ // Connect to the server
+
+ bool nxConnected = CNxServer::connect();
+ if (nxConnected)
+ {
+ // Set the background color
+
+ if (!setBackgroundColor(CONFIG_CSCROLLBARVERTICALTEST_BGCOLOR))
+ {
+ message("CScrollbarVerticalTest::connect: setBackgroundColor failed\n");
+ }
+ }
+
+ return nxConnected;
+}
+
+// Disconnect from the NX server
+
+void CScrollbarVerticalTest::disconnect(void)
+{
+ // Close the window
+
+ if (m_bgWindow)
+ {
+ delete m_bgWindow;
+ m_bgWindow = (CBgWindow *)NULL;
+ }
+
+ // Free the widget control instance
+
+ if (m_widgetControl)
+ {
+ delete m_widgetControl;
+ m_widgetControl = (CWidgetControl *)NULL;
+ }
+
+ // And disconnect from the server
+
+ CNxServer::disconnect();
+}
+
+// Create the background window instance. This function illustrates
+// the basic steps to instantiate any window:
+//
+// 1) Create a dumb CWigetControl instance
+// 2) Pass the dumb CWidgetControl instance to the window constructor
+// that inherits from INxWindow. This will "smarten" the CWidgetControl
+// instance with some window knowlede
+// 3) Call the open() method on the window to display the window.
+// 4) After that, the fully smartened CWidgetControl instance can
+// be used to generate additional widgets by passing it to the
+// widget constructor
+
+bool CScrollbarVerticalTest::createWindow(void)
+{
+ // Initialize the widget control using the default style
+
+ m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL);
+
+ // Get an (uninitialized) instance of the background window as a class
+ // that derives from INxWindow.
+
+ m_bgWindow = getBgWindow(m_widgetControl);
+ if (!m_bgWindow)
+ {
+ message("CScrollbarVerticalTest::createWindow: Failed to create CBgWindow instance\n");
+ disconnect();
+ return false;
+ }
+
+ // Open (and initialize) the window
+
+ bool success = m_bgWindow->open();
+ if (!success)
+ {
+ message("CScrollbarVerticalTest::createWindow: Failed to open background window\n");
+ disconnect();
+ return false;
+ }
+
+ return true;
+}
+
+// Create a scrollbar in the center of the window
+
+CScrollbarVertical *CScrollbarVerticalTest::createScrollbar(void)
+{
+ // Get the size of the display
+
+ struct nxgl_size_s windowSize;
+ if (!m_bgWindow->getSize(&windowSize))
+ {
+ printf("CScrollbarVerticalTest::createScrollbar: Failed to get window size\n");
+ disconnect();
+ return false;
+ }
+
+ // Put the scrollbar in the center of the display
+
+ nxgl_coord_t scrollbarWidth = 10;
+ nxgl_coord_t scrollbarX = (windowSize.w - scrollbarWidth) >> 1;
+
+ nxgl_coord_t scrollbarHeight = windowSize.h >> 1;
+ nxgl_coord_t scrollbarY = windowSize.h >> 2;
+
+ // Create the scrollbar
+
+ CScrollbarVertical *scrollbar =
+ new CScrollbarVertical(m_widgetControl,
+ scrollbarX, scrollbarY,
+ scrollbarWidth, scrollbarHeight);
+ if (!scrollbar)
+ {
+ printf("CScrollbarVerticalTest::createScrollbar: Failed to create CScrollbarVertical\n");
+ disconnect();
+ }
+ return scrollbar;
+}
+
+// (Re-)draw the scrollbar.
+
+void CScrollbarVerticalTest::showScrollbar(CScrollbarVertical *scrollbar)
+{
+ scrollbar->enable(); // Un-necessary, the widget is enabled by default
+ scrollbar->enableDrawing();
+ scrollbar->redraw();
+}
diff --git a/NxWidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.hxx b/NxWidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.hxx
new file mode 100644
index 000000000..874a851fd
--- /dev/null
+++ b/NxWidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.hxx
@@ -0,0 +1,147 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.hxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef __UNITTESTS_CSCROLLBARVERTICAL_CSCROLLBARVERTICALTEST_HXX
+#define __UNITTESTS_CSCROLLBARVERTICAL_CSCROLLBARVERTICALTEST_HXX
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <semaphore.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "nxconfig.hxx"
+#include "cwidgetcontrol.hxx"
+#include "ccallback.hxx"
+#include "cbgwindow.hxx"
+#include "cnxserver.hxx"
+#include "cscrollbarvertical.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+// Configuration ////////////////////////////////////////////////////////////
+
+#ifndef CONFIG_HAVE_CXX
+# error "CONFIG_HAVE_CXX must be defined"
+#endif
+
+#ifndef CONFIG_CSCROLLBARVERTICALTEST_BGCOLOR
+# define CONFIG_CSCROLLBARVERTICALTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR
+#endif
+
+// What is the entry point called?
+
+#ifdef CONFIG_NSH_BUILTIN_APPS
+# define MAIN_NAME cscrollbarvertical_main
+# define MAIN_STRING "cscrollbarvertical_main: "
+#else
+# define MAIN_NAME user_start
+# define MAIN_STRING "user_start: "
+#endif
+
+// If debug is enabled, use the debug function, lib_rawprintf() instead
+// of printf() so that the output is synchronized.
+
+#ifdef CONFIG_DEBUG
+# define message lib_lowprintf
+#else
+# define message printf
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Classes
+/////////////////////////////////////////////////////////////////////////////
+
+using namespace NXWidgets;
+
+class CScrollbarVerticalTest : public CNxServer
+{
+private:
+ CWidgetControl *m_widgetControl; // The controlling widget for the window
+ CBgWindow *m_bgWindow; // Background window instance
+
+public:
+ // Constructor/destructors
+
+ CScrollbarVerticalTest(void);
+ ~CScrollbarVerticalTest(void);
+
+ // Initializer/unitializer. These methods encapsulate the basic steps for
+ // starting and stopping the NX server
+
+ bool connect(void);
+ void disconnect(void);
+
+ // Create a window. This method provides the general operations for
+ // creating a window that you can draw within.
+ //
+ // Those general operations are:
+ // 1) Create a dumb CWigetControl instance
+ // 2) Pass the dumb CWidgetControl instance to the window constructor
+ // that inherits from INxWindow. This will "smarten" the CWidgetControl
+ // instance with some window knowlede
+ // 3) Call the open() method on the window to display the window.
+ // 4) After that, the fully smartened CWidgetControl instance can
+ // be used to generate additional widgets by passing it to the
+ // widget constructor
+
+ bool createWindow(void);
+
+ // Create a scrollbar in the center of the window
+
+ CScrollbarVertical *createScrollbar(void);
+
+ // (Re-)draw the scrollbar.
+
+ void showScrollbar(CScrollbarVertical *scrollbar);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+#endif // __UNITTESTS_CSCROLLBARVERTICAL_CSCROLLBARVERTICALTEST_HXX
diff --git a/NxWidgets/UnitTests/CScrollbarVertical/main.cxx b/NxWidgets/UnitTests/CScrollbarVertical/main.cxx
new file mode 100644
index 000000000..16bd9eea6
--- /dev/null
+++ b/NxWidgets/UnitTests/CScrollbarVertical/main.cxx
@@ -0,0 +1,231 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CScrollbarVertical/main.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <unistd.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "cscrollbarverticaltest.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+#define MAX_SCROLLBAR 20
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+static unsigned int g_mmInitial;
+static unsigned int g_mmprevious;
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+// Suppress name-mangling
+
+extern "C" int MAIN_NAME(int argc, char *argv[]);
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: updateMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void updateMemoryUsage(unsigned int previous,
+ FAR const char *msg)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ /* Show the change from the previous time */
+
+ message("\n%s:\n", msg);
+ message(" Before: %8d After: %8d Change: %8d\n\n",
+ previous, mmcurrent.uordblks, mmcurrent.uordblks - previous);
+
+ /* Set up for the next test */
+
+ g_mmprevious = mmcurrent.uordblks;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: initMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void initMemoryUsage(void)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ g_mmInitial = mmcurrent.uordblks;
+ g_mmprevious = mmcurrent.uordblks;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: user_start/nxheaders_main
+/////////////////////////////////////////////////////////////////////////////
+
+int MAIN_NAME(int argc, char *argv[])
+{
+ // Initialize memory monitor logic
+
+ initMemoryUsage();
+
+ // Create an instance of the checkbox test
+
+ message(MAIN_STRING "Create CScrollbarVerticalTest instance\n");
+ CScrollbarVerticalTest *test = new CScrollbarVerticalTest();
+ updateMemoryUsage(g_mmprevious, "After creating CScrollbarVerticalTest");
+
+ // Connect the NX server
+
+ message(MAIN_STRING "Connect the CScrollbarVerticalTest instance to the NX server\n");
+ if (!test->connect())
+ {
+ message(MAIN_STRING "Failed to connect the CScrollbarVerticalTest instance to the NX server\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After connecting to the server");
+
+ // Create a window to draw into
+
+ message(MAIN_STRING "Create a Window\n");
+ if (!test->createWindow())
+ {
+ message(MAIN_STRING "Failed to create a window\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating a window");
+
+ // Create a scrollbar
+
+ message(MAIN_STRING "Create a Scrollbar\n");
+ CScrollbarVertical *scrollbar = test->createScrollbar();
+ if (!scrollbar)
+ {
+ message(MAIN_STRING "Failed to create a scrollbar\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating a scrollbar");
+
+ // Set the scrollbar minimum and maximum values
+
+ scrollbar->setMinimumValue(0);
+ scrollbar->setMaximumValue(MAX_SCROLLBAR);
+ scrollbar->setValue(0);
+ message(MAIN_STRING "Scrollbar range %d->%d Initial value %d\n",
+ scrollbar->getMinimumValue(), scrollbar->getMaximumValue(),
+ scrollbar->getValue());
+
+ // Show the initial state of the checkbox
+
+ test->showScrollbar(scrollbar);
+ sleep(1);
+
+ // Now move the scrollbar up
+
+ for (int i = 0; i <= MAX_SCROLLBAR; i++)
+ {
+ scrollbar->setValue(i);
+ test->showScrollbar(scrollbar);
+ message(MAIN_STRING "%d. New value %d\n", i, scrollbar->getValue());
+ usleep(1000); // The simulation needs this to let the X11 event loop run
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After moving the scrollbar up");
+
+ // And move the scrollbar down
+
+ for (int i = MAX_SCROLLBAR; i >= 0; i--)
+ {
+ scrollbar->setValue(i);
+ test->showScrollbar(scrollbar);
+ message(MAIN_STRING "%d. New value %d\n", i, scrollbar->getValue());
+ usleep(5000); // The simulation needs this to let the X11 event loop run
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After moving the scrollbar down");
+ sleep(1);
+
+ // Clean up and exit
+
+ message(MAIN_STRING "Clean-up and exit\n");
+ delete scrollbar;
+ updateMemoryUsage(g_mmprevious, "After deleting the scrollbar");
+ delete test;
+ updateMemoryUsage(g_mmprevious, "After deleting the test");
+ updateMemoryUsage(g_mmInitial, "Final memory usage");
+ return 0;
+}
+
diff --git a/NxWidgets/UnitTests/CSliderHorizonal/Makefile b/NxWidgets/UnitTests/CSliderHorizonal/Makefile
new file mode 100644
index 000000000..b496bdda7
--- /dev/null
+++ b/NxWidgets/UnitTests/CSliderHorizonal/Makefile
@@ -0,0 +1,172 @@
+#################################################################################
+# NxWidgets/UnitTests/CSliderHorizontal/Makefile
+#
+# Copyright (C) 2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+# me be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#################################################################################
+
+TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'}
+
+-include $(TOPDIR)/.config
+-include $(TOPDIR)/Make.defs
+include $(APPDIR)/Make.defs
+
+# Add the path to the NXWidget include directory to the CFLAGS
+
+NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets"
+NXWIDGETS_INC="$(NXWIDGETS_DIR)/include"
+NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)"
+
+INCDIR=$(TOPDIR)/tools/incdir.sh
+ifeq ($(WINTOOL),y)
+ CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"}
+else
+ CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"}
+endif
+
+# Get the path to the archiver tool
+
+TESTTOOL_DIR="$(TESTDIR)/../tools"
+ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh
+
+# Hello, World! C++ Example
+
+ASRCS =
+CSRCS =
+CXXSRCS = main.cxx csliderhorizontaltest.cxx
+
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+COBJS = $(CSRCS:.c=$(OBJEXT))
+CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS)
+OBJS = $(AOBJS) $(COBJS) $(CXXOBJS)
+
+POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)"
+ifeq ($(WINTOOL),y)
+ BIN = "${shell cygpath -w $(POSIX_BIN)}"
+else
+ BIN = $(POSIX_BIN)
+endif
+
+ROOTDEPPATH = --dep-path .
+
+# helloxx built-in application info
+
+APPNAME = csliderhorizontal
+PRIORITY = SCHED_PRIORITY_DEFAULT
+STACKSIZE = 2048
+
+# Common build
+
+VPATH =
+
+all: .built
+.PHONY: clean depend context disclean chkcxx chklib
+
+# Object file creation targets
+
+$(AOBJS): %$(OBJEXT): %.S
+ $(call ASSEMBLE, $<, $@)
+
+$(COBJS): %$(OBJEXT): %.c
+ $(call COMPILE, $<, $@)
+
+$(CXXOBJS): %$(OBJEXT): %.cxx
+ $(call COMPILEXX, $<, $@)
+
+# Verify that the NuttX configuration is setup to support C++
+
+chkcxx:
+ifneq ($(CONFIG_HAVE_CXX),y)
+ @echo ""
+ @echo "In order to use this example, you toolchain must support must"
+ @echo ""
+ @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support"
+ @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file"
+ @echo " of the configuration that you are using."
+ @echo ""
+ @exit 1
+endif
+
+# Verify that the NXWidget library has been built
+
+chklib:
+ @( \
+ if [ ! -e "$(NXWIDGETS_LIB)" ]; then \
+ echo "$(NXWIDGETS_LIB) does not exist."; \
+ echo "Please go to $(NXWIDGETS_DIR)"; \
+ echo "and rebuild the library"; \
+ exit 1; \
+ fi; \
+ )
+
+# Library creation targets
+
+$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work.
+
+.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB)
+ @( for obj in $(OBJS) ; do \
+ $(call ARCHIVE, $(BIN), $${obj}); \
+ done ; )
+ifeq ($(WINTOOL),y)
+ @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+else
+ @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+endif
+ @touch .built
+
+# Standard housekeeping targets
+
+.context:
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+ $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
+endif
+ @touch $@
+
+context: .context
+
+.depend: Makefile $(SRCS)
+ @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep
+ @touch $@
+
+depend: .depend
+
+clean:
+ @rm -f *.o *~ .*.swp .built
+ $(call CLEAN)
+
+distclean: clean
+ @rm -f Make.dep .depend
+
+-include Make.dep
diff --git a/NxWidgets/UnitTests/CSliderHorizonal/csliderhorizontaltest.cxx b/NxWidgets/UnitTests/CSliderHorizonal/csliderhorizontaltest.cxx
new file mode 100644
index 000000000..1687448db
--- /dev/null
+++ b/NxWidgets/UnitTests/CSliderHorizonal/csliderhorizontaltest.cxx
@@ -0,0 +1,224 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CSliderHorizontal/csliderhorizontaltest.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cerrno>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+#include <nuttx/nx/nxfonts.h>
+
+#include "nxconfig.hxx"
+#include "cbgwindow.hxx"
+#include "csliderhorizontaltest.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// CSliderHorizontalTest Method Implementations
+/////////////////////////////////////////////////////////////////////////////
+
+// CSliderHorizontalTest Constructor
+
+CSliderHorizontalTest::CSliderHorizontalTest()
+{
+ // Initialize state data
+
+ m_widgetControl = (CWidgetControl *)NULL;
+ m_bgWindow = (CBgWindow *)NULL;
+}
+
+// CSliderHorizontalTest Descriptor
+
+CSliderHorizontalTest::~CSliderHorizontalTest(void)
+{
+ disconnect();
+}
+
+// Connect to the NX server
+
+bool CSliderHorizontalTest::connect(void)
+{
+ // Connect to the server
+
+ bool nxConnected = CNxServer::connect();
+ if (nxConnected)
+ {
+ // Set the background color
+
+ if (!setBackgroundColor(CONFIG_CSLIDERHORIZONTALTEST_BGCOLOR))
+ {
+ message("CSliderHorizontalTest::connect: setBackgroundColor failed\n");
+ }
+ }
+
+ return nxConnected;
+}
+
+// Disconnect from the NX server
+
+void CSliderHorizontalTest::disconnect(void)
+{
+ // Close the window
+
+ if (m_bgWindow)
+ {
+ delete m_bgWindow;
+ m_bgWindow = (CBgWindow *)NULL;
+ }
+
+ // Free the widget control instance
+
+ if (m_widgetControl)
+ {
+ delete m_widgetControl;
+ m_widgetControl = (CWidgetControl *)NULL;
+ }
+
+ // And disconnect from the server
+
+ CNxServer::disconnect();
+}
+
+// Create the background window instance. This function illustrates
+// the basic steps to instantiate any window:
+//
+// 1) Create a dumb CWigetControl instance
+// 2) Pass the dumb CWidgetControl instance to the window constructor
+// that inherits from INxWindow. This will "smarten" the CWidgetControl
+// instance with some window knowlede
+// 3) Call the open() method on the window to display the window.
+// 4) After that, the fully smartened CWidgetControl instance can
+// be used to generate additional widgets by passing it to the
+// widget constructor
+
+bool CSliderHorizontalTest::createWindow(void)
+{
+ // Initialize the widget control using the default style
+
+ m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL);
+
+ // Get an (uninitialized) instance of the background window as a class
+ // that derives from INxWindow.
+
+ m_bgWindow = getBgWindow(m_widgetControl);
+ if (!m_bgWindow)
+ {
+ message("CSliderHorizontalTest::createWindow: Failed to create CBgWindow instance\n");
+ disconnect();
+ return false;
+ }
+
+ // Open (and initialize) the window
+
+ bool success = m_bgWindow->open();
+ if (!success)
+ {
+ message("CSliderHorizontalTest::createWindow: Failed to open background window\n");
+ disconnect();
+ return false;
+ }
+
+ return true;
+}
+
+// Create a slider in the center of the window
+
+CSliderHorizontal *CSliderHorizontalTest::createSlider(void)
+{
+ // Get the size of the display
+
+ struct nxgl_size_s windowSize;
+ if (!m_bgWindow->getSize(&windowSize))
+ {
+ printf("CSliderHorizontalTest::createSlider: Failed to get window size\n");
+ disconnect();
+ return false;
+ }
+
+ // Put the slider in the center of the display
+
+ nxgl_coord_t sliderWidth = windowSize.w >> 1;
+ nxgl_coord_t sliderX = windowSize.w >> 2;
+
+ nxgl_coord_t sliderHeight = 10;
+ nxgl_coord_t sliderY = (windowSize.h - sliderHeight) >> 1;
+
+ // Create the slider
+
+ CSliderHorizontal *slider = new CSliderHorizontal(m_widgetControl,
+ sliderX, sliderY,
+ sliderWidth, sliderHeight);
+ if (!slider)
+ {
+ printf("CSliderHorizontalTest::createSlider: Failed to create CSliderHorizontal\n");
+ disconnect();
+ }
+ return slider;
+}
+
+// (Re-)draw the slider.
+
+void CSliderHorizontalTest::showSlider(CSliderHorizontal *slider)
+{
+ slider->enable(); // Un-necessary, the widget is enabled by default
+ slider->enableDrawing();
+ slider->redraw();
+}
diff --git a/NxWidgets/UnitTests/CSliderHorizonal/csliderhorizontaltest.hxx b/NxWidgets/UnitTests/CSliderHorizonal/csliderhorizontaltest.hxx
new file mode 100644
index 000000000..1dde688a8
--- /dev/null
+++ b/NxWidgets/UnitTests/CSliderHorizonal/csliderhorizontaltest.hxx
@@ -0,0 +1,147 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CSliderHorizontal/csliderhorizontaltest.hxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef __UNITTESTS_CSLIDERHORIZONTAL_CSLIDERHORIZONTALTEST_HXX
+#define __UNITTESTS_CSLIDERHORIZONTAL_CSLIDERHORIZONTALTEST_HXX
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <semaphore.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "nxconfig.hxx"
+#include "cwidgetcontrol.hxx"
+#include "ccallback.hxx"
+#include "cbgwindow.hxx"
+#include "cnxserver.hxx"
+#include "csliderhorizontal.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+// Configuration ////////////////////////////////////////////////////////////
+
+#ifndef CONFIG_HAVE_CXX
+# error "CONFIG_HAVE_CXX must be defined"
+#endif
+
+#ifndef CONFIG_CSLIDERHORIZONTALTEST_BGCOLOR
+# define CONFIG_CSLIDERHORIZONTALTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR
+#endif
+
+// What is the entry point called?
+
+#ifdef CONFIG_NSH_BUILTIN_APPS
+# define MAIN_NAME csliderhorizontal_main
+# define MAIN_STRING "csliderhorizontal_main: "
+#else
+# define MAIN_NAME user_start
+# define MAIN_STRING "user_start: "
+#endif
+
+// If debug is enabled, use the debug function, lib_rawprintf() instead
+// of printf() so that the output is synchronized.
+
+#ifdef CONFIG_DEBUG
+# define message lib_lowprintf
+#else
+# define message printf
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Classes
+/////////////////////////////////////////////////////////////////////////////
+
+using namespace NXWidgets;
+
+class CSliderHorizontalTest : public CNxServer
+{
+private:
+ CWidgetControl *m_widgetControl; // The controlling widget for the window
+ CBgWindow *m_bgWindow; // Background window instance
+
+public:
+ // Constructor/destructors
+
+ CSliderHorizontalTest(void);
+ ~CSliderHorizontalTest(void);
+
+ // Initializer/unitializer. These methods encapsulate the basic steps for
+ // starting and stopping the NX server
+
+ bool connect(void);
+ void disconnect(void);
+
+ // Create a window. This method provides the general operations for
+ // creating a window that you can draw within.
+ //
+ // Those general operations are:
+ // 1) Create a dumb CWigetControl instance
+ // 2) Pass the dumb CWidgetControl instance to the window constructor
+ // that inherits from INxWindow. This will "smarten" the CWidgetControl
+ // instance with some window knowlede
+ // 3) Call the open() method on the window to display the window.
+ // 4) After that, the fully smartened CWidgetControl instance can
+ // be used to generate additional widgets by passing it to the
+ // widget constructor
+
+ bool createWindow(void);
+
+ // Create a slider in the center of the window
+
+ CSliderHorizontal *createSlider(void);
+
+ // (Re-)draw the slider.
+
+ void showSlider(CSliderHorizontal *slider);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+#endif // __UNITTESTS_CSLIDERHORIZONTAL_CSLIDERHORIZONTALTEST_HXX
diff --git a/NxWidgets/UnitTests/CSliderHorizonal/main.cxx b/NxWidgets/UnitTests/CSliderHorizonal/main.cxx
new file mode 100644
index 000000000..b99d1c547
--- /dev/null
+++ b/NxWidgets/UnitTests/CSliderHorizonal/main.cxx
@@ -0,0 +1,231 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CSliderHorizontal/main.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <unistd.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "csliderhorizontaltest.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+#define MAX_SLIDER 50
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+static unsigned int g_mmInitial;
+static unsigned int g_mmprevious;
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+// Suppress name-mangling
+
+extern "C" int MAIN_NAME(int argc, char *argv[]);
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: updateMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void updateMemoryUsage(unsigned int previous,
+ FAR const char *msg)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ /* Show the change from the previous time */
+
+ message("\n%s:\n", msg);
+ message(" Before: %8d After: %8d Change: %8d\n\n",
+ previous, mmcurrent.uordblks, mmcurrent.uordblks - previous);
+
+ /* Set up for the next test */
+
+ g_mmprevious = mmcurrent.uordblks;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: initMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void initMemoryUsage(void)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ g_mmInitial = mmcurrent.uordblks;
+ g_mmprevious = mmcurrent.uordblks;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: user_start/nxheaders_main
+/////////////////////////////////////////////////////////////////////////////
+
+int MAIN_NAME(int argc, char *argv[])
+{
+ // Initialize memory monitor logic
+
+ initMemoryUsage();
+
+ // Create an instance of the checkbox test
+
+ message(MAIN_STRING "Create CSliderHorizontalTest instance\n");
+ CSliderHorizontalTest *test = new CSliderHorizontalTest();
+ updateMemoryUsage(g_mmprevious, "After creating CSliderHorizontalTest");
+
+ // Connect the NX server
+
+ message(MAIN_STRING "Connect the CSliderHorizontalTest instance to the NX server\n");
+ if (!test->connect())
+ {
+ message(MAIN_STRING "Failed to connect the CSliderHorizontalTest instance to the NX server\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After connecting to the server");
+
+ // Create a window to draw into
+
+ message(MAIN_STRING "Create a Window\n");
+ if (!test->createWindow())
+ {
+ message(MAIN_STRING "Failed to create a window\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating a window");
+
+ // Create a slider
+
+ message(MAIN_STRING "Create a Slider\n");
+ CSliderHorizontal *slider = test->createSlider();
+ if (!slider)
+ {
+ message(MAIN_STRING "Failed to create a slider\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating a slider");
+
+ // Set the slider minimum and maximum values
+
+ slider->setMinimumValue(0);
+ slider->setMaximumValue(MAX_SLIDER);
+ slider->setValue(0);
+ message(MAIN_STRING "Slider range %d->%d Initial value %d\n",
+ slider->getMinimumValue(), slider->getMaximumValue(),
+ slider->getValue());
+
+ // Show the initial state of the checkbox
+
+ test->showSlider(slider);
+ sleep(1);
+
+ // Now move the slider up
+
+ for (int i = 0; i <= MAX_SLIDER; i++)
+ {
+ slider->setValue(i);
+ test->showSlider(slider);
+ message(MAIN_STRING "%d. New value %d\n", i, slider->getValue());
+ usleep(1000); // The simulation needs this to let the X11 event loop run
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After moving the slider up");
+
+ // And move the slider down
+
+ for (int i = MAX_SLIDER; i >= 0; i--)
+ {
+ slider->setValue(i);
+ test->showSlider(slider);
+ message(MAIN_STRING "%d. New value %d\n", i, slider->getValue());
+ usleep(1000); // The simulation needs this to let the X11 event loop run
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After moving the slider down");
+ sleep(1);
+
+ // Clean up and exit
+
+ message(MAIN_STRING "Clean-up and exit\n");
+ delete slider;
+ updateMemoryUsage(g_mmprevious, "After deleting the slider");
+ delete test;
+ updateMemoryUsage(g_mmprevious, "After deleting the test");
+ updateMemoryUsage(g_mmInitial, "Final memory usage");
+ return 0;
+}
+
diff --git a/NxWidgets/UnitTests/CSliderVertical/Makefile b/NxWidgets/UnitTests/CSliderVertical/Makefile
new file mode 100644
index 000000000..5d5e590f1
--- /dev/null
+++ b/NxWidgets/UnitTests/CSliderVertical/Makefile
@@ -0,0 +1,172 @@
+#################################################################################
+# NxWidgets/UnitTests/CSliderVertical/Makefile
+#
+# Copyright (C) 2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+# me be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#################################################################################
+
+TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'}
+
+-include $(TOPDIR)/.config
+-include $(TOPDIR)/Make.defs
+include $(APPDIR)/Make.defs
+
+# Add the path to the NXWidget include directory to the CFLAGS
+
+NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets"
+NXWIDGETS_INC="$(NXWIDGETS_DIR)/include"
+NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)"
+
+INCDIR=$(TOPDIR)/tools/incdir.sh
+ifeq ($(WINTOOL),y)
+ CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"}
+else
+ CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"}
+endif
+
+# Get the path to the archiver tool
+
+TESTTOOL_DIR="$(TESTDIR)/../tools"
+ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh
+
+# Hello, World! C++ Example
+
+ASRCS =
+CSRCS =
+CXXSRCS = main.cxx csliderverticaltest.cxx
+
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+COBJS = $(CSRCS:.c=$(OBJEXT))
+CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS)
+OBJS = $(AOBJS) $(COBJS) $(CXXOBJS)
+
+POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)"
+ifeq ($(WINTOOL),y)
+ BIN = "${shell cygpath -w $(POSIX_BIN)}"
+else
+ BIN = $(POSIX_BIN)
+endif
+
+ROOTDEPPATH = --dep-path .
+
+# helloxx built-in application info
+
+APPNAME = cslidervertical
+PRIORITY = SCHED_PRIORITY_DEFAULT
+STACKSIZE = 2048
+
+# Common build
+
+VPATH =
+
+all: .built
+.PHONY: clean depend context disclean chkcxx chklib
+
+# Object file creation targets
+
+$(AOBJS): %$(OBJEXT): %.S
+ $(call ASSEMBLE, $<, $@)
+
+$(COBJS): %$(OBJEXT): %.c
+ $(call COMPILE, $<, $@)
+
+$(CXXOBJS): %$(OBJEXT): %.cxx
+ $(call COMPILEXX, $<, $@)
+
+# Verify that the NuttX configuration is setup to support C++
+
+chkcxx:
+ifneq ($(CONFIG_HAVE_CXX),y)
+ @echo ""
+ @echo "In order to use this example, you toolchain must support must"
+ @echo ""
+ @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support"
+ @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file"
+ @echo " of the configuration that you are using."
+ @echo ""
+ @exit 1
+endif
+
+# Verify that the NXWidget library has been built
+
+chklib:
+ @( \
+ if [ ! -e "$(NXWIDGETS_LIB)" ]; then \
+ echo "$(NXWIDGETS_LIB) does not exist."; \
+ echo "Please go to $(NXWIDGETS_DIR)"; \
+ echo "and rebuild the library"; \
+ exit 1; \
+ fi; \
+ )
+
+# Library creation targets
+
+$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work.
+
+.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB)
+ @( for obj in $(OBJS) ; do \
+ $(call ARCHIVE, $(BIN), $${obj}); \
+ done ; )
+ifeq ($(WINTOOL),y)
+ @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+else
+ @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+endif
+ @touch .built
+
+# Standard housekeeping targets
+
+.context:
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+ $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
+endif
+ @touch $@
+
+context: .context
+
+.depend: Makefile $(SRCS)
+ @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep
+ @touch $@
+
+depend: .depend
+
+clean:
+ @rm -f *.o *~ .*.swp .built
+ $(call CLEAN)
+
+distclean: clean
+ @rm -f Make.dep .depend
+
+-include Make.dep
diff --git a/NxWidgets/UnitTests/CSliderVertical/csliderverticaltest.cxx b/NxWidgets/UnitTests/CSliderVertical/csliderverticaltest.cxx
new file mode 100644
index 000000000..d0691c52d
--- /dev/null
+++ b/NxWidgets/UnitTests/CSliderVertical/csliderverticaltest.cxx
@@ -0,0 +1,225 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CSliderVertical/csliderverticaltest.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+// modify this software without notice.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cerrno>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+#include <nuttx/nx/nxfonts.h>
+
+#include "nxconfig.hxx"
+#include "cbgwindow.hxx"
+#include "csliderverticaltest.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// CSliderVerticalTest Method Implementations
+/////////////////////////////////////////////////////////////////////////////
+
+// CSliderVerticalTest Constructor
+
+CSliderVerticalTest::CSliderVerticalTest()
+{
+ // Initialize state data
+
+ m_widgetControl = (CWidgetControl *)NULL;
+ m_bgWindow = (CBgWindow *)NULL;
+}
+
+// CSliderVerticalTest Descriptor
+
+CSliderVerticalTest::~CSliderVerticalTest(void)
+{
+ disconnect();
+}
+
+// Connect to the NX server
+
+bool CSliderVerticalTest::connect(void)
+{
+ // Connect to the server
+
+ bool nxConnected = CNxServer::connect();
+ if (nxConnected)
+ {
+ // Set the background color
+
+ if (!setBackgroundColor(CONFIG_CSLIDERVERTICALTEST_BGCOLOR))
+ {
+ message("CSliderVerticalTest::connect: setBackgroundColor failed\n");
+ }
+ }
+
+ return nxConnected;
+}
+
+// Disconnect from the NX server
+
+void CSliderVerticalTest::disconnect(void)
+{
+ // Close the window
+
+ if (m_bgWindow)
+ {
+ delete m_bgWindow;
+ m_bgWindow = (CBgWindow *)NULL;
+ }
+
+ // Free the widget control instance
+
+ if (m_widgetControl)
+ {
+ delete m_widgetControl;
+ m_widgetControl = (CWidgetControl *)NULL;
+ }
+
+ // And disconnect from the server
+
+ CNxServer::disconnect();
+}
+
+// Create the background window instance. This function illustrates
+// the basic steps to instantiate any window:
+//
+// 1) Create a dumb CWigetControl instance
+// 2) Pass the dumb CWidgetControl instance to the window constructor
+// that inherits from INxWindow. This will "smarten" the CWidgetControl
+// instance with some window knowlede
+// 3) Call the open() method on the window to display the window.
+// 4) After that, the fully smartened CWidgetControl instance can
+// be used to generate additional widgets by passing it to the
+// widget constructor
+
+bool CSliderVerticalTest::createWindow(void)
+{
+ // Initialize the widget control using the default style
+
+ m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL);
+
+ // Get an (uninitialized) instance of the background window as a class
+ // that derives from INxWindow.
+
+ m_bgWindow = getBgWindow(m_widgetControl);
+ if (!m_bgWindow)
+ {
+ message("CSliderVerticalTest::createWindow: Failed to create CBgWindow instance\n");
+ disconnect();
+ return false;
+ }
+
+ // Open (and initialize) the window
+
+ bool success = m_bgWindow->open();
+ if (!success)
+ {
+ message("CSliderVerticalTest::createWindow: Failed to open background window\n");
+ disconnect();
+ return false;
+ }
+
+ return true;
+}
+
+// Create a slider in the center of the window
+
+CSliderVertical *CSliderVerticalTest::createSlider(void)
+{
+ // Get the size of the display
+
+ struct nxgl_size_s windowSize;
+ if (!m_bgWindow->getSize(&windowSize))
+ {
+ printf("CSliderVerticalTest::createSlider: Failed to get window size\n");
+ disconnect();
+ return false;
+ }
+
+ // Put the slider in the center of the display
+
+ nxgl_coord_t sliderWidth = 10;
+ nxgl_coord_t sliderX = (windowSize.w - sliderWidth) >> 1;
+
+ nxgl_coord_t sliderHeight = windowSize.h >> 1;
+ nxgl_coord_t sliderY = windowSize.h >> 2;
+
+ // Create the slider
+
+ CSliderVertical *slider = new CSliderVertical(m_widgetControl,
+ sliderX, sliderY,
+ sliderWidth, sliderHeight);
+ if (!slider)
+ {
+ printf("CSliderVerticalTest::createSlider: Failed to create CSliderVertical\n");
+ disconnect();
+ }
+ return slider;
+}
+
+// (Re-)draw the slider.
+
+void CSliderVerticalTest::showSlider(CSliderVertical *slider)
+{
+ slider->enable(); // Un-necessary, the widget is enabled by default
+ slider->enableDrawing();
+ slider->redraw();
+}
diff --git a/NxWidgets/UnitTests/CSliderVertical/csliderverticaltest.hxx b/NxWidgets/UnitTests/CSliderVertical/csliderverticaltest.hxx
new file mode 100644
index 000000000..e8d506db9
--- /dev/null
+++ b/NxWidgets/UnitTests/CSliderVertical/csliderverticaltest.hxx
@@ -0,0 +1,147 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CSliderVertical/csliderverticaltest.hxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef __UNITTESTS_CSLIDERVERTICAL_CSLIDERVERTICALTEST_HXX
+#define __UNITTESTS_CSLIDERVERTICAL_CSLIDERVERTICALTEST_HXX
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <semaphore.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "nxconfig.hxx"
+#include "cwidgetcontrol.hxx"
+#include "ccallback.hxx"
+#include "cbgwindow.hxx"
+#include "cnxserver.hxx"
+#include "cslidervertical.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+// Configuration ////////////////////////////////////////////////////////////
+
+#ifndef CONFIG_HAVE_CXX
+# error "CONFIG_HAVE_CXX must be defined"
+#endif
+
+#ifndef CONFIG_CSLIDERVERTICALTEST_BGCOLOR
+# define CONFIG_CSLIDERVERTICALTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR
+#endif
+
+// What is the entry point called?
+
+#ifdef CONFIG_NSH_BUILTIN_APPS
+# define MAIN_NAME cslidervertical_main
+# define MAIN_STRING "cslidervertical_main: "
+#else
+# define MAIN_NAME user_start
+# define MAIN_STRING "user_start: "
+#endif
+
+// If debug is enabled, use the debug function, lib_rawprintf() instead
+// of printf() so that the output is synchronized.
+
+#ifdef CONFIG_DEBUG
+# define message lib_lowprintf
+#else
+# define message printf
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Classes
+/////////////////////////////////////////////////////////////////////////////
+
+using namespace NXWidgets;
+
+class CSliderVerticalTest : public CNxServer
+{
+private:
+ CWidgetControl *m_widgetControl; // The controlling widget for the window
+ CBgWindow *m_bgWindow; // Background window instance
+
+public:
+ // Constructor/destructors
+
+ CSliderVerticalTest(void);
+ ~CSliderVerticalTest(void);
+
+ // Initializer/unitializer. These methods encapsulate the basic steps for
+ // starting and stopping the NX server
+
+ bool connect(void);
+ void disconnect(void);
+
+ // Create a window. This method provides the general operations for
+ // creating a window that you can draw within.
+ //
+ // Those general operations are:
+ // 1) Create a dumb CWigetControl instance
+ // 2) Pass the dumb CWidgetControl instance to the window constructor
+ // that inherits from INxWindow. This will "smarten" the CWidgetControl
+ // instance with some window knowlede
+ // 3) Call the open() method on the window to display the window.
+ // 4) After that, the fully smartened CWidgetControl instance can
+ // be used to generate additional widgets by passing it to the
+ // widget constructor
+
+ bool createWindow(void);
+
+ // Create a slider in the center of the window
+
+ CSliderVertical *createSlider(void);
+
+ // (Re-)draw the slider.
+
+ void showSlider(CSliderVertical *slider);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+#endif // __UNITTESTS_CSLIDERVERTICAL_CSLIDERVERTICALTEST_HXX
diff --git a/NxWidgets/UnitTests/CSliderVertical/main.cxx b/NxWidgets/UnitTests/CSliderVertical/main.cxx
new file mode 100644
index 000000000..f5a53f018
--- /dev/null
+++ b/NxWidgets/UnitTests/CSliderVertical/main.cxx
@@ -0,0 +1,231 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CSliderVertical/main.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <unistd.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "csliderverticaltest.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+#define MAX_SLIDER 50
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+static unsigned int g_mmInitial;
+static unsigned int g_mmprevious;
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+// Suppress name-mangling
+
+extern "C" int MAIN_NAME(int argc, char *argv[]);
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: updateMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void updateMemoryUsage(unsigned int previous,
+ FAR const char *msg)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ /* Show the change from the previous time */
+
+ message("\n%s:\n", msg);
+ message(" Before: %8d After: %8d Change: %8d\n\n",
+ previous, mmcurrent.uordblks, mmcurrent.uordblks - previous);
+
+ /* Set up for the next test */
+
+ g_mmprevious = mmcurrent.uordblks;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: initMemoryUsage
+/////////////////////////////////////////////////////////////////////////////
+
+static void initMemoryUsage(void)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ g_mmInitial = mmcurrent.uordblks;
+ g_mmprevious = mmcurrent.uordblks;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Name: user_start/nxheaders_main
+/////////////////////////////////////////////////////////////////////////////
+
+int MAIN_NAME(int argc, char *argv[])
+{
+ // Initialize memory monitor logic
+
+ initMemoryUsage();
+
+ // Create an instance of the checkbox test
+
+ message(MAIN_STRING "Create CSliderVerticalTest instance\n");
+ CSliderVerticalTest *test = new CSliderVerticalTest();
+ updateMemoryUsage(g_mmprevious, "After creating CSliderVerticalTest");
+
+ // Connect the NX server
+
+ message(MAIN_STRING "Connect the CSliderVerticalTest instance to the NX server\n");
+ if (!test->connect())
+ {
+ message(MAIN_STRING "Failed to connect the CSliderVerticalTest instance to the NX server\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After connecting to the server");
+
+ // Create a window to draw into
+
+ message(MAIN_STRING "Create a Window\n");
+ if (!test->createWindow())
+ {
+ message(MAIN_STRING "Failed to create a window\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating a window");
+
+ // Create a slider
+
+ message(MAIN_STRING "Create a Slider\n");
+ CSliderVertical *slider = test->createSlider();
+ if (!slider)
+ {
+ message(MAIN_STRING "Failed to create a slider\n");
+ delete test;
+ return 1;
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating a slider");
+
+ // Set the slider minimum and maximum values
+
+ slider->setMinimumValue(0);
+ slider->setMaximumValue(MAX_SLIDER);
+ slider->setValue(0);
+ message(MAIN_STRING "Slider range %d->%d Initial value %d\n",
+ slider->getMinimumValue(), slider->getMaximumValue(),
+ slider->getValue());
+
+ // Show the initial state of the checkbox
+
+ test->showSlider(slider);
+ sleep(1);
+
+ // Now move the slider up
+
+ for (int i = 0; i <= MAX_SLIDER; i++)
+ {
+ slider->setValue(i);
+ test->showSlider(slider);
+ message(MAIN_STRING "%d. New value %d\n", i, slider->getValue());
+ usleep(1000); // The simulation needs this to let the X11 event loop run
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After moving the slider up");
+
+ // And move the slider down
+
+ for (int i = MAX_SLIDER; i >= 0; i--)
+ {
+ slider->setValue(i);
+ test->showSlider(slider);
+ message(MAIN_STRING "%d. New value %d\n", i, slider->getValue());
+ usleep(1000); // The simulation needs this to let the X11 event loop run
+ }
+ updateMemoryUsage(g_mmprevious, MAIN_STRING "After moving the slider down");
+ sleep(1);
+
+ // Clean up and exit
+
+ message(MAIN_STRING "Clean-up and exit\n");
+ delete slider;
+ updateMemoryUsage(g_mmprevious, "After deleting the slider");
+ delete test;
+ updateMemoryUsage(g_mmprevious, "After deleting the test");
+ updateMemoryUsage(g_mmInitial, "Final memory usage");
+ return 0;
+}
+
diff --git a/NxWidgets/UnitTests/CTextBox/Makefile b/NxWidgets/UnitTests/CTextBox/Makefile
new file mode 100644
index 000000000..3fe0fa43e
--- /dev/null
+++ b/NxWidgets/UnitTests/CTextBox/Makefile
@@ -0,0 +1,172 @@
+#################################################################################
+# NxWidgets/UnitTests/CTextBox/Makefile
+#
+# Copyright (C) 2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+# me be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#################################################################################
+
+TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'}
+
+-include $(TOPDIR)/.config
+-include $(TOPDIR)/Make.defs
+include $(APPDIR)/Make.defs
+
+# Add the path to the NXWidget include directory to the CFLAGS
+
+NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets"
+NXWIDGETS_INC="$(NXWIDGETS_DIR)/include"
+NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)"
+
+INCDIR=$(TOPDIR)/tools/incdir.sh
+ifeq ($(WINTOOL),y)
+ CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"}
+else
+ CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"}
+ CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"}
+endif
+
+# Get the path to the archiver tool
+
+TESTTOOL_DIR="$(TESTDIR)/../tools"
+ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh
+
+# Hello, World! C++ Example
+
+ASRCS =
+CSRCS =
+CXXSRCS = main.cxx ctextboxtest.cxx
+
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+COBJS = $(CSRCS:.c=$(OBJEXT))
+CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS)
+OBJS = $(AOBJS) $(COBJS) $(CXXOBJS)
+
+POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)"
+ifeq ($(WINTOOL),y)
+ BIN = "${shell cygpath -w $(POSIX_BIN)}"
+else
+ BIN = $(POSIX_BIN)
+endif
+
+ROOTDEPPATH = --dep-path .
+
+# helloxx built-in application info
+
+APPNAME = ctextbox
+PRIORITY = SCHED_PRIORITY_DEFAULT
+STACKSIZE = 2048
+
+# Common build
+
+VPATH =
+
+all: .built
+.PHONY: clean depend context disclean chkcxx chklib
+
+# Object file creation targets
+
+$(AOBJS): %$(OBJEXT): %.S
+ $(call ASSEMBLE, $<, $@)
+
+$(COBJS): %$(OBJEXT): %.c
+ $(call COMPILE, $<, $@)
+
+$(CXXOBJS): %$(OBJEXT): %.cxx
+ $(call COMPILEXX, $<, $@)
+
+# Verify that the NuttX configuration is setup to support C++
+
+chkcxx:
+ifneq ($(CONFIG_HAVE_CXX),y)
+ @echo ""
+ @echo "In order to use this example, you toolchain must support must"
+ @echo ""
+ @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support"
+ @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file"
+ @echo " of the configuration that you are using."
+ @echo ""
+ @exit 1
+endif
+
+# Verify that the NXWidget library has been built
+
+chklib:
+ @( \
+ if [ ! -e "$(NXWIDGETS_LIB)" ]; then \
+ echo "$(NXWIDGETS_LIB) does not exist."; \
+ echo "Please go to $(NXWIDGETS_DIR)"; \
+ echo "and rebuild the library"; \
+ exit 1; \
+ fi; \
+ )
+
+# Library creation targets
+
+$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work.
+
+.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB)
+ @( for obj in $(OBJS) ; do \
+ $(call ARCHIVE, $(BIN), $${obj}); \
+ done ; )
+ifeq ($(WINTOOL),y)
+ @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+else
+ @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR)
+endif
+ @touch .built
+
+# Standard housekeeping targets
+
+.context:
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+ $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
+endif
+ @touch $@
+
+context: .context
+
+.depend: Makefile $(SRCS)
+ @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep
+ @touch $@
+
+depend: .depend
+
+clean:
+ @rm -f *.o *~ .*.swp .built
+ $(call CLEAN)
+
+distclean: clean
+ @rm -f Make.dep .depend
+
+-include Make.dep
diff --git a/NxWidgets/UnitTests/CTextBox/ctextboxtest.cxx b/NxWidgets/UnitTests/CTextBox/ctextboxtest.cxx
new file mode 100644
index 000000000..e54bd4e6a
--- /dev/null
+++ b/NxWidgets/UnitTests/CTextBox/ctextboxtest.cxx
@@ -0,0 +1,287 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CTextBox/ctextboxtest.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <cerrno>
+#include <unistd.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+#include <nuttx/nx/nxfonts.h>
+
+#include "nxconfig.hxx"
+#include "ctextboxtest.hxx"
+#include "cbgwindow.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// CTextBoxTest Method Implementations
+/////////////////////////////////////////////////////////////////////////////
+
+// CTextBoxTest Constructor
+
+CTextBoxTest::CTextBoxTest()
+{
+ m_bgWindow = (CBgWindow *)NULL;
+ m_nxFont = (CNxFont *)NULL;
+ m_text = (CNxString *)NULL;
+}
+
+// CTextBoxTest Descriptor
+
+CTextBoxTest::~CTextBoxTest()
+{
+ disconnect();
+}
+
+// Connect to the NX server
+
+bool CTextBoxTest::connect(void)
+{
+ // Connect to the server
+
+ bool nxConnected = CNxServer::connect();
+ if (nxConnected)
+ {
+ // Create the default font instance
+
+ m_nxFont = new CNxFont(NXFONT_DEFAULT,
+ CONFIG_NXWIDGETS_DEFAULT_FONTCOLOR,
+ CONFIG_NXWIDGETS_TRANSPARENT_COLOR);
+ if (!m_nxFont)
+ {
+ printf("CTextBoxTest::connect: Failed to create the default font\n");
+ }
+
+ // Set the background color
+
+ if (!setBackgroundColor(CONFIG_CTEXTBOXTEST_BGCOLOR))
+ {
+ printf("CTextBoxTest::connect: setBackgroundColor failed\n");
+ }
+ }
+
+ return nxConnected;
+}
+
+// Disconnect from the NX server
+
+void CTextBoxTest::disconnect(void)
+{
+ // Close the window
+
+ if (m_bgWindow)
+ {
+ delete m_bgWindow;
+ }
+
+ // Free the display string
+
+ if (m_text)
+ {
+ delete m_text;
+ m_text = (CNxString *)NULL;
+ }
+
+ // Free the default font
+
+ if (m_nxFont)
+ {
+ delete m_nxFont;
+ m_nxFont = (CNxFont *)NULL;
+ }
+
+ // And disconnect from the server
+
+ CNxServer::disconnect();
+}
+
+// Create the background window instance. This function illustrates
+// the basic steps to instantiate any window:
+//
+// 1) Create a dumb CWigetControl instance
+// 2) Pass the dumb CWidgetControl instance to the window constructor
+// that inherits from INxWindow. This will "smarten" the CWidgetControl
+// instance with some window knowlede
+// 3) Call the open() method on the window to display the window.
+// 4) After that, the fully smartened CWidgetControl instance can
+// be used to generate additional widgets by passing it to the
+// widget constructor
+
+bool CTextBoxTest::createWindow(void)
+{
+ // Initialize the widget control using the default style
+
+ m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL);
+
+ // Get an (uninitialized) instance of the background window as a class
+ // that derives from INxWindow.
+
+ m_bgWindow = getBgWindow(m_widgetControl);
+ if (!m_bgWindow)
+ {
+ printf("CTextBoxTest::createGraphics: Failed to create CBgWindow instance\n");
+ delete m_widgetControl;
+ return false;
+ }
+
+ // Open (and initialize) the window
+
+ bool success = m_bgWindow->open();
+ if (!success)
+ {
+ printf("CTextBoxTest::createGraphics: Failed to open background window\n");
+ delete m_bgWindow;
+ m_bgWindow = (CBgWindow*)0;
+ return false;
+ }
+
+ return true;
+}
+
+// Create a CTextBox instance
+
+CTextBox *CTextBoxTest::createTextBox(void)
+{
+ // Get the width of the display
+
+ struct nxgl_size_s windowSize;
+ if (!m_bgWindow->getSize(&windowSize))
+ {
+ printf("CTextBoxTest::createGraphics: Failed to get window size\n");
+ return (CTextBox *)NULL;
+ }
+
+ // Create an empty CNxString instance to contain the C string
+
+ m_text = new CNxString();
+
+ // Get the height and width of the text display area. The width
+ // is half of the display width and the height is optimized for
+ // the font height
+
+ nxgl_coord_t textBoxWidth = windowSize.w >> 1;
+ nxgl_coord_t textBoxHeight = (nxgl_coord_t)m_nxFont->getHeight();
+
+ // The default CTextBox has borders enabled with thickness of one.
+ // Add twice the thickness of the border to the height.
+
+ textBoxHeight += 2 * 1;
+
+ // Pick an X/Y position such that the label will be centered in the display
+
+ nxgl_coord_t labelX = windowSize.w >> 2;
+ nxgl_coord_t labelY = (windowSize.h - textBoxHeight) >> 1;
+
+ // Now we have enough information to create the label
+
+ return new CTextBox(m_widgetControl, labelX, labelY, textBoxWidth, textBoxHeight, *m_text);
+}
+
+// Draw the label
+
+void CTextBoxTest::showTextBox(CTextBox *label)
+{
+ label->enable();
+ label->enableDrawing();
+ label->redraw();
+}
+
+// Inject simulated keyboard characters into NX.
+
+void CTextBoxTest::injectChars(CTextBox *textbox, int nCh, FAR const uint8_t *string)
+{
+ // nx_kbdin is meant to be called by keyboard handling software.
+ // Here we just inject the string under unit test control.
+
+ // First, get the server handle. Graphics software will never care
+ // about the server handle. Here we need it to get access to the
+ // low-level keyboard interface
+
+ NXHANDLE handle = getServer();
+
+ // The widget must have focus to receive keyboard input
+
+ m_widgetControl->setFocusedWidget(textbox);
+
+ // Inject the string one character at a time to get a more realistic
+ // simulation of keyboard behavior. Note the API nx_kbdin() could
+ // be used to inject the string in its entirety.
+
+ for (int i = 0; i < nCh; i++)
+ {
+ // Inject the next character
+
+ (void)nx_kbdchin(handle, string[i]);
+
+ // Widget events are normally handled in a modal loop (by calling goModal()).
+ // However, for this case we know when there should be keyboard events pending,
+ // events so we don't have to poll repeatedly. We can just perform a one pass
+ // poll
+
+ m_widgetControl->pollEvents(textbox);
+
+ // Sleep a bit, just for the effect (this also gives the X server loop a
+ // chance to run in the simulated environment.
+
+ usleep(500*1000);
+ }
+}
diff --git a/NxWidgets/UnitTests/CTextBox/ctextboxtest.hxx b/NxWidgets/UnitTests/CTextBox/ctextboxtest.hxx
new file mode 100644
index 000000000..2a839b06d
--- /dev/null
+++ b/NxWidgets/UnitTests/CTextBox/ctextboxtest.hxx
@@ -0,0 +1,152 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CTextBox/ctextboxtest.hxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef __UNITTESTS_CTEXTBOX_CTEXTBOXTEST_HXX
+#define __UNITTESTS_CTEXTBOX_CTEXTBOXTEST_HXX
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <semaphore.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "nxconfig.hxx"
+#include "cwidgetcontrol.hxx"
+#include "ccallback.hxx"
+#include "cbgwindow.hxx"
+#include "cnxserver.hxx"
+#include "cnxfont.hxx"
+#include "cnxstring.hxx"
+#include "ctextbox.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+// Configuration ////////////////////////////////////////////////////////////
+
+#ifndef CONFIG_HAVE_CXX
+# error "CONFIG_HAVE_CXX must be defined"
+#endif
+
+#ifndef CONFIG_CTEXTBOXTEST_BGCOLOR
+# define CONFIG_CTEXTBOXTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR
+#endif
+
+#ifndef CONFIG_CTEXTBOXTEST_FONTCOLOR
+# define CONFIG_CTEXTBOXTEST_FONTCOLOR CONFIG_NXWIDGETS_DEFAULT_FONTCOLOR
+#endif
+
+// What is the entry point called?
+
+#ifdef CONFIG_NSH_BUILTIN_APPS
+# define MAIN_NAME ctextbox_main
+# define MAIN_STRING "ctextbox_main: "
+#else
+# define MAIN_NAME user_start
+# define MAIN_STRING "user_start: "
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Classes
+/////////////////////////////////////////////////////////////////////////////
+
+using namespace NXWidgets;
+
+class CTextBoxTest : public CNxServer
+{
+private:
+ CWidgetControl *m_widgetControl; // The controlling widget for the window
+ CNxFont *m_nxFont; // Default font
+ CBgWindow *m_bgWindow; // Background window instance
+ CNxString *m_text; // The label string
+
+public:
+ // Constructor/destructors
+
+ CTextBoxTest();
+ ~CTextBoxTest();
+
+ // Initializer/unitializer. These methods encapsulate the basic steps for
+ // starting and stopping the NX server
+
+ bool connect(void);
+ void disconnect(void);
+
+ // Create a window. This method provides the general operations for
+ // creating a window that you can draw within.
+ //
+ // Those general operations are:
+ // 1) Create a dumb CWigetControl instance
+ // 2) Pass the dumb CWidgetControl instance to the window constructor
+ // that inherits from INxWindow. This will "smarten" the CWidgetControl
+ // instance with some window knowlede
+ // 3) Call the open() method on the window to display the window.
+ // 4) After that, the fully smartened CWidgetControl instance can
+ // be used to generate additional widgets by passing it to the
+ // widget constructor
+
+ bool createWindow(void);
+
+ // Create a CTextBox instance. This method will show you how to create
+ // a CTextBox widget
+
+ CTextBox *createTextBox(void);
+
+ // Draw the label. This method illustrates how to draw the CTextBox widget.
+
+ void showTextBox(CTextBox *label);
+
+ // Inject simulated keyboard characters into NX.
+
+ void injectChars(CTextBox *textbox, int nCh, FAR const uint8_t *string);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Data
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+
+#endif // __UNITTESTS_CTEXTBOX_CTEXTBOXTEST_HXX
diff --git a/NxWidgets/UnitTests/CTextBox/main.cxx b/NxWidgets/UnitTests/CTextBox/main.cxx
new file mode 100644
index 000000000..b5b8ec4d5
--- /dev/null
+++ b/NxWidgets/UnitTests/CTextBox/main.cxx
@@ -0,0 +1,141 @@
+/////////////////////////////////////////////////////////////////////////////
+// NxWidgets/UnitTests/CTextBox/main.cxx
+//
+// Copyright (C) 2012 Gregory Nutt. All rights reserved.
+// Author: Gregory Nutt <gnutt@nuttx.org>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+// me be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Included Files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <nuttx/config.h>
+
+#include <nuttx/init.h>
+#include <cstdio>
+#include <unistd.h>
+#include <debug.h>
+
+#include <nuttx/nx/nx.h>
+
+#include "ctextboxtest.hxx"
+
+/////////////////////////////////////////////////////////////////////////////
+// Definitions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Classes
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// Private Data
+/////////////////////////////////////////////////////////////////////////////
+
+static const char string1[] = "Johhn ";
+static const char string2[] = "\b\b\bn Doe\r";
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+// Suppress name-mangling
+
+extern "C" int MAIN_NAME(int argc, char *argv[]);
+
+/////////////////////////////////////////////////////////////////////////////
+// Public Functions
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// user_start/nxheaders_main
+/////////////////////////////////////////////////////////////////////////////
+
+int MAIN_NAME(int argc, char *argv[])
+{
+ // Create an instance of the font test
+
+ printf(MAIN_STRING "Create CTextBoxTest instance\n");
+ CTextBoxTest *test = new CTextBoxTest();
+
+ // Connect the NX server
+
+ printf(MAIN_STRING "Connect the CTextBoxTest instance to the NX server\n");
+ if (!test->connect())
+ {
+ printf(MAIN_STRING "Failed to connect the CTextBoxTest instance to the NX server\n");
+ delete test;
+ return 1;
+ }
+
+ // Create a window to draw into
+
+ printf(MAIN_STRING "Create a Window\n");
+ if (!test->createWindow())
+ {
+ printf(MAIN_STRING "Failed to create a window\n");
+ delete test;
+ return 1;
+ }
+
+ // Create a CTextBox instance
+
+ CTextBox *textbox = test->createTextBox();
+ if (!textbox)
+ {
+ printf(MAIN_STRING "Failed to create a text box\n");
+ delete test;
+ return 1;
+ }
+
+ // Show the text box
+
+ test->showTextBox(textbox);
+
+ // Wait a bit, then inject a string with a typo
+
+ sleep(1);
+ test->injectChars(textbox, sizeof(string1), (FAR const uint8_t*)string1);
+
+ // Now fix the string with backspaces and finish it correctly
+
+ usleep(500*1000);
+ test->injectChars(textbox, sizeof(string2), (FAR const uint8_t*)string2);
+
+ // Clean up and exit
+
+ sleep(2);
+ printf(MAIN_STRING "Clean-up and exit\n");
+ delete textbox;
+ delete test;
+ return 0;
+}
+
diff --git a/NxWidgets/UnitTests/README.txt b/NxWidgets/UnitTests/README.txt
new file mode 100644
index 000000000..b0f3c9aab
--- /dev/null
+++ b/NxWidgets/UnitTests/README.txt
@@ -0,0 +1,394 @@
+README
+======
+
+This directory contains a collection of Unit Tests that can be used to verify
+NXWidgets.:
+
+Contents
+========
+ o Installing and Building the Unit Tests
+ 1. Setup NuttX
+ a) Configure NuttX
+ b) Enable C++ Support
+ c) Enable Debug Options
+ d) Other Possible nuttx/.config changes
+ e) Other Possible apps/.config changes
+ 2. Configure in the Selected Unit Test
+ o Work-Arounds
+ 1. Build Issues
+ 2. Stack Size Issues with the X11 Simulation
+ o Theory of Operation
+ o Unit Test Directories
+ o Example
+
+Installing and Building the Unit Tests
+======================================
+
+1. Setup NuttX
+
+ a) Configure NuttX
+
+ Configure NuttX to run one of the target configurations. For example,
+ let's assume that you are using the sim/nsh2 configuration. The sim/nsh2
+ configuration was specially created for use NXWidgets on the simulation
+ platform. A similar, special configuration stm3210e-eval/nsh2 is also
+ for the STM3210E-EVAL available. However, the unit test can be run on
+ other configurations (see steps d and e below).
+
+ We will assume the sim/nsh2 configuration in this discussion. The
+ sim/nsh2 configuration is installed as follows:
+
+ cd <nuttx-directory-path>
+ make distclean
+ cd tools
+ ./configure.sh sim/nsh2
+
+ Where:
+
+ <nuttx-directory-path> is the full, absolute path to the NuttX build directory
+
+ If you are using the sim/nsh2 or stm3210e-eval configurations, then skip
+ to step 2.
+
+ There may be certain requirements for the configuration that you select...
+ for example, certain widget tests may require touchscreen support or special
+ font selections. These test-specific requirements are addressed below under
+ "Unit Test Directories"
+
+ b) Enable C++ Support
+
+ If you are not using the sim/nsh2 or stm3210e-eval, you will need to add
+ the following definitions to the nuttx configuration at nuttx/.config to
+ enable C++ support:
+
+ CONFIG_HAVE_CXX=y
+
+ Check first, some configurations already have C++ support enabled (As of this
+ writing *ONLY* the sim/nsh2 and stm321-e-eval configurations have C++ support
+ pre-enabled).
+
+ c) Enable Debug Options
+
+ If you are running on a simulated target, then you might also want to
+ enable debug symbols:
+
+ CONFIG_DEBUG_SYMBOLS=y
+
+ Then you can run the simulation using GDB or DDD which is a very powerful
+ debugging environment!
+
+ d) Other nuttx/.config changes -- NSH configurations only.
+
+ If the configuration that you are using supports NSH and NSH built-in tasks
+ then all is well. If it is an NSH configuration, then you will have to define
+ the following in your nuttx/.config file as well (if it is not already defined):
+
+ CONFIG_NSH_BUILTIN_APPS=y
+
+ sim/nsh2 and stm3210e-eval/nsh2 already has this setting. You do not need
+ to change anything further in the nuttx/.config file if you are using either
+ of these configurations.
+
+ e) Other apps/.config changes -- NON-NSH configurations only.
+
+ For non-NSH configurations (such as the sim/touchscreen) you will have to
+ remove the CONFIGURED_APPS seting that contains the user_start function so
+ that you use the user_start in the unit test code instead. So, for example,
+ with the sim/touchscreen configuration you need to remove the following from
+ the apps/.config file:
+
+ CONFIGURED_APPS += examples/<example> ## REMOVE
+
+ The following step will then install the new, correct directory containing
+ the user_start function for the selected unit test. If you see that NSH
+ is configured:
+
+ CONFIGURED_APPS += examples/nsh ## DO NOT REMOVE
+
+ Then DO NOT REMOVE the CONFIGURED_APPS setting. Go back and re-read c)
+ above. Do either c) or d). Don't do both!
+
+ sim/nsh2 and stm3210e-eval/nsh2 both NSH configurations. You do not need
+ to change anything further in the apps/.config file for any NSH configuration.
+
+2. Configure/Install the Selected Unit Test
+
+ Then reconfigure that to use the Unit Test of your choice:
+
+ cd <raztek-nxwidgets-directory>/trunk/UnitTests/tools
+ ./install.sh <apps-directory-path> <test-sub-directory>
+
+ Where:
+
+ <apps-directory-path> is the full, absolute path to the NuttX apps/ directory
+ <test-sub-directory> is the name of a sub-directory in the UnitTests directory
+
+3. Instantiate the Configuration
+
+ Before we can make the NXWidgets Library, we have to instantiate the NuttX
+ configuration with the installed unit test:
+
+ cd <nuttx-directory-path>
+ . ./setenv.sh
+ make context
+
+ This will create auto-generated files and will setup symbolic links needed
+ in order to build the NXWidgets Library.
+
+4. Adjust the Stack Size
+
+ If using an simulation configuration (like sim/nsh2) and your unit test
+ uses X11 as its display device, then you would have to increase the size
+ of unit test stack as described below under "Stack Size Issues with the
+ X11 Simulation."
+
+5. Build the NXWidgets Library
+
+ cd <raztek-nxwidgets-directory>/trunk/NXWidgets/libnxwidgets
+ make TOPDIR=<nuttx-directory-path>
+
+6. Build NuttX including the unit test and the NXWidget library
+
+ cd <nuttx-directory-path>
+ . ./setenv.sh
+ make
+
+Work-Arounds
+============
+
+Build Issues
+------------
+1. I have seen this error on Cygwin building C++ code:
+
+ LD: nuttx.rel
+ ld: skipping incompatible /home/patacongo/projects/nuttx/nuttx/trunk/nuttx/libxx//liblibxx.a when searching for -llibxx
+ ld: cannot find -llibxx
+
+ The problem seems to be caused because gcc build code for 32-bit mode and g++ builds code for 64-bit mode. Add the -m32 option to the g++ command line seems to fix the problem. In Make.defs:
+
+ CXXFLAGS = -m32 $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) \
+ $(ARCHCPUFLAGSXX) $(ARCHINCLUDESXX) $(ARCHDEFINES) $(EXTRADEFINES) -pipe
+
+2. Stack Size Issues with the X11 Simulation
+
+ When you run the NuttX simulation, it uses stacks allocated by NuttX from the
+ NuttX heap. The memory management model is exactly the same in the simulation
+ as it is real, target system. This is good because this produces a higher
+ fidelity simulation.
+
+ However, when the simulation calls into Linux/Cygwin libraries, it will still
+ use these small simulation stacks. This happens, for example, when you call
+ into the system to get and put characters to the console window or when you
+ make x11 calls into the system. The programming model within those libraries
+ will assume a Linux/Cygwin environment where the stack size grows dynamically
+
+ As a consequence, those system libraries may allocate large data structures
+ on the stack and overflow the small NuttX stacks. X11, in particular,
+ requires large stacks. If you are using X11 in the simulation, make sure
+ that you set aside a "lot" of stack for the X11 system calls (maybe 8 or 16Kb).
+ The stack size for the thread that begins with user start is controlled
+ by the configuration setting CONFIG_USERMAIN_STACKSIZE; you may need to
+ increase this value to larger number to survive the X11 system calls.
+
+ If you are running X11 applications as NSH add-on programs, then the stack
+ size of the add-on program is controlled in another way. Here are the
+ steps for increasing the stack size in that case:
+
+ cd ../apps/namedapps # Go to the namedapps directory
+ vi namedapps_list.h # Edit this file and increase the stack size of the add-on
+ rm .built *.o # This will force the namedapps logic to rebuild
+
+Theory Of Operation
+===================
+
+The NuttX application Makefile at apps/Makefile has some special hooks for
+building "external" applications. In particular, it will automatically
+build in the contents any directory call "external/" that may appear in the
+apps/ directory. There is no external/ directory in the repository. Rather,
+this directory may be provided by the user (possibly as a symbolic link) to
+add libraries and applications to the standard build from the repository.
+
+The script at tools/install.sh, then, just does a lot of careful validation and
+sanity checking. Then it installs the UnitTest test sub-directory in the apps/
+directory by creating a symbolic link in the apps/ directory call "external".
+That symbolic link will refer to the selected UnitTest sub-directory.
+
+UnitTests
+=========
+
+The following provide simple unit tests for each of the NXWidgets. In
+addition, these unit tests provide examples for the use of each widget
+type.
+
+CButton
+ Exercises the CButton widget
+ Depends on CLabel
+
+CButtonArray
+ Exercises the CButtonArray widget
+
+CCheckBox
+ Exercises the CCheckBox widget
+ Depends on CLabel and CButton.
+
+CGlyphButton
+ Exercises the CGlyphButton widget.
+ Depends on CLabel and CButton.
+
+CImage
+ Exercises the CImage widget
+
+CLabel
+ Exercises the CLabel widget
+
+CProgressBar
+ Exercises the CProgressBar widget
+
+CRadioButton
+ Exercises the CRadioButton and CRadioButtonGroup widgets.
+ Depends on CLabel and CButton
+
+CScrollBarHorizontal
+ Exercises the ScrollbarHorizontal
+ Depends on CSliderHorizontal and CGlyphButton
+
+CScrollBarVertical
+ Exercises the ScrollbarHorizontal
+ Depends on CSliderVertical and CGlyphButton
+
+CSliderHorizontal
+ Exercises the CSliderHorizontal
+ Depends on CSliderHorizontalGrip
+
+CSliderVertical
+ Exercises the CSliderVertical
+ Depends on CSliderVerticalGrip
+
+CTextBox
+ Exercises the CTextBox widget
+ Depends on CLabel
+
+Example
+=======
+
+1. Configure sim/nsh2
+ Where: nuttx and nuttx/tools directory
+
+ $ cd tools/
+ $ ./configure.sh sim/nsh2
+ $ cd -
+
+2. Edit nuttx/.config to enable C++ support
+
+ Do nothing... sim/nsh2 already has C++ support enabled.
+
+3. Install the CButton C++ application (for example)
+ Where: NXWidgets/trunk/UnitTests/tool
+
+ $ ./install.sh ~/projects/nuttx/nuttx/trunk/apps/ CButton
+ /home/patacongo/projects/nuttx/nuttx/trunk/apps//external already exists...
+ Removing the old symbolic link.
+ Creating symbolic link
+ - To /home/patacongo/projects/nuttx/gui/raztek-nxwidgets/trunk/UnitTests/tools/../CButton
+ - At /home/patacongo/projects/nuttx/nuttx/trunk/apps//external
+
+4. Instantiate the Configuration
+ Where: nuttx directory
+
+ $ cd /home/patacongo/projects/nuttx/nuttx/trunk/nuttx
+ $ . ./setenv.sh
+ $ make context
+
+ This will create auto-generated files and will setup symbolic links needed
+ in order to build the NXWidgets Library.
+
+6. Adjust the Stack Size
+
+ If using an simulation configuration (like sim/nsh2) and your unit test
+ uses X11 as its display device, then you would have to increase the size
+ of unit test stack as described above under "Stack Size Issues."
+
+7. Build the NXWdigets Library
+ Where XWidgets/trunk/NXWidgets/libnxwidgets
+
+ $ cd /home/patacongo/projects/nuttx/gui/raztek-nxwidgets/trunkXWidgets/libnxwidgets
+ $ make TOPDIR=/home/patacongo/projects/nuttx/nuttx/trunk/nuttx
+
+8. Build NuttX
+ Where: nuttx directory
+
+ $ cd /home/patacongo/projects/nuttx/nuttx/trunk/nuttx
+ $ make
+ ...
+
+8. Run the "bringup" task:
+
+ a. Start NuttX
+ Where: nuttx directory
+
+ ./nuttx
+
+ NuttShell (NSH) NuttX-6.9
+ nsh>
+
+ b. Execute NuttX
+ Where: NSH command prompt
+
+ NOTE that when you run NSH as a simulation, the commands are echoed
+ twice -- once by Linux/Cygwin and once by NuttX:
+
+ nsh> help
+ help
+ ...
+ Builtin Apps:
+ nx
+ nxhello
+ tc
+ bringup
+ nsh> bringup
+ bringup
+ bringup [2:128]
+
+ c. Then do a kludgy thing
+ Where: NSH command prompt
+
+ The I/O with the Linux/Cygwin simulation is blocking. So while NSH is
+ waiting for input nothing can run (see configs/sim/README.txt for more info).
+ One way to make NSH stop asking for input is to sleep.
+
+ nsh> sleep 10
+ sleep 10
+
+ NOTE 1: This is not a problem if CONFIG_SCHED_WAITPID is defined in the
+ configuration file. If CONFIG_SCHED_WAITPID is defined, NSH will wait
+ for the unit test to complete and it will not be necessary to sleep.
+
+ NOTE 2: CONFIG_SCHED_WAITPID is defined in the sim/nsh2 configuration
+ so you can probably ignore this kludgy thing.
+
+ d. The Unit Test runs
+
+ As soon as NSH sleeps, the unit test will run:
+
+ bringup_main: Saying hello from the dynamically constructed instance
+ CHelloWorld::HelloWorld: Hello, World!!
+ bringup_main: Saying hello from the instance constructed on the stack
+ CHelloWorld::HelloWorld: Hello, World!!
+ bringup_main: Saying hello from the statically constructed instance
+ CHelloWorld::HelloWorld: Hello, World!!
+
+8. Debugging
+ Where: nuttx directory
+
+ In the simulation (only) you can use GDB or, better, the graphic
+ front-end DDD to debug the code. Most embedded targets do not
+ have good debugging capabilities.
+
+ In order to debug, you have to have build with CONFIG_DEBUG_SYMBOLS=y.
+ This setting is preselected in the sim/nsh2 configuration so that
+ you don't have to do anything.
+
+ Then under Linux or in a Cygwin X11 window, you can start the graphic
+ debugger like:
+
+ ddd nuttx &
diff --git a/NxWidgets/UnitTests/tools/addobjs.sh b/NxWidgets/UnitTests/tools/addobjs.sh
new file mode 100755
index 000000000..e998cfc64
--- /dev/null
+++ b/NxWidgets/UnitTests/tools/addobjs.sh
@@ -0,0 +1,141 @@
+#!/bin/bash
+#################################################################################
+# NxWidgets/UnitTests/tools/addobjs.sh
+#
+# Copyright (C) 2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+# me be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#################################################################################
+
+# set -x
+
+# Get input parameters
+
+usage="Usage: $0 [OPTIONS] <lib-path> <obj-dir>"
+advice="Try '$0 -h' for more information"
+
+unset prefix
+wintool=n
+
+while [ ! -z "$1" ]; do
+ case $1 in
+ -d )
+ set -x
+ ;;
+ -p )
+ shift
+ prefix=$1
+ ;;
+ -w )
+ wintool=y
+ ;;
+ -h )
+ echo "$0 will add all object (.o) files in directory to an archive."
+ echo ""
+ echo $usage
+ echo ""
+ echo "Where:"
+ echo " <alib-path> is the full, absolute path to the library to use"
+ echo " <obj-dir> is full path to the directory containing the object files to be added"
+ echo "OPTIONS include:"
+ echo " -p Prefix to use. For example, to use arm-elf-ar, add '-p arm-elf-'"
+ echo " -w Use Windows style paths insted of POSIX paths"
+ echo " -d Enable script debug"
+ echo " -h Show this usage information"
+ exit 0
+ ;;
+ * )
+ break;
+ ;;
+ esac
+ shift
+done
+
+libpath=$1
+objdir=$2
+archiver="${prefix}"ar
+
+# Verify input parameters
+
+if [ -z "${libpath}" ]; then
+ echo "Missing required arguments"
+ echo ""
+ echo $usage
+ echo $advice
+ exit 1
+fi
+
+if [ -z "${objdir}" ]; then
+ echo "Missing required argument <obj-dir>"
+ echo ""
+ echo $usage
+ echo $advice
+ exit 1
+fi
+
+if [ ! -w ${libpath} ]; then
+ if [ -e ${libpath} ]; then
+ echo "${libpath} exists but is not a write-able file"
+ echo $advice
+ else
+ echo "${libpath} does not exist"
+ echo $advice
+ fi
+ exit 1
+fi
+
+if [ ! -d ${objdir} ]; then
+ if [ -e ${objdir} ]; then
+ echo "${objdir} exists but is not a directory"
+ echo $advice
+ else
+ echo "${objdir} does not exist"
+ echo $advice
+ fi
+ exit 1
+fi
+
+# Add each object file in <obj-dir> to the archive at <lib-path>
+
+for obj in `ls "${objdir}"/*.o`; do
+ name=`basename "${obj}"`
+ if [ "X${wintool}" = "Xy" ]; then
+ objpath=`cygpath -w "${obj}"`
+ else
+ objpath=${obj}
+ fi
+ echo "AR: ${name}"
+ ${archiver} rcs ${libpath} ${objpath} || \
+ { echo "Failed to archive the object file:"; \
+ echo " Archive: ${libpath}"; \
+ echo " Object: ${obj}"; \
+ exit 1; \
+ }
+done \ No newline at end of file
diff --git a/NxWidgets/UnitTests/tools/install.sh b/NxWidgets/UnitTests/tools/install.sh
new file mode 100755
index 000000000..3ba086aff
--- /dev/null
+++ b/NxWidgets/UnitTests/tools/install.sh
@@ -0,0 +1,152 @@
+#!/bin/bash
+#################################################################################
+# NxWidgets/UnitTests/tools/install.sh
+#
+# Copyright (C) 2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
+# me be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#################################################################################
+#
+# set -x
+# Functions
+
+function ShowUsage()
+{
+ echo ""
+ echo "USAGE: $0 <apps-directory-path> <test-sub-directory>"
+ echo ""
+ echo "Where:"
+ echo " <apps-directory-path> is the full, absolute path to the NuttX apps/ directory"
+ echo " <test-sub-directory> is the name of a sub-directory in the UnitTests directory"
+ echo ""
+}
+
+function ShowTests()
+{
+ for testdir in ${UNITTEST_DIRPATH}/*; do
+ subdir=`basename ${testdir}`
+ if [ -d "${UNITTEST_DIRPATH}/${subdir}" ]; then
+ if [ -f "${UNITTEST_DIRPATH}/${subdir}/Makefile" ]; then
+ echo $subdir
+ fi
+ fi
+ done
+}
+
+# Input parameters
+
+APPS_DIRPATH=$1
+TEST_SUBDIR=$2
+
+if [ -z "${APPS_DIRPATH}" ]; then
+ echo "Missing required arguments"
+ ShowUsage
+ exit 1
+fi
+
+if [ -z "${TEST_SUBDIR}" ]; then
+ echo "Missing required argument <test-sub-directory>"
+ ShowUsage
+ exit 1
+fi
+
+# Make sure that we know where we are and where we are going
+
+WD=`pwd`
+if [ -x install.sh ]; then
+ UNITTEST_DIRPATH="${WD}/.."
+ TOOLS_DIRPATH="${WD}"
+else
+ if [ -x tools/install.sh ]; then
+ UNITTEST_DIRPATH="${WD}"
+ TOOLS_DIRPATH="${WD}/tools"
+ else
+ echo "This script must be executed in the UnitTest or UnitTest/tools directory"
+ ShowUsage
+ exit 1
+ fi
+fi
+
+if [ ! -d "${APPS_DIRPATH}" ]; then
+ echo "Directory ${APPS_DIRPATH} does not exist"
+ ShowUsage
+ exit 1
+fi
+
+if [ ! -f "${APPS_DIRPATH}/Makefile" ]; then
+ echo "Directory ${APPS_DIRPATH} does not look like a NuttX apps directory"
+ ShowUsage
+ exit 1
+fi
+
+TEST_PATH="${UNITTEST_DIRPATH}/${TEST_SUBDIR}"
+if [ ! -d "${TEST_PATH}" ]; then
+ echo "Directory ${TEST_PATH} does not exist"
+ ShowUsage
+ ShowTests
+ exit 1
+fi
+
+if [ ! -f "${TEST_PATH}/Makefile" ]; then
+ echo "Directory ${TEST_PATH} does not look like a unit test directory"
+ ShowUsage
+ ShowTests
+ exit 1
+fi
+
+# Check if the symbolic link "external" exists in the NuttX apps directory
+
+if [ -e "${APPS_DIRPATH}/external" ]; then
+ echo "${APPS_DIRPATH}/external already exists..."
+ if [ -h "${APPS_DIRPATH}/external" ]; then
+ echo " Removing the old symbolic link."
+ rm "${APPS_DIRPATH}/external" || \
+ { echo " ERROR: Failed to remove old symbolic link"; \
+ exit 1;
+ }
+ else
+ echo " ERROR: But it is not a symbolic link!"
+ echo " Please remove ${APPS_DIRPATH}/external"
+ echo " and run this script again"
+ fi
+fi
+
+# Then set up the symbolic link "external" in the NuttX apps to point to the
+# UnitTest subdirectory
+
+echo "Creating symbolic link"
+echo " - To ${TEST_PATH}"
+echo " - At ${APPS_DIRPATH}/external"
+
+ln -s "${TEST_PATH}" "${APPS_DIRPATH}/external" || \
+ { echo "Failed to create symbollic link"; \
+ exit 1;
+ }
+