Add beginning of NxWM NxConsole application

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4681 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2012-05-01 14:52:54 +00:00
parent 289f0a16fe
commit d4f2f57522
9 changed files with 557 additions and 30 deletions

View File

@ -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).

View File

@ -38,6 +38,7 @@
/////////////////////////////////////////////////////////////////////////////
#include <nuttx/config.h>
#include <nuttx/arch.h>
#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:

View File

@ -42,7 +42,13 @@
#include <nuttx/config.h>
#include <sys/types.h>
#include <nuttx/nx/nxtk.h>
#include <nuttx/nx/nxconsole.h>
#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
*/
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 */
~CNxConsole(void);
/**
* Called when the window minimize button is pressed.
*/
public:
/**
* CNxConsole constructor
*
* @param window. The application window
*/
void minimize(void);
CNxConsole(NXWidgets::INxWindow *window);
/**
* Called when the window minimize close is pressed.
*/
/**
* 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.
*/
void close(void);
NXWidgets::IBitmap *getIcon(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

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -39,6 +39,19 @@
#include <nuttx/config.h>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <unistd.h>
#include <fcntl.h>
#include <semaphore.h>
#include <sched.h>
#include <apps/nsh.h>
#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<IApplicationCallback *>(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<NXWidgets::IBitmap *>(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<IApplication*>(this));
}
/**
* Called when the window minimize close is pressed.
*/
void CNxConsole::close(void)
{
m_taskbar->stopApplication(static_cast<IApplication*>(this));
}

View File

@ -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<IApplicationCallback *>(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;
}
/**

View File

@ -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;
}