From 990276740afafeb69f64b01050a99f113bb89fa6 Mon Sep 17 00:00:00 2001 From: patacongo Date: Tue, 1 May 2012 14:52:54 +0000 Subject: Add beginning of NxWM NxConsole application git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4681 42af7a65-404d-4744-a932-0658087f49c3 --- NxWidgets/README.txt | 40 ++++ NxWidgets/UnitTests/nxwm/main.cxx | 7 + NxWidgets/nxwm/include/cnxconsole.hxx | 131 ++++++++--- NxWidgets/nxwm/include/cstartwindow.hxx | 4 +- NxWidgets/nxwm/include/iapplication.hxx | 6 +- NxWidgets/nxwm/include/nxwmconfig.hxx | 22 ++ NxWidgets/nxwm/src/cnxconsole.cxx | 372 +++++++++++++++++++++++++++++++- NxWidgets/nxwm/src/cstartwindow.cxx | 8 +- NxWidgets/nxwm/src/ctaskbar.cxx | 7 +- 9 files changed, 562 insertions(+), 35 deletions(-) (limited to 'NxWidgets') diff --git a/NxWidgets/README.txt b/NxWidgets/README.txt index 380051a22..99b1d8fda 100755 --- a/NxWidgets/README.txt +++ b/NxWidgets/README.txt @@ -49,3 +49,43 @@ o Many Graphic Objects Note: Many of the fundamental classed in NxWidgets derive from the Antony Dzeryn's "Woopsi" project: http://woopsi.org/ which also has a BSD style license. See the COPYING file for details. + +Directory Structure +=================== + +libnxwidgets + + The source code, header files, and build environment for NxWidgets is + provided in this directory. + +UnitTests + + Provides a collection of unit-level tests for many of the individual + widgets provided by libnxwidgets. + +nxwm + + This directory holds a tiny desktop for small embedded devices with a + touchscreen,. NxWM. NxWM is truly multiple window manager but only one + window is displayed at a time. This simplification helps performance on + LCD based products (in the same way that a tiled window manager helps) + and also makes the best use of small displays. It is awkward from a + human factors point-of-view trying to manage multiple windows on a + small display. + + The window manager consists of a task bar with icons representing the + running tasks. If you touch the tasks icon, it comes to the top. Each + window has a toolbar with (1) a title, (2) a minimize button, and (3) a + stop application button using the standard icons for these things. + + There is always a start window that is available in the task bar. When + you touch the start window icon, it brings up the start window containing + icons representing all of the available applications. If you touch an + icon in the start window, it will be started and added to the task bar. + + There is a base class that defines an add-on application and an + interface that supports incorporation of new application. The only + application that is provided is NxConsole. This is an NSH session + running in a window. I should be able to select the NX icon in the start + menu and create as many NSH sessions in windows as I want. (keybard input + still comes through serial). diff --git a/NxWidgets/UnitTests/nxwm/main.cxx b/NxWidgets/UnitTests/nxwm/main.cxx index dffa7b600..b0792c1f4 100644 --- a/NxWidgets/UnitTests/nxwm/main.cxx +++ b/NxWidgets/UnitTests/nxwm/main.cxx @@ -38,6 +38,7 @@ ///////////////////////////////////////////////////////////////////////////// #include +#include #include "ctaskbar.hxx" #include "cstartwindow.hxx" @@ -90,6 +91,12 @@ extern "C" int MAIN_NAME(int argc, char *argv[]); int MAIN_NAME(int argc, char *argv[]) { + // Call all C++ static constructors + +#if defined(CONFIG_HAVE_CXX) && defined(CONFIG_HAVE_CXXINITIALIZE) + up_cxxinitialize(); +#endif + // Create an instance of the Task Bar. // // The general sequence for initializing the task bar is: diff --git a/NxWidgets/nxwm/include/cnxconsole.hxx b/NxWidgets/nxwm/include/cnxconsole.hxx index 4009eb8b9..99a9b92f2 100644 --- a/NxWidgets/nxwm/include/cnxconsole.hxx +++ b/NxWidgets/nxwm/include/cnxconsole.hxx @@ -42,7 +42,13 @@ #include +#include +#include +#include + #include "iapplication.hxx" +#include "capplicationwindow.hxx" +#include "ctaskbar.hxx" /**************************************************************************** * Pre-Processor Definitions @@ -56,37 +62,110 @@ namespace NxWM { + /** + * One time NSH initialization. This function must be called exactly + * once during the boot-up sequence to initialize the NSH library. + * + * @return True on successful initialization + */ + + bool nshlibInitialize(void); + /** * This class implements the NxConsole application. */ - class CNxConsole : public IApplication + class CNxConsole : public IApplication, private IApplicationCallback { - protected: - /** - * CNxConsole destructor - */ - - ~CNxConsole(void); - - public: - /** - * CNxConsole constructor - * - * @param window. The application window - */ - - CNxConsole(NXWidgets::INxWindow *window); - - /** - * Get the icon associated with the application - * - * @return An instance if IBitmap that may be used to rend the - * application's icon. This is an new IBitmap instance that must - * be deleted by the caller when it is no long needed. - */ - - NXWidgets::IBitmap *getIcon(void); + protected: + CTaskbar *m_taskbar; /**< Reference to the "parent" taskbar */ + CApplicationWindow *m_window; /**< Reference to the application window */ + NXCONSOLE m_nxcon; /**< NxConsole handle */ + pid_t m_pid; /**< Task ID of the NxConsole thread */ + + /** + * Called when the window minimize button is pressed. + */ + + void minimize(void); + + /** + * Called when the window minimize close is pressed. + */ + + void close(void); + + /** + * CNxConsole destructor + */ + + ~CNxConsole(void); + + public: + /** + * CNxConsole constructor + * + * @param window. The application window + * + * @param taskbar. A pointer to the parent task bar instance + * @param window. The window to be used by this application. + */ + + CNxConsole(CTaskbar *taskbar, CApplicationWindow *window); + + /** + * Each implementation of IApplication must provide a method to recover + * the contained CApplicationWindow instance. + */ + + CApplicationWindow *getWindow(void) const; + + /** + * Get the icon associated with the application + * + * @return An instance if IBitmap that may be used to rend the + * application's icon. This is an new IBitmap instance that must + * be deleted by the caller when it is no long needed. + */ + + NXWidgets::IBitmap *getIcon(void); + + /** + * Get the name string associated with the application + * + * @return A copy if CNxString that contains the name of the application. + */ + + NXWidgets::CNxString getName(void); + + /** + * Start the application (perhaps in the minimized state). + * + * @return True if the application was successfully started. + */ + + bool run(void); + + /** + * Stop the application. + */ + + void stop(void); + + /** + * The application window is hidden (either it is minimized or it is + * maximized, but not at the top of the hierarchy + */ + + void hide(void); + + /** + * Redraw the entire window. The application has been maximized or + * otherwise moved to the top of the hierarchy. This method is call from + * CTaskbar when the application window must be displayed + */ + + void redraw(void); }; } #endif // __cplusplus diff --git a/NxWidgets/nxwm/include/cstartwindow.hxx b/NxWidgets/nxwm/include/cstartwindow.hxx index fca886e8d..ab6b6f926 100644 --- a/NxWidgets/nxwm/include/cstartwindow.hxx +++ b/NxWidgets/nxwm/include/cstartwindow.hxx @@ -160,9 +160,11 @@ namespace NxWM /** * Start the application. + * + * @return True if the application was successfully started. */ - void run(void); + bool run(void); /** * Stop the application. diff --git a/NxWidgets/nxwm/include/iapplication.hxx b/NxWidgets/nxwm/include/iapplication.hxx index 885b85710..be9a96fe5 100644 --- a/NxWidgets/nxwm/include/iapplication.hxx +++ b/NxWidgets/nxwm/include/iapplication.hxx @@ -99,10 +99,12 @@ namespace NxWM virtual NXWidgets::CNxString getName(void) = 0; /** - * Start the application (pehaps in the minimized state). + * Start the application (perhaps in the minimized state). + * + * @return True if the application was successfully started. */ - virtual void run(void) = 0; + virtual bool run(void) = 0; /** * Stop the application. diff --git a/NxWidgets/nxwm/include/nxwmconfig.hxx b/NxWidgets/nxwm/include/nxwmconfig.hxx index cdbcee564..a683dbd5f 100644 --- a/NxWidgets/nxwm/include/nxwmconfig.hxx +++ b/NxWidgets/nxwm/include/nxwmconfig.hxx @@ -198,4 +198,26 @@ # define CONFIG_NXWM_STARTWINDOW_HSPACING (2) #endif +/* NxConsole Window *********************************************************/ + +#ifndef CONFIG_NXWM_NXCONSOLE_PRIO +# define CONFIG_NXWM_NXCONSOLE_PRIO SCHED_PRIORITY_DEFAULT +#endif + +#ifndef CONFIG_NXWM_NXCONSOLE_STACKSIZE +# define CONFIG_NXWM_NXCONSOLE_STACKSIZE 2048 +#endif + +#ifndef CONFIG_NXWM_NXCONSOLE_WCOLOR +# define CONFIG_NXWM_NXCONSOLE_WCOLOR MKRGB(192,192,192) +#endif + +#ifndef CONFIG_NXWM_NXCONSOLE_FONTCOLOR +# define CONFIG_NXWM_NXCONSOLE_FONTCOLOR MKRGB(0,0,0) +#endif + +#ifndef CONFIG_NXWM_NXCONSOLE_FONTID +# define CONFIG_NXWM_NXCONSOLE_FONTID CONFIG_NXWM_DEFAULT_FONTID +#endif + #endif // __INCLUDE_NXWMCONFIG_HXX diff --git a/NxWidgets/nxwm/src/cnxconsole.cxx b/NxWidgets/nxwm/src/cnxconsole.cxx index a127a8a5a..857b67983 100644 --- a/NxWidgets/nxwm/src/cnxconsole.cxx +++ b/NxWidgets/nxwm/src/cnxconsole.cxx @@ -39,6 +39,19 @@ #include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "cwidgetcontrol.hxx" + #include "nxwmconfig.hxx" #include "cnxconsole.hxx" #include "nxwmglyphs.hxx" @@ -47,6 +60,125 @@ * Pre-Processor Definitions ********************************************************************************************/ +/******************************************************************************************** + * Private Types + ********************************************************************************************/ + +namespace NxWM +{ + /** + * This structure is used to pass start up parameters to nxcon_task and to assure the + * the NxConsole is successfully started. + */ + + struct nxcon_task_s + { + sem_t sem; // Sem that will be posted when the task is successfully initialized + NXTKWINDOW hwnd; // Window handle + NXCONSOLE nxcon; // NxConsole handle + int minor; // Next device minor number + bool result; // True if successfully initialized + }; + +/******************************************************************************************** + * Private Data + ********************************************************************************************/ + + /** + * This global data structure is used to pass start parameters to nxcon_task and to + * assure that the NxConsole is successfully started. + */ + + static struct nxcon_task_s g_nxconvars; + +/******************************************************************************************** + * Private Functions + ********************************************************************************************/ + + /** + * This is the NxConsole task. This function first redirects output to the console window. + */ + + static int nxcon_task(int argc, char *argv[]) + { + // Configure NxConsole + + struct nxcon_window_s wndo; /* Describes the window */ + wndo.wcolor[0] = CONFIG_NXWM_NXCONSOLE_WCOLOR; + wndo.fcolor[0] = CONFIG_NXWM_NXCONSOLE_FONTCOLOR; + wndo.fontid = CONFIG_NXWM_NXCONSOLE_FONTID; + + // To stop compiler complaining about "jump to label crosses initialization of 'int fd' + + int fd = -1; + + // Use the window handle to create the NX console + + g_nxconvars.nxcon = nxtk_register(g_nxconvars.hwnd, &wndo, g_nxconvars.minor); + if (!g_nxconvars.nxcon) + { + goto errout; + } + + // Construct the driver name using this minor number + + char devname[32]; + snprintf(devname, 32, "/dev/nxcon%d", g_nxconvars.minor); + + // Increment the minor number while it is protect by the semaphore + + g_nxconvars.minor++; + + // Open the NxConsole driver + + fd = open(devname, O_WRONLY); + if (fd < 0) + { + goto errout_with_nxcon; + } + + // Now re-direct stdout and stderr so that they use the NX console driver. + // Note that stdin is retained (file descriptor 0, probably the the serial console). + + (void)fflush(stdout); + (void)fflush(stderr); + + (void)fclose(stdout); + (void)fclose(stderr); + + (void)dup2(fd, 1); + (void)dup2(fd, 2); + + // And we can close our original driver file descriptor + + close(fd); + + // Inform the parent thread that we successfully initialize + + g_nxconvars.result = true; + sem_post(&g_nxconvars.sem); + + // Run the NSH console + +#ifdef CONFIG_NSH_CONSOLE + (void)nsh_consolemain(argc, argv); +#endif + + // We get here if console exits +#warning "Missing logic" + return EXIT_SUCCESS; + + errout_with_nxcon: + nxcon_unregister(g_nxconvars.nxcon); + + errout: + g_nxconvars.nxcon = 0; + g_nxconvars.result = false; + sem_post(&g_nxconvars.sem); + return EXIT_FAILURE; + } +} + /******************************************************************************************** * CNxConsole Method Implementations ********************************************************************************************/ @@ -59,8 +191,80 @@ using namespace NxWM; * @param window. The application window */ -CNxConsole::CNxConsole(NXWidgets::INxWindow *window) +CNxConsole::CNxConsole(CTaskbar *taskbar, CApplicationWindow *window) +{ + // Save the constructor data + + m_taskbar = taskbar; + m_window = window; + + // The NxConsole is not runing + + m_pid = -1; + m_nxcon = 0; + + // Add our callbacks to the application window + + window->registerCallbacks(static_cast(this)); +} + +/** + * CNxConsole destructor + * + * @param window. The application window + */ + +CNxConsole::~CNxConsole(void) { + // Although we didn't create it, we are responsible for deleting the + // application window + + if (m_window) + { + delete m_window; + } +} + +/** + * One time NSH initialization. This function must be called exactly + * once during the boot-up sequence to initialize the NSH library. + * + * @return True on successful initialization + */ + +bool nshlibInitialize(void) +{ + // Initialize the global data structure + + sem_init(&g_nxconvars.sem, 0, 0); + + // Initialize the NSH library + + nsh_initialize(); + + // If the Telnet console is selected as a front-end, then start the + // Telnet daemon. + +#ifdef CONFIG_NSH_TELNET + int ret = nsh_telnetstart(); + if (ret < 0) + { + // The daemon is NOT running! + + return false; + } +#endif + return true; +} + +/** + * Each implementation of IApplication must provide a method to recover + * the contained CApplicationWindow instance. + */ + +CApplicationWindow *CNxConsole::getWindow(void) const +{ + return m_window; } /** @@ -73,7 +277,169 @@ CNxConsole::CNxConsole(NXWidgets::INxWindow *window) NXWidgets::IBitmap *CNxConsole::getIcon(void) { - NXWidgets::CRlePaletteBitmap *bitmap = new NXWidgets::CRlePaletteBitmap(&g_nshBitmap); - return static_cast(bitmap); + NXWidgets::CRlePaletteBitmap *bitmap = + new NXWidgets::CRlePaletteBitmap(&g_nshBitmap); + + return bitmap; +} + +/** + * Get the name string associated with the application + * + * @return A copy if CNxString that contains the name of the application. + */ + +NXWidgets::CNxString CNxConsole::getName(void) +{ + return NXWidgets::CNxString("NuttShell"); +} + +/** + * Start the application (perhaps in the minimized state). + * + * @return True if the application was successfully started. + */ + +bool CNxConsole::run(void) +{ + // Some sanity checking + + if (m_pid >= 0 || m_nxcon != 0) + { + return false; + } + + // Recover the NXTK window instance contained in the application window + + NXWidgets::CNxTkWindow *window = m_window->getWindow(); + + // Get the widget control associated with the NXTK window + + NXWidgets::CWidgetControl *control = window->getWidgetControl(); + + // Get the window handle from the widget control + + g_nxconvars.hwnd = control->getWindowHandle(); + + // Start the NxConsole task + + g_nxconvars.result = false; + g_nxconvars.nxcon = 0; + + sched_lock(); + m_pid = TASK_CREATE("NxConsole", CONFIG_NXWM_NXCONSOLE_PRIO, + CONFIG_NXWM_NXCONSOLE_STACKSIZE, nxcon_task, + (FAR const char **)0); + + // Did we successfully start the NxConsole task? + + if (m_pid < 0) + { + return false; + } + + // Wait for up to two second for the task to initialize + + struct timespec abstime; + clock_gettime(CLOCK_REALTIME, &abstime); + abstime.tv_sec += 2; + + int ret = sem_timedwait(&g_nxconvars.sem, &abstime); + if (ret == OK && g_nxconvars.result) + { + // Save the handle to use in the stop method + + m_nxcon = g_nxconvars.nxcon; + return true; + } + else + { + // Stop the application + + stop(); + return false; + } } +/** + * Stop the application. + */ + +void CNxConsole::stop(void) +{ + // Delete the NxConsole task if it is still running (this could strand resources) + + if (m_pid >= 0) + { + task_delete(m_pid); + m_pid = -1; + } + + // Destroy the NX console device + + if (m_nxcon) + { + nxcon_unregister(m_nxcon); + m_nxcon = 0; + } +} + +/** + * The application window is hidden (either it is minimized or it is + * maximized, but not at the top of the hierarchy + */ + +void CNxConsole::hide(void) +{ + // Disable drawing and events +#warning "Missing logic" +} + +/** + * Redraw the entire window. The application has been maximized or + * otherwise moved to the top of the hierarchy. This method is call from + * CTaskbar when the application window must be displayed + */ + +void CNxConsole::redraw(void) +{ + // Recover the NXTK window instance contained in the application window + + NXWidgets::CNxTkWindow *window = m_window->getWindow(); + + // Get the size of the window + + struct nxgl_size_s windowSize; + (void)window->getSize(&windowSize); + + // Redraw the entire NxConsole window + + struct nxgl_rect_s rect; + rect.pt1.x = 0; + rect.pt1.y = 0; + rect.pt2.x = windowSize.w - 1; + rect.pt2.y = windowSize.h - 1; + + nxcon_redraw(m_nxcon, &rect, false); +} + +/** + * Called when the window minimize button is pressed. + */ + +void CNxConsole::minimize(void) +{ + m_taskbar->minimizeApplication(static_cast(this)); +} + +/** + * Called when the window minimize close is pressed. + */ + +void CNxConsole::close(void) +{ + m_taskbar->stopApplication(static_cast(this)); +} + + + diff --git a/NxWidgets/nxwm/src/cstartwindow.cxx b/NxWidgets/nxwm/src/cstartwindow.cxx index 4213c33cb..6949b90db 100644 --- a/NxWidgets/nxwm/src/cstartwindow.cxx +++ b/NxWidgets/nxwm/src/cstartwindow.cxx @@ -70,7 +70,7 @@ CStartWindow::CStartWindow(CTaskbar *taskbar, CApplicationWindow *window) m_taskbar = taskbar; m_window = window; - // Add out callbacks to the application window + // Add our callbacks to the application window window->registerCallbacks(static_cast(this)); } @@ -133,11 +133,15 @@ NXWidgets::CNxString CStartWindow::getName(void) /** * Start the application. + * + * @return True if the application was successfully started. */ -void CStartWindow::run(void) +bool CStartWindow::run(void) { // We don't have a thread of execution. We only respond to button presses + + return true; } /** diff --git a/NxWidgets/nxwm/src/ctaskbar.cxx b/NxWidgets/nxwm/src/ctaskbar.cxx index 3791ee0f6..8d2907266 100644 --- a/NxWidgets/nxwm/src/ctaskbar.cxx +++ b/NxWidgets/nxwm/src/ctaskbar.cxx @@ -267,7 +267,12 @@ bool CTaskbar::startApplication(IApplication *app, bool minimized) // Then start the application (whatever that means) - app->run(); + if (!app->run()) + { + stopApplication(app); + return false; + } + return true; } -- cgit v1.2.3