NxWM: Add IApplicationFactory so that we can create multiple instances of applications; And, as a result of that, re-vamp entire threading model. this is now buggier than it was before

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4742 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2012-05-16 22:43:40 +00:00
parent d21b932f5e
commit b231fb795e
45 changed files with 981 additions and 226 deletions

19
NxWidgets/ChangeLog.txt Executable file → Normal file
View File

@ -90,5 +90,22 @@
* NXWidgets::CNxWidget: Add a new onPreRelease() method.
* NXWidgets::CButton, CButtonArry, CImage now post action event at pre-release time.
* NxWM: ICON touches are now drive by action events instead of click events.
* NXWidgets::CNxTkWindow: Reported size of a framed window must exlude the
* NXWidgets::CNxTkWindow: Reported size of a framed window must exclude the
height of the tool bar (if present)
* TODO.txt: Add a file to keep track of issues.
* NXWidgets::CStartWindow and IApplicationFactory: This is a substantial
redesign. IApplication wraps an application. However, if we want to
be able to start multiple copies of an application, then we need to
be able to create multiple IApplication instances from the start window.
Enter IApplicationFactory. Icons in the start window now correspond
to application factories; icons in the task bar no correspond to
application instances.
* NXWidgetes::CStartWindow and CWindowControl: The above change necessitated
another architectural change: When create applications, it is sometimes
necessary to wait for windows events. The above change moved the
application creation to the window event thread, hence, causing deadlocks
wheneven the logic tried to wait for a window event. The solution was
to create a new thread, called the start window thread, that runs
asynchronously and can wait for windoew events.
* doc/NxWM-ThreadingModel.ppt: Documented the now rather complex NxWM
threading model.

0
NxWidgets/README.txt Executable file → Normal file
View File

0
NxWidgets/ReleaseNotes.txt Executable file → Normal file
View File

23
NxWidgets/TODO.txt Executable file → Normal file
View File

@ -26,13 +26,20 @@ NxWM
Status: Open
Priority: Medium low
Title: MULTIPLE COPIES OF AN APPLICATION
Description: There is a limitation now in that one instance of an application
an be started at a time. This limitation is because the
application container class is created at start-up time; in
order to have multiple instances of tasks, you would have to
be able to create multiple container classes from the start
window.
Title: MULTIPLE COPIES OF AN NxCONSOLE
Description: From the start window, you an create multiple copies of the
NxConsole. However, there is a problem in the current
implementation: Each NxConsole receives its input from the
serial console so, for example, it you enter text one character
will go to one NxConsole instance and the next character goes
to a different instance. That is correct behavior within the
current design, but not very usable. We need a mechanism to
assure that the top window is the one that receives all
eyboard input. NX already provides this capability with its
nx_kbdin interface(), but that is not currently used. At present,
NxConsoles get their input from /dev/console which is the serial
port. The necessary change is to create an NX input device for
/dev/console that will get its input from NX.
Status: Open
Priority: High
Priority: Medium High

0
NxWidgets/UnitTests/CButton/cbutton-pushed.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

0
NxWidgets/UnitTests/CButton/cbutton-released.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

0
NxWidgets/UnitTests/CButtonArray/cbuttonarray.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

0
NxWidgets/UnitTests/CCheckBox/ccheckbox.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

0
NxWidgets/UnitTests/CLabel/clabel.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

0
NxWidgets/UnitTests/CProgressBar/cprogressbar.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

0
NxWidgets/UnitTests/CRadioButton/cradiobutton.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

0
NxWidgets/UnitTests/CTextBox/ctextbox.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

@ -35,8 +35,12 @@ Installing and Building the Unit Tests
for the STM3210E-EVAL available. However, the unit test can be run on
other configurations (see steps d and e below).
NOTE: Another special configuration, sim/nxwm, is recommended for unit-leveling
testing of NxWM because the configuration is more complex in that case.
NOTE: There are some other special configurationsrecommended for unit-leveling
testing of NxWM because the configuration is more complex in that case. These
are:
1) sim/nxwmm, or the simulated platform (no touchscreen), and
2) stm3240g-evel, for the STM3240G-EVAL board (with the STMPE11 touchscreen)
We will assume the sim/nsh2 configuration in this discussion. The
sim/nsh2 configuration is installed as follows:
@ -286,7 +290,7 @@ CTextBox
nxwm
Exercises the NxWM window manager.
Use the special configuration nuttx/configs/sim/nxwm
Use the special configurations nuttx/configs/sim/nxwm or nuttx/configs/stm3240g-eval/nxwm.
Example
=======

0
NxWidgets/UnitTests/TestStatus.txt Executable file → Normal file
View File

View File

@ -83,7 +83,6 @@ struct SNxWmTest
NxWM::CStartWindow *startwindow; // The start window
#ifdef CONFIG_NXWM_TOUCHSCREEN
NxWM::CTouchscreen *touchscreen; // The touchscreen
NxWM::CCalibration *calibration; // The touchscreen calibration application
struct NxWM::SCalibrationData calibData; // Calibration data
#endif
unsigned int mmInitial; // Initial memory usage
@ -250,24 +249,24 @@ static bool createTaskbar(void)
// 3. Call CTaskBar::startApplication repeatedly to add applications to the task bar
// 4. Call CTaskBar::startWindowManager to start the display with applications in place
printf(MAIN_STRING "Create CTaskbar instance\n");
printf("createTaskbar: Create CTaskbar instance\n");
g_nxwmtest.taskbar = new NxWM::CTaskbar();
if (!g_nxwmtest.taskbar)
{
printf(MAIN_STRING "ERROR: Failed to instantiate CTaskbar\n");
printf("createTaskbar: ERROR: Failed to instantiate CTaskbar\n");
return false;
}
showTestCaseMemory("After create taskbar");
showTestCaseMemory("createTaskbar: After create taskbar");
// Connect to the NX server
printf(MAIN_STRING "Connect CTaskbar instance to the NX server\n");
printf("createTaskbar: Connect CTaskbar instance to the NX server\n");
if (!g_nxwmtest.taskbar->connect())
{
printf(MAIN_STRING "ERROR: Failed to connect CTaskbar instance to the NX server\n");
printf("createTaskbar: ERROR: Failed to connect CTaskbar instance to the NX server\n");
return false;
}
showTestCaseMemory("After connecting to the server");
showTestCaseMemory("createTaskbar: After connecting to the server");
// Initialize the task bar
//
@ -275,14 +274,14 @@ static bool createTaskbar(void)
// CTaskBar::startWindowManager() brings the window manager up with those applications
// in place.
printf(MAIN_STRING "Initialize CTaskbar instance\n");
printf("createTaskbar: Initialize CTaskbar instance\n");
if (!g_nxwmtest.taskbar->initWindowManager())
{
printf(MAIN_STRING "ERROR: Failed to intialize CTaskbar instance\n");
printf("createTaskbar: ERROR: Failed to intialize CTaskbar instance\n");
return false;
}
showTestCaseMemory("After initializing window manager");
showTestCaseMemory("createTaskbar: After initializing window manager");
return true;
}
@ -292,55 +291,58 @@ static bool createTaskbar(void)
static bool createStartWindow(void)
{
// Create the start window. The general sequence for setting up the start window is:
// Create the start window. The start window is unique among applications
// because it has no factory. The general sequence for setting up the
// start window is:
//
// 1. Call CTaskBar::openApplicationWindow to create a window for the start window,
// 2. Use the window to instantiate Cstartwindow
// 3. Call Cstartwindow::addApplication numerous times to install applications
// 1. Create and open a CApplicationWindow
// 2. Use the window to create the CStartWindow the start window application
// 2. Call Cstartwindow::addApplication numerous times to install applications
// in the start window.
// 4. Call CTaskBar::startApplication (initially minimized) to start the start
// 3. Call CTaskBar::startApplication (initially minimized) to start the start
// window application.
//
// NOTE: that the start window should not have a stop button.
printf(MAIN_STRING "Opening the start window application window\n");
NxWM::CApplicationWindow *window = g_nxwmtest.taskbar->openApplicationWindow(NxWM::CApplicationWindow::WINDOW_PERSISTENT);
if (!window)
{
printf(MAIN_STRING "ERROR: Failed to create CApplicationWindow for the start window\n");
printf("createStartWindow: ERROR: Failed to create CApplicationWindow\n");
return false;
}
showTestCaseMemory("After creating start window application window");
showTestCaseMemory("createStartWindow: After creating CApplicationWindow");
// Open the window (it is hot in here)
printf(MAIN_STRING "Initialize CApplicationWindow\n");
if (!window->open())
{
printf(MAIN_STRING "ERROR: Failed to open CApplicationWindow \n");
printf("createStartWindow: ERROR: Failed to open CApplicationWindow \n");
delete window;
return false;
}
showTestCaseMemory("After initializing the start window application window");
showTestCaseMemory("createStartWindow: After opening CApplicationWindow");
// Instantiate the application, providing the window to the application's
// constructor
printf(MAIN_STRING "Creating the start window application\n");
g_nxwmtest.startwindow = new NxWM::CStartWindow(g_nxwmtest.taskbar, window);
if (!g_nxwmtest.startwindow)
{
printf(MAIN_STRING "ERROR: Failed to instantiate CStartWindow\n");
gdbg("ERROR: Failed to instantiate CStartWindow\n");
delete window;
return false;
}
showTestCaseMemory("createStartWindow: After creating CStartWindow");
// Call CTaskBar::startApplication to start the Calibration application (minimized)
// Add the CStartWindow application to the task bar (minimized)
printf(MAIN_STRING "Start the start window application\n");
printf("createStartWindow: Start the start window application\n");
if (!g_nxwmtest.taskbar->startApplication(g_nxwmtest.startwindow, true))
{
printf(MAIN_STRING "ERROR: Failed to start the start window application\n");
printf("createStartWindow: ERROR: Failed to start the start window application\n");
return false;
}
showTestCaseMemory("After starting the start window application");
showTestCaseMemory("After create the start window application");
showTestCaseMemory("createStartWindow: After starting the start window application");
return true;
}
@ -352,14 +354,14 @@ static bool startWindowManager(void)
{
// Start the window manager
printf(MAIN_STRING "Start the window manager\n");
printf("startWindowManager: Start the window manager\n");
if (!g_nxwmtest.taskbar->startWindowManager())
{
printf(MAIN_STRING "ERROR: Failed to start the window manager\n");
printf("startWindowManager: ERROR: Failed to start the window manager\n");
return false;
}
showTestCaseMemory("After starting the window manager");
showTestCaseMemory("AstartWindowManager: fter starting the window manager");
return true;
}
@ -377,23 +379,24 @@ static bool createTouchScreen(void)
// Create the touchscreen device
printf(MAIN_STRING "Creating CTouchscreen\n");
printf("createTouchScreen: Creating CTouchscreen\n");
g_nxwmtest.touchscreen = new NxWM::CTouchscreen(g_nxwmtest.taskbar, &displaySize);
if (!g_nxwmtest.touchscreen)
{
printf(MAIN_STRING "ERROR: Failed to create CTouchscreen\n");
printf("createTouchScreen: ERROR: Failed to create CTouchscreen\n");
return false;
}
showTestCaseMemory("createTouchScreen: createTouchScreen: After creating CTouchscreen");
printf(MAIN_STRING "Start touchscreen listener\n");
printf("createTouchScreen: Start touchscreen listener\n");
if (!g_nxwmtest.touchscreen->start())
{
printf(MAIN_STRING "ERROR: Failed start the touchscreen listener\n");
printf("createTouchScreen: ERROR: Failed start the touchscreen listener\n");
delete g_nxwmtest.touchscreen;
return false;
}
showTestCaseMemory("After starting the touchscreen listener");
showTestCaseMemory("createTouchScreen: After starting the touchscreen listener");
return true;
}
#endif
@ -405,61 +408,50 @@ static bool createTouchScreen(void)
#ifdef CONFIG_NXWM_TOUCHSCREEN
static bool createCalibration(void)
{
// 1. Call CTaskBar::openFullScreenWindow to create a window for the application,
// 2. Instantiate the application, providing the window to the application's
// constructor,
// 1Create the CCalibrationFactory application factory
printf(MAIN_STRING "Opening the calibration application window\n");
NxWM::CFullScreenWindow *window = g_nxwmtest.taskbar->openFullScreenWindow();
if (!window)
printf("createCalibration: Creating CCalibrationFactory\n");
NxWM::CCalibrationFactory *factory = new NxWM::CCalibrationFactory(g_nxwmtest.taskbar, g_nxwmtest.touchscreen);
if (!factory)
{
printf(MAIN_STRING "ERROR: Failed to create CFullScreenWindow for the calibration window\n");
printf("createCalibration: ERROR: Failed to create CCalibrationFactory\n");
return false;
}
showTestCaseMemory("After creating calibration full screen window");
showTestCaseMemory("createCalibration: After creating CCalibrationFactory");
printf(MAIN_STRING "Initialize CFullScreenWindow\n");
if (!window->open())
// Add the calibration application to the start window.
printf("createCalibration: Adding CCalibration to the start window\n");
if (!g_nxwmtest.startwindow->addApplication(factory))
{
printf(MAIN_STRING "ERROR: Failed to open CFullScreenWindow \n");
delete window;
printf("createCalibration: ERROR: Failed to add CCalibrationto the start window\n");
delete factory;
return false;
}
showTestCaseMemory("After initializing the calibration full screen window");
showTestCaseMemory("createCalibration: After adding CCalibration");
printf(MAIN_STRING "Creating CCalibration application\n");
g_nxwmtest.calibration = new NxWM::CCalibration(g_nxwmtest.taskbar, window, g_nxwmtest.touchscreen);
if (!g_nxwmtest.calibration)
// Call StartWindowFactory::create to to create the start window application
printf("createCalibration: Creating CCalibration\n");
NxWM::IApplication *calibration = factory->create();
if (!calibration)
{
printf(MAIN_STRING "ERROR: Failed to instantiate CCalibration\n");
delete window;
printf("createCalibration: ERROR: Failed to create CCalibration\n");
return false;
}
showTestCaseMemory("After creating CCalibration application");
// Add the calibration application to the start window. It can't really
// be used to re-calibrate (because there is nothing to get the calibration
// data). But is a good case to test a full screen appliation
printf(MAIN_STRING "Adding CCalibration application to the start window\n");
if (!g_nxwmtest.startwindow->addApplication(g_nxwmtest.calibration))
{
printf(MAIN_STRING "ERROR: Failed to add CCalibration to the start window\n");
delete g_nxwmtest.calibration;
return false;
}
showTestCaseMemory("After adding CCalibration application");
showTestCaseMemory("createCalibration: After creating CCalibration");
// Call CTaskBar::startApplication to start the Calibration application. Nothing
// will be displayed because the window manager has not yet been started.
printf(MAIN_STRING "Start the calibration application\n");
if (!g_nxwmtest.taskbar->startApplication(g_nxwmtest.calibration, false))
printf("createCalibration: Start the calibration application\n");
if (!g_nxwmtest.taskbar->startApplication(calibration, false))
{
printf(MAIN_STRING "ERROR: Failed to start the calibration application\n");
delete calibration;
return false;
}
showTestCaseMemory("After starting the start window application");
showTestCaseMemory("createCalibration: After starting the start window application");
return true;
}
#endif
@ -472,43 +464,24 @@ static bool createNxConsole(void)
{
// Add the NxConsole application to the start window
printf(MAIN_STRING "Opening the NxConsole application window\n");
NxWM::CApplicationWindow *window = g_nxwmtest.taskbar->openApplicationWindow();
if (!window)
{
printf(MAIN_STRING "ERROR: Failed to create CApplicationWindow for the NxConsole\n");
return false;
}
showTestCaseMemory("After creating the NxConsole application window");
printf(MAIN_STRING "Initialize CApplicationWindow\n");
if (!window->open())
{
printf(MAIN_STRING "ERROR: Failed to open CApplicationWindow \n");
delete window;
return false;
}
showTestCaseMemory("After initializing the NxConsole application window");
printf(MAIN_STRING "Creating the NxConsole application\n");
NxWM::CNxConsole *console = new NxWM::CNxConsole(g_nxwmtest.taskbar, window);
printf("createNxConsole: Creating the NxConsole application\n");
NxWM::CNxConsoleFactory *console = new NxWM::CNxConsoleFactory(g_nxwmtest.taskbar);
if (!console)
{
printf(MAIN_STRING "ERROR: Failed to instantiate CNxConsole\n");
delete window;
printf("createNxConsole: ERROR: Failed to instantiate CNxConsoleFactory\n");
return false;
}
showTestCaseMemory("After creating the NxConsole application");
showTestCaseMemory("createNxConsole: After creating the NxConsole application");
printf(MAIN_STRING "Adding the NxConsole application to the start window\n");
printf("createNxConsole: Adding the NxConsole application to the start window\n");
if (!g_nxwmtest.startwindow->addApplication(console))
{
printf(MAIN_STRING "ERROR: Failed to add CNxConsole to the start window\n");
printf("createNxConsole: ERROR: Failed to add CNxConsoleFactory to the start window\n");
delete console;
return false;
}
showTestCaseMemory("After adding the NxConsole application");
showTestCaseMemory("createNxConsole: After adding the NxConsole application");
return true;
}
@ -557,7 +530,7 @@ int MAIN_NAME(int argc, char *argv[])
printf(MAIN_STRING "ERROR: Failed to initialize the NSH library\n");
return EXIT_FAILURE;
}
showTestCaseMemory("After initializing the NSH library");
showTestCaseMemory(MAIN_STRING "After initializing the NSH library");
// Create the task bar.
@ -641,20 +614,20 @@ int MAIN_NAME(int argc, char *argv[])
#ifndef CONFIG_NXWM_TOUCHSCREEN
sleep(2);
g_nxwmtest.taskbar->clickIcon(0);
showTestCaseMemory("After clicking the start window icon");
showTestCaseMemory(MAIN_STRING "After clicking the start window icon");
// Wait bit to see the result of the button press. The press the first icon
// in the start menu. That should be the NxConsole icon.
sleep(2);
g_nxwmtest.startwindow->clickIcon(0);
showTestCaseMemory("After clicking the NxConsole icon");
showTestCaseMemory(MAIN_STRING "After clicking the NxConsole icon");
#endif
// Wait bit to see the result of the button press.
sleep(2);
showTestMemory("Final memory usage");
showTestMemory(MAIN_STRING "Final memory usage");
return EXIT_SUCCESS;
}

View File

@ -346,7 +346,7 @@ namespace NXWidgets
* Destructor.
*/
~CWidgetControl(void);
virtual ~CWidgetControl(void);
/**
* Wait for an interesting window event to occur (like a mouse or keyboard event)

View File

@ -143,7 +143,7 @@ CWidgetControl::CWidgetControl(FAR const CWidgetStyle *style)
CWidgetControl::~CWidgetControl(void)
{
// Notify any external waiters... this should not happen becaue it
// Notify any external waiters... this should not happen because it
// it is probably already too late
#ifdef CONFIG_NXWIDGET_EVENTWAIT
@ -432,6 +432,7 @@ void CWidgetControl::geometryEvent(NXHANDLE hWindow,
void CWidgetControl::redrawEvent(FAR const struct nxgl_rect_s *nxRect, bool more)
{
// REVISIT. This is not not yet used and not fully implemented.
CRect rect;
rect.setNxRect(nxRect);
m_eventHandlers.raiseRedrawEvent();

View File

@ -125,7 +125,7 @@ void CWidgetEventHandlerList::addWidgetEventHandler(CWidgetEventHandler *eventHa
{
// Prevent insertion if the handler already exists
for (int i = 0; i < m_widgetEventHandlers.size(); ++i)
for (int i = 0; i < m_widgetEventHandlers.size(); i++)
{
if (m_widgetEventHandlers.at(i) == eventHandler)
{
@ -146,7 +146,7 @@ void CWidgetEventHandlerList::addWidgetEventHandler(CWidgetEventHandler *eventHa
void CWidgetEventHandlerList::removeWidgetEventHandler(CWidgetEventHandler *eventHandler)
{
for (int i = 0; i < m_widgetEventHandlers.size(); ++i)
for (int i = 0; i < m_widgetEventHandlers.size(); i++)
{
if (m_widgetEventHandlers.at(i) == eventHandler)
{
@ -169,7 +169,7 @@ void CWidgetEventHandlerList::raiseClickEvent(nxgl_coord_t x, nxgl_coord_t y)
{
CWidgetEventArgs e(m_widget, x, y, 0, 0, KEY_CODE_NONE);
for (int i = 0; i < m_widgetEventHandlers.size(); ++i)
for (int i = 0; i < m_widgetEventHandlers.size(); i++)
{
m_widgetEventHandlers.at(i)->handleClickEvent(e);
}
@ -189,7 +189,7 @@ void CWidgetEventHandlerList::raiseDoubleClickEvent(nxgl_coord_t x, nxgl_coord_t
{
CWidgetEventArgs e(m_widget, x, y, 0, 0, KEY_CODE_NONE);
for (int i = 0; i < m_widgetEventHandlers.size(); ++i)
for (int i = 0; i < m_widgetEventHandlers.size(); i++)
{
m_widgetEventHandlers.at(i)->handleDoubleClickEvent(e);
}
@ -209,7 +209,7 @@ void CWidgetEventHandlerList::raiseReleaseEvent(nxgl_coord_t x, nxgl_coord_t y)
{
CWidgetEventArgs e(m_widget, x, y, 0, 0, KEY_CODE_NONE);
for (int i = 0; i < m_widgetEventHandlers.size(); ++i)
for (int i = 0; i < m_widgetEventHandlers.size(); i++)
{
m_widgetEventHandlers.at(i)->handleReleaseEvent(e);
}
@ -229,7 +229,7 @@ void CWidgetEventHandlerList::raiseReleaseOutsideEvent(nxgl_coord_t x, nxgl_coor
{
CWidgetEventArgs e(m_widget, x, y, 0, 0, KEY_CODE_NONE);
for (int i = 0; i < m_widgetEventHandlers.size(); ++i)
for (int i = 0; i < m_widgetEventHandlers.size(); i++)
{
m_widgetEventHandlers.at(i)->handleReleaseOutsideEvent(e);
}
@ -252,7 +252,7 @@ void CWidgetEventHandlerList::raiseDragEvent(nxgl_coord_t x, nxgl_coord_t y,
{
CWidgetEventArgs e(m_widget, x, y, vX, vY, KEY_CODE_NONE);
for (int i = 0; i < m_widgetEventHandlers.size(); ++i)
for (int i = 0; i < m_widgetEventHandlers.size(); i++)
{
m_widgetEventHandlers.at(i)->handleDragEvent(e);
}
@ -272,7 +272,7 @@ void CWidgetEventHandlerList::raiseDropEvent(nxgl_coord_t x, nxgl_coord_t y)
{
CWidgetEventArgs e(m_widget, x, y, 0, 0, KEY_CODE_NONE);
for (int i = 0; i < m_widgetEventHandlers.size(); ++i)
for (int i = 0; i < m_widgetEventHandlers.size(); i++)
{
m_widgetEventHandlers.at(i)->handleDropEvent(e);
}
@ -291,7 +291,7 @@ void CWidgetEventHandlerList::raiseKeyPressEvent(nxwidget_char_t key)
{
CWidgetEventArgs e(m_widget, 0, 0, 0, 0, key);
for (int i = 0; i < m_widgetEventHandlers.size(); ++i)
for (int i = 0; i < m_widgetEventHandlers.size(); i++)
{
m_widgetEventHandlers.at(i)->handleKeyPressEvent(e);
}
@ -310,7 +310,7 @@ void CWidgetEventHandlerList::raiseCursorControlEvent(ECursorControl cursorContr
{
CWidgetEventArgs e(m_widget, 0, 0, 0, 0, (nxwidget_char_t)cursorControl);
for (int i = 0; i < m_widgetEventHandlers.size(); ++i)
for (int i = 0; i < m_widgetEventHandlers.size(); i++)
{
m_widgetEventHandlers.at(i)->handleCursorControlEvent(e);
}
@ -327,7 +327,7 @@ void CWidgetEventHandlerList::raiseFocusEvent(void)
{
CWidgetEventArgs e(m_widget, 0, 0, 0, 0, KEY_CODE_NONE);
for (int i = 0; i < m_widgetEventHandlers.size(); ++i)
for (int i = 0; i < m_widgetEventHandlers.size(); i++)
{
m_widgetEventHandlers.at(i)->handleFocusEvent(e);
}
@ -344,7 +344,7 @@ void CWidgetEventHandlerList::raiseBlurEvent(void)
{
CWidgetEventArgs e(m_widget, 0, 0, 0, 0, KEY_CODE_NONE);
for (int i = 0; i < m_widgetEventHandlers.size(); ++i)
for (int i = 0; i < m_widgetEventHandlers.size(); i++)
{
m_widgetEventHandlers.at(i)->handleBlurEvent(e);
}
@ -361,7 +361,7 @@ void CWidgetEventHandlerList::raiseCloseEvent(void)
{
CWidgetEventArgs e(m_widget, 0, 0, 0, 0, KEY_CODE_NONE);
for (int i = 0; i < m_widgetEventHandlers.size(); ++i)
for (int i = 0; i < m_widgetEventHandlers.size(); i++)
{
m_widgetEventHandlers.at(i)->handleCloseEvent(e);
}
@ -378,7 +378,7 @@ void CWidgetEventHandlerList::raiseHideEvent(void)
{
CWidgetEventArgs e(m_widget, 0, 0, 0, 0, KEY_CODE_NONE);
for (int i = 0; i < m_widgetEventHandlers.size(); ++i)
for (int i = 0; i < m_widgetEventHandlers.size(); i++)
{
m_widgetEventHandlers.at(i)->handleHideEvent(e);
}
@ -395,7 +395,7 @@ void CWidgetEventHandlerList::raiseShowEvent(void)
{
CWidgetEventArgs e(m_widget, 0, 0, 0, 0, KEY_CODE_NONE);
for (int i = 0; i < m_widgetEventHandlers.size(); ++i)
for (int i = 0; i < m_widgetEventHandlers.size(); i++)
{
m_widgetEventHandlers.at(i)->handleShowEvent(e);
}
@ -412,7 +412,7 @@ void CWidgetEventHandlerList::raiseEnableEvent(void)
{
CWidgetEventArgs e(m_widget, 0, 0, 0, 0, KEY_CODE_NONE);
for (int i = 0; i < m_widgetEventHandlers.size(); ++i)
for (int i = 0; i < m_widgetEventHandlers.size(); i++)
{
m_widgetEventHandlers.at(i)->handleEnableEvent(e);
}
@ -429,7 +429,7 @@ void CWidgetEventHandlerList::raiseDisableEvent(void)
{
CWidgetEventArgs e(m_widget, 0, 0, 0, 0, KEY_CODE_NONE);
for (int i = 0; i < m_widgetEventHandlers.size(); ++i)
for (int i = 0; i < m_widgetEventHandlers.size(); i++)
{
m_widgetEventHandlers.at(i)->handleDisableEvent(e);
}
@ -446,7 +446,7 @@ void CWidgetEventHandlerList::raiseValueChangeEvent(void)
{
CWidgetEventArgs e(m_widget, 0, 0, 0, 0, KEY_CODE_NONE);
for (int i = 0; i < m_widgetEventHandlers.size(); ++i)
for (int i = 0; i < m_widgetEventHandlers.size(); i++)
{
m_widgetEventHandlers.at(i)->handleValueChangeEvent(e);
}
@ -466,7 +466,7 @@ void CWidgetEventHandlerList::raiseResizeEvent(nxgl_coord_t width, nxgl_coord_t
{
CWidgetEventArgs e(m_widget, 0, 0, 0, 0, KEY_CODE_NONE);
for (int i = 0; i < m_widgetEventHandlers.size(); ++i)
for (int i = 0; i < m_widgetEventHandlers.size(); i++)
{
m_widgetEventHandlers.at(i)->handleResizeEvent(e);
}
@ -489,7 +489,7 @@ void CWidgetEventHandlerList::raiseMoveEvent(nxgl_coord_t x, nxgl_coord_t y,
{
CWidgetEventArgs e(m_widget, x, y, vX, vY, KEY_CODE_NONE);
for (int i = 0; i < m_widgetEventHandlers.size(); ++i)
for (int i = 0; i < m_widgetEventHandlers.size(); i++)
{
m_widgetEventHandlers.at(i)->handleMoveEvent(e);
}
@ -510,7 +510,7 @@ void CWidgetEventHandlerList::raiseActionEvent(void)
{
CWidgetEventArgs e(m_widget, 0, 0, 0, 0, KEY_CODE_NONE);
for (int i = 0; i < m_widgetEventHandlers.size(); ++i)
for (int i = 0; i < m_widgetEventHandlers.size(); i++)
{
m_widgetEventHandlers.at(i)->handleActionEvent(e);
}
@ -530,7 +530,7 @@ void CWidgetEventHandlerList::raiseScrollEvent(nxgl_coord_t vX, nxgl_coord_t vY)
{
CWidgetEventArgs e(m_widget, 0, 0, vX, vY, KEY_CODE_NONE);
for (int i = 0; i < m_widgetEventHandlers.size(); ++i)
for (int i = 0; i < m_widgetEventHandlers.size(); i++)
{
m_widgetEventHandlers.at(i)->handleScrollEvent(e);
}

View File

@ -159,3 +159,4 @@ void CWindowEventHandlerList::raiseKeyboardEvent(void)
}
#endif
}

Binary file not shown.

View File

@ -150,6 +150,14 @@ namespace NxWM
NXWidgets::INxWindow *getWindow(void) const;
/**
* Recover the contained window control
*
* @return. The window control used by this application
*/
CWindowControl *getWindowControl(void) const ;
/**
* Set the window label
*

View File

@ -314,6 +314,46 @@ namespace NxWM
bool isFullScreen(void) const;
};
class CCalibrationFactory : public IApplicationFactory
{
private:
CTaskbar *m_taskbar; /**< The taskbar */
CTouchscreen *m_touchscreen; /**< The touchscreen device */
public:
/**
* CCalibrationFactory Constructor
*
* @param taskbar. The taskbar instance used to terminate calibration
* @param touchscreen. An instance of the class that wraps the
* touchscreen device.
*/
CCalibrationFactory(CTaskbar *taskbar, CTouchscreen *touchscreen);
/**
* CCalibrationFactory Destructor
*/
inline ~CCalibrationFactory(void) { }
/**
* Create a new instance of an CCalibration (as IApplication).
*/
IApplication *create(void);
/**
* 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);
};
}
#endif // __INCLUDE_CCALIBRATION_HXX

View File

@ -114,6 +114,14 @@ namespace NxWM
NXWidgets::INxWindow *getWindow(void) const;
/**
* Recover the contained window control
*
* @return. The window control used by this application
*/
CWindowControl *getWindowControl(void) const;
/**
* Set the window label
*

View File

@ -191,6 +191,43 @@ namespace NxWM
bool isFullScreen(void) const;
};
class CNxConsoleFactory : public IApplicationFactory
{
private:
CTaskbar *m_taskbar; /**< The taskbar */
public:
/**
* CNxConsoleFactory Constructor
*
* @param taskbar. The taskbar instance used to terminate calibration
*/
CNxConsoleFactory(CTaskbar *taskbar);
/**
* CNxConsoleFactory Destructor
*/
inline ~CNxConsoleFactory(void) { }
/**
* Create a new instance of an CNxConsole (as IApplication).
*/
IApplication *create(void);
/**
* 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);
};
}
#endif // __cplusplus

View File

@ -42,6 +42,8 @@
#include <nuttx/config.h>
#include <debug.h>
#include "tnxarray.hxx"
#include "iapplication.hxx"
@ -59,8 +61,35 @@
namespace NxWM
{
/**
* Forward references
*/
class CTaskbar;
/**
* Start window message opcodes and format
*/
enum EStartWindowMessageOpcodes
{
MSGID_POSITIONAL_CHANGE = 1, /**< Change in window positional data (not used) */
MSGID_REDRAW_REQUEST, /**< Request to redraw a portion of the window (not used) */
MSGID_MOUSE_INPUT, /**< New mouse input is available */
MSGID_KEYBOARD_INPUT, /**< New keyboard input is available */
MSGID_DESTROY_APP /**< Destroy the application */
};
struct SStartWindowMessage
{
enum EStartWindowMessageOpcodes msgId; /**< The message opcode */
FAR void *instance; /**< Object instance. */
};
/**
* This class is the the start window application.
*/
class CStartWindow : public IApplication,
private IApplicationCallback,
private NXWidgets::CWidgetEventHandler
@ -72,7 +101,7 @@ namespace NxWM
struct SStartWindowSlot
{
IApplication *app; /**< A reference to the icon */
IApplicationFactory *app; /**< A reference to the icon */
NXWidgets::CImage *image; /**< The icon image that goes with the application */
};
@ -84,6 +113,33 @@ namespace NxWM
CApplicationWindow *m_window; /**< Reference to the application window */
TNxArray<struct SStartWindowSlot> m_slots; /**< List of apps in the start window */
struct nxgl_size_s m_iconSize; /**< A box big enough to hold the largest icon */
pid_t m_taskId; /**< ID of the start window task */
/**
* This is the start window task. This function receives window events from
* the NX listener threads indirectly through this sequence:
*
* 1. The NX listener thread receives a windows event. The NX listener thread
* which is part of CTaskBar and was created when NX server connection was
* established). This event may be a positional change notification, a
* redraw request, or mouse or keyboard input.
* 2. The NX listener thread handles the message by calling nx_eventhandler().
* nx_eventhandler() dispatches the message by calling a method in the
* NXWidgets::CCallback instance associated with the window.
* NXWidgets::CCallback is a part of the CWidgetControl.
* 3. NXWidgets::CCallback calls into NXWidgets::CWidgetControl to process
* the event.
* 4. NXWidgets::CWidgetControl records the new state data and raises a
* window event.
* 5. NXWidgets::CWindowEventHandlerList will give the event to
* NxWM::CWindowControl.
* 6. NxWM::CWindowControl will send the a message on a well-known message
* queue.
* 7. This CStartWindow::startWindow task will receive and process that
* message.
*/
static int startWindow(int argc, char *argv[]);
/**
* Called when the window minimize button is pressed.
@ -107,7 +163,7 @@ namespace NxWM
* Stop all applications
*/
void stopAllApplications(void);
void removeAllApplications(void);
/**
* Handle a widget action event. For CImage, this is a mouse button pre-release event.
@ -202,18 +258,15 @@ namespace NxWM
* Add the application to the start window. The general sequence for
* setting up the start window is:
*
* 1. Call CTaskBar::openApplicationWindow to create a window for the start window,
* 2. Use the window to instantiate CStartWindow
* 3. Call CStartWindow::addApplication numerous times to install applications
* in the start window.
* 4. Call CTaskBar::startApplication (initially minimized) to start the start
* window application.
* 1. Call IAppicationFactory::create to a new instance of the application
* 2. Call CStartWindow::addApplication to add the application to the
* start window.
*
* @param app. The new application to add to the start window
* @return true on success
*/
bool addApplication(IApplication *app);
bool addApplication(IApplicationFactory *app);
/**
* Simulate a mouse click on the icon at index. This inline method is only

View File

@ -43,6 +43,8 @@
#include <nuttx/config.h>
#include <sys/types.h>
#include <mqueue.h>
#include <nuttx/nx/nxtk.h>
#include <nuttx/nx/nxconsole.h>
@ -61,6 +63,12 @@
namespace NxWM
{
/**
* Forward references.
*/
class IApplication;
/**
* The class CWindowControl integrates the widget control with some special
* handling of mouse and keyboard inputs neesed by NxWM
@ -70,6 +78,9 @@ namespace NxWM
private NXWidgets::CWindowEventHandler
{
private:
mqd_t m_mqd; /**< Message queue descriptor used to commincate with the
** start window thread. */
/**
* Handle an NX window mouse input event.
*
@ -105,6 +116,16 @@ namespace NxWM
*/
~CWindowControl(void);
/**
* Destroy the application window and everything in it. This is
* handled by CWindowControl (vs just calling the destructors) because
* in the case where an application destroys itself (because of pressing
* the stop button), then we need to unwind and get out of the application
* logic before destroying all of its objects.
*/
void destroy(IApplication *app);
};
}
#endif // __cplusplus

View File

@ -44,6 +44,8 @@
#include "cnxstring.hxx"
#include "ibitmap.hxx"
#include "cwindowcontrol.hxx"
#include "capplicationwindow.hxx"
/****************************************************************************
@ -65,14 +67,25 @@ namespace NxWM
class IApplication
{
protected:
// These values (and the accessors that go with them) violate the "purity"
// of the base class. These are really part of the task bar implementation:
// Each application provides this state information needed by the taskbar.
/**
* These values (and the accessors that go with them) violate the "purity"
* of the base class. These are really part of the task bar implementation:
* Each application provides this state information needed by the taskbar.
*/
bool m_minimized; /**< True if the application is minimized */
bool m_topapp; /**< True if this application is at the top in the hiearchy */
public:
/**
* A virtual destructor is required in order to override the IApplication
* destructor. We do this because if we delete IApplication, we want the
* destructor of the class that inherits from IApplication to run, not this
* one.
*/
virtual ~IApplication(void) { }
/**
* Each implementation of IApplication must provide a method to recover
* the contained CApplicationWindow instance.
@ -80,6 +93,18 @@ namespace NxWM
virtual IApplicationWindow *getWindow(void) const = 0;
/**
* Get the window widget control.
*
* @return The widget control of the underlying window instance.
*/
virtual inline CWindowControl *getWindowControl(void) const
{
IApplicationWindow *window = getWindow();
return window->getWindowControl();
}
/**
* Get the icon associated with the application
*
@ -181,6 +206,31 @@ namespace NxWM
virtual bool isFullScreen(void) const = 0;
};
/**
* IApplicationFactory provides a mechanism for creating multiple instances
* of an application.
*/
class IApplicationFactory
{
public:
/**
* Create a new instance of an application.
*/
virtual IApplication *create(void) = 0;
/**
* 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.
*/
virtual NXWidgets::IBitmap *getIcon(void) = 0;
};
}
#endif // __cplusplus

View File

@ -42,13 +42,10 @@
#include <nuttx/config.h>
#include "cnxtkwindow.hxx"
#include "cnxtoolbar.hxx"
#include "cwidgeteventargs.hxx"
#include "cwidgeteventhandler.hxx"
#include "cimage.hxx"
#include "clabel.hxx"
#include "crlepalettebitmap.hxx"
#include "inxwindow.hxx"
#include "cnxstring.hxx"
#include "cwindowcontrol.hxx"
/****************************************************************************
* Pre-Processor Definitions
@ -121,6 +118,14 @@ namespace NxWM
virtual NXWidgets::INxWindow *getWindow(void) const = 0;
/**
* Recover the contained window control
*
* @return. The window control used by this application
*/
virtual CWindowControl *getWindowControl(void) const = 0;
/**
* Set the window label
*

View File

@ -263,6 +263,19 @@
* CONFIG_NXWM_STARTWINDOW_VSPACING - Vertical spacing. Default: 2 pixels
* CONFIG_NXWM_STARTWINDOW_HSPACING - Horizontal spacing. Default: 2 rows
* CONFIG_NXWM_STARTWINDOW_ICON - The glyph to use as the start window icon
* CONFIG_NXWM_STARTWINDOW_MQNAME - The well known name of the message queue
* Used to communicated from CWindowControl tothe start window thread.
* Default: "/dev/nxwm"
* CONFIG_NXWM_STARTWINDOW_MXMSGS - The maximum number of messages to queue
* before blocking. Defualt 32
* CONFIG_NXWM_STARTWINDOW_MXMPRIO - The message priority. Default: 42.
* CONFIG_NXWM_STARTWINDOW_PRIO - Priority of the NxConsole task. Default:
* SCHED_PRIORITY_DEFAULT. NOTE: This priority should be less than
* CONFIG_NXWIDGETS_SERVERPRIO or else there may be data overrun errors.
* Such errors would most likely appear as duplicated rows of data on the
* display.
* CONFIG_NXWM_STARTWINDOW_STACKSIZE - The stack size to use when starting the
* NxConsole task. Default: 2048 bytes.
*/
#ifndef CONFIG_NXWM_STARTWINDOW_VSPACING
@ -281,6 +294,39 @@
# define CONFIG_NXWM_STARTWINDOW_ICON NxWM::g_playBitmap
#endif
/**
* Start window task parameters
*/
#ifndef CONFIG_NXWM_STARTWINDOW_MQNAME
# define CONFIG_NXWM_STARTWINDOW_MQNAME "/dev/nxwm"
#endif
#ifndef CONFIG_NXWM_STARTWINDOW_MXMSGS
# ifdef CONFIG_NX_MXCLIENTMSGS
# define CONFIG_NXWM_STARTWINDOW_MXMSGS CONFIG_NX_MXCLIENTMSGS
# else
# define CONFIG_NXWM_STARTWINDOW_MXMSGS 32
# endif
#endif
#ifndef CONFIG_NXWM_STARTWINDOW_MXMPRIO
# define CONFIG_NXWM_STARTWINDOW_MXMPRIO 42
#endif
#ifndef CONFIG_NXWM_STARTWINDOW_PRIO
# define CONFIG_NXWM_STARTWINDOW_PRIO SCHED_PRIORITY_DEFAULT
#endif
#if CONFIG_NXWIDGETS_SERVERPRIO <= CONFIG_NXWM_STARTWINDOW_PRIO
# warning "CONFIG_NXWIDGETS_SERVERPRIO <= CONFIG_NXWM_STARTWINDOW_PRIO"
# warning" -- This can result in data overrun errors"
#endif
#ifndef CONFIG_NXWM_STARTWINDOW_STACKSIZE
# define CONFIG_NXWM_STARTWINDOW_STACKSIZE 2048
#endif
/* NxConsole Window *********************************************************/
/**
* NxConsole Window Configuration
@ -347,7 +393,7 @@
* CONFIG_NXWM_TOUCHSCREEN_LISTENERPRIO - Priority of the touchscreen listener
* thread. Default: SCHED_PRIORITY_DEFAULT
* CONFIG_NXWM_TOUCHSCREEN_LISTENERSTACK - Touchscreen listener thread stack
* size. Default 2048
* size. Default 1024
*/
#ifndef CONFIG_NXWM_TOUCHSCREEN_DEVNO
@ -367,7 +413,7 @@
#endif
#ifndef CONFIG_NXWM_TOUCHSCREEN_LISTENERSTACK
# define CONFIG_NXWM_TOUCHSCREEN_LISTENERSTACK 2048
# define CONFIG_NXWM_TOUCHSCREEN_LISTENERSTACK 1024
#endif
/* Calibration display ******************************************************/

View File

@ -413,6 +413,18 @@ NXWidgets::INxWindow *CApplicationWindow::getWindow(void) const
return static_cast<NXWidgets::INxWindow*>(m_window);
}
/**
* Recover the contained window control
*
* @return. The window control used by this application
*/
CWindowControl *CApplicationWindow::getWindowControl(void) const
{
NXWidgets::CWidgetControl *control = m_window->getWidgetControl();
return static_cast<CWindowControl*>(control);
}
/**
* Set the window label
*

View File

@ -1,5 +1,5 @@
/****************************************************************************
* NxWidgets/nxwm/src/capplicationwindow.cxx
* NxWidgets/nxwm/src/ccalibration.cxx
*
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
@ -107,6 +107,11 @@ CCalibration::CCalibration(CTaskbar *taskbar, CFullScreenWindow *window,
CCalibration::~CCalibration(void)
{
// Make sure that the application is not running (it should already
// have been stopped)
stop();
// Although we did not create the window, the rule is that I have to dispose
// of it
@ -788,4 +793,71 @@ bool CCalibration::createCalibrationData(struct SCalibrationData &data)
return true;
}
/**
* CCalibrationFactory Constructor
*
* @param taskbar. The taskbar instance used to terminate calibration
* @param touchscreen. An instance of the class that wraps the
* touchscreen device.
*/
CCalibrationFactory::CCalibrationFactory(CTaskbar *taskbar, CTouchscreen *touchscreen)
{
m_taskbar = taskbar;
m_touchscreen = touchscreen;
}
/**
* Create a new instance of an CCalibration (as IApplication).
*/
IApplication *CCalibrationFactory::create(void)
{
// Call CTaskBar::openFullScreenWindow to create a full screen window for
// the calibation application
CFullScreenWindow *window = m_taskbar->openFullScreenWindow();
if (!window)
{
gdbg("ERROR: Failed to create CFullScreenWindow\n");
return (IApplication *)0;
}
// Open the window (it is hot in here)
if (!window->open())
{
gdbg("ERROR: Failed to open CFullScreenWindow \n");
delete window;
return (IApplication *)0;
}
// Instantiate the application, providing the window to the application's
// constructor
CCalibration *calibration = new CCalibration(m_taskbar, window, m_touchscreen);
if (!calibration)
{
gdbg("ERROR: Failed to instantiate CCalibration\n");
delete window;
return (IApplication *)0;
}
return static_cast<IApplication*>(calibration);
}
/**
* 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 *CCalibrationFactory::getIcon(void)
{
NXWidgets::CRlePaletteBitmap *bitmap =
new NXWidgets::CRlePaletteBitmap(&CONFIG_NXWM_CALIBRATION_ICON);
return bitmap;
}

View File

@ -127,6 +127,18 @@ NXWidgets::INxWindow *CFullScreenWindow::getWindow(void) const
return static_cast<NXWidgets::INxWindow*>(m_window);
}
/**
* Recover the contained window control
*
* @return. The window control used by this application
*/
CWindowControl *CFullScreenWindow::getWindowControl(void) const
{
NXWidgets::CWidgetControl *control = m_window->getWidgetControl();
return static_cast<CWindowControl*>(control);
}
/**
* Set the window label
*

View File

@ -47,6 +47,7 @@
#include <fcntl.h>
#include <semaphore.h>
#include <sched.h>
#include <debug.h>
#include <apps/nsh.h>
@ -141,6 +142,11 @@ CNxConsole::CNxConsole(CTaskbar *taskbar, CApplicationWindow *window)
CNxConsole::~CNxConsole(void)
{
// There would be a problem if we were stopped with the NxConsole task
// running... that should never happen but we'll check anyway:
stop();
// Although we didn't create it, we are responsible for deleting the
// application window
@ -504,6 +510,72 @@ void CNxConsole::close(void)
m_taskbar->stopApplication(static_cast<IApplication*>(this));
}
/**
* CNxConsoleFactory Constructor
*
* @param taskbar. The taskbar instance used to terminate the console
*/
CNxConsoleFactory::CNxConsoleFactory(CTaskbar *taskbar)
{
m_taskbar = taskbar;
}
/**
* Create a new instance of an CNxConsole (as IApplication).
*/
IApplication *CNxConsoleFactory::create(void)
{
// Call CTaskBar::openFullScreenWindow to create a full screen window for
// the NxConsole application
CApplicationWindow *window = m_taskbar->openApplicationWindow();
if (!window)
{
gdbg("ERROR: Failed to create CApplicationWindow\n");
return (IApplication *)0;
}
// Open the window (it is hot in here)
if (!window->open())
{
gdbg("ERROR: Failed to open CApplicationWindow\n");
delete window;
return (IApplication *)0;
}
// Instantiate the application, providing the window to the application's
// constructor
CNxConsole *nxconsole = new CNxConsole(m_taskbar, window);
if (!nxconsole)
{
gdbg("ERROR: Failed to instantiate CNxConsole\n");
delete window;
return (IApplication *)0;
}
return static_cast<IApplication*>(nxconsole);
}
/**
* 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 *CNxConsoleFactory::getIcon(void)
{
NXWidgets::CRlePaletteBitmap *bitmap =
new NXWidgets::CRlePaletteBitmap(&CONFIG_NXWM_NXCONSOLE_ICON);
return bitmap;
}
/**
* One time NSH initialization. This function must be called exactly
* once during the boot-up sequence to initialize the NSH library.

View File

@ -39,6 +39,13 @@
#include <nuttx/config.h>
#include <cstdlib>
#include <cfcntl>
#include <csched>
#include <cerrno>
#include <mqueue.h>
#include "cwidgetcontrol.hxx"
#include "nxwmconfig.hxx"
@ -51,7 +58,7 @@
********************************************************************************************/
/********************************************************************************************
* CNxConsole Method Implementations
* CStartWindow Method Implementations
********************************************************************************************/
using namespace NxWM;
@ -70,6 +77,10 @@ CStartWindow::CStartWindow(CTaskbar *taskbar, CApplicationWindow *window)
m_taskbar = taskbar;
m_window = window;
// The start window task is not running
m_taskId = -1;
// Add our personalized window label
NXWidgets::CNxString myName = getName();
@ -86,6 +97,11 @@ CStartWindow::CStartWindow(CTaskbar *taskbar, CApplicationWindow *window)
CStartWindow::~CStartWindow(void)
{
// There would be a problem if we were stopped with the start window task
// running... that should never happen but we'll check anyway:
stop();
// Although we didn't create it, we are responsible for deleting the
// application window
@ -96,7 +112,7 @@ CStartWindow::~CStartWindow(void)
// Then stop and delete all applications
stopAllApplications();
removeAllApplications();
}
/**
@ -144,9 +160,24 @@ NXWidgets::CNxString CStartWindow::getName(void)
bool CStartWindow::run(void)
{
// We don't have a thread of execution. We only respond to button presses
// Some sanity checking
return true;
if (m_taskId >= 0)
{
// The start window task is already running???
return false;
}
// Start the start window task
m_taskId = TASK_CREATE("StartWindow", CONFIG_NXWM_STARTWINDOW_PRIO,
CONFIG_NXWM_STARTWINDOW_STACKSIZE, startWindow,
(FAR const char **)0);
// Did we successfully start the NxConsole task?
return m_taskId >= 0;
}
/**
@ -155,7 +186,20 @@ bool CStartWindow::run(void)
void CStartWindow::stop(void)
{
// We don't have a thread of execution. We only respond to button presses
// Delete the start window task --- what are we doing? This should never
// happen because the start window task is persistent!
if (m_taskId >= 0)
{
// Call task_delete(), possibly stranding resources
pid_t pid = m_taskId;
m_taskId = -1;
// Then delete the NSH task
task_delete(pid);
}
}
/**
@ -293,21 +337,17 @@ bool CStartWindow::isFullScreen(void) const
}
/**
* Add the application to the start window. The general sequence for
* setting up the start window is:
* Add the application to the start window. The general sequence is:
*
* 1. Call CTaskBar::openApplicationWindow to create a window for the start window,
* 2. Use the window to instantiate CStartWindow
* 3. Call CStartWindow::addApplication numerous times to install applications
* in the start window.
* 4. Call CTaskBar::startApplication (initially minimized) to start the start
* window application.
* 1. Call IAppicationFactory::create to a new instance of the application
* 2. Call CStartWindow::addApplication to add the application to the
* start window.
*
* @param app. The new application to add to the start window
* @return true on success
*/
bool CStartWindow::addApplication(IApplication *app)
bool CStartWindow::addApplication(IApplicationFactory *app)
{
// Recover the NXTK window instance contained in the application window
@ -418,18 +458,17 @@ void CStartWindow::getIconBounds(void)
* Stop all applications
*/
void CStartWindow::stopAllApplications(void)
void CStartWindow::removeAllApplications(void)
{
// Stop all applications and remove them from the task bar. Clearly, there
// Stop all applications and remove them from the start window. Clearly, there
// are some ordering issues here... On an orderly system shutdown, disconnection
// should really occur priority to deleting instances
while (!m_slots.empty())
{
// Stop the application (and remove it from the task bar)
// Remove the application factory from the start menu
IApplication *app = m_slots.at(0).app;
m_taskbar->stopApplication(app);
IApplicationFactory *app = m_slots.at(0).app;
// Now, delete the image and the application
@ -459,12 +498,125 @@ void CStartWindow::handleActionEvent(const NXWidgets::CWidgetEventArgs &e)
NXWidgets::CImage *image = m_slots.at(i).image;
if (image->isClicked())
{
// Start a new copy of the application
// Create a new copy of the application
m_taskbar->startApplication(m_slots.at(i).app, false);
IApplication *app = m_slots.at(i).app->create();
if (app)
{
// Start the new copy of the application
if (m_taskbar->startApplication(app, false))
{
// Then break out of the loop
break;
}
else
{
// If we cannot start the app. Destroy the
// instance we created and see what happens next.
CWindowControl *control = app->getWindowControl();
control->destroy(app);
}
}
}
}
}
/**
* This is the start window task. This function receives window events from
* the NX listener threads indirectly through this sequence:
*
* 1. NX listener thread receives a windows event. This may be a
* positional change notification, a redraw request, or mouse or
* keyboard input.
* 2. The NX listener thread performs the callback by calling a
* NXWidgets::CCallback method associated with the window.
* 3. NXWidgets::CCallback calls into NXWidgets::CWidgetControl to process
* the event.
* 4. NXWidgets::CWidgetControl records the new state data and raises a
* window event.
* 5. NXWidgets::CWindowEventHandlerList will give the event to
* NxWM::CWindowControl.
* 6. NxWM::CWindowControl will send the a message on a well-known message
* queue.
* 7. This CStartWindow::startWindow task will receive and process that
* message.
*/
int CStartWindow::startWindow(int argc, char *argv[])
{
/* Open a well-known message queue for reading */
struct mq_attr attr;
attr.mq_maxmsg = CONFIG_NXWM_STARTWINDOW_MXMSGS;
attr.mq_msgsize = sizeof(struct SStartWindowMessage);
attr.mq_flags = 0;
mqd_t mqd = mq_open(CONFIG_NXWM_STARTWINDOW_MQNAME, O_RDONLY|O_CREAT, 0666, &attr);
if (mqd == (mqd_t)-1)
{
gdbg("ERROR: mq_open(%s) failed: %d\n", CONFIG_NXWM_STARTWINDOW_MQNAME, errno);
return EXIT_FAILURE;
}
// Now loop forever, receiving and processing messages. Ultimately, all
// widget driven events (button presses, etc.) are driven by this logic
// on this thread.
for (;;)
{
// Receive the next message
struct SStartWindowMessage msg;
ssize_t nbytes = mq_receive(mqd, &msg, sizeof(struct SStartWindowMessage), 0);
if (nbytes < 0)
{
// EINTR is not an error. The wait was interrupted by a signal and
// we just need to try reading again.
if (errno != EINTR)
{
gdbg("ERROR: mq_receive failed: %d\n", errno);
}
}
while (nbytes < 0);
gvdbg("Received msgid=%d nbytes=%d\n", msg.msgId, nbytes);
DEBUGASSERT(nbytes = sizeof(struct SStartWindowMessage) && msg.instance);
// Dispatch the message to the appropriate CWidgetControl and to the
// appropriate CWidgetControl method
switch (msg.msgId)
{
break;
case MSGID_MOUSE_INPUT: // New mouse input is available
case MSGID_KEYBOARD_INPUT: // New keyboard input is available
{
// Handle all new window input events by calling the CWidgetControl::pollEvents() method
NXWidgets::CWidgetControl *control = (NXWidgets::CWidgetControl *)msg.instance;
control->pollEvents();
}
break;
case MSGID_DESTROY_APP: // Destroy the application
{
// Handle all destroy application events
gdbg("Deleting app=%p\n", msg.instance);
IApplication *app = (IApplication *)msg.instance;
delete app;
}
break;
case MSGID_POSITIONAL_CHANGE: // Change in window positional data (not used)
case MSGID_REDRAW_REQUEST: // Request to redraw a portion of the window (not used)
default:
gdbg("ERROR: Unrecognized or unsupported msgId: %d\n", (int)msg.msgId);
break;
}
}

View File

@ -609,7 +609,9 @@ bool CTaskbar::stopApplication(IApplication *app)
hideApplicationWindow(app);
// Stop the application (whatever this means to the application)
// Stop the application (whatever this means to the application). We
// separate stopping from destroying to get the application a chance
// to put things in order before being destroyed.
app->stop();
@ -631,6 +633,11 @@ bool CTaskbar::stopApplication(IApplication *app)
}
}
// destroy the application
CWindowControl *control = app->getWindowControl();
control->destroy(app);
// Re-draw the new top, non-minimized application
bool ret = redrawTopWindow();

View File

@ -39,6 +39,13 @@
#include <nuttx/config.h>
#include <cfcntl>
#include <cerrno>
#include <debug.h>
#include "nxwmconfig.hxx"
#include "cstartwindow.hxx"
#include "cwindowcontrol.hxx"
/********************************************************************************************
@ -62,6 +69,20 @@ using namespace NxWM;
CWindowControl::CWindowControl(FAR const NXWidgets::CWidgetStyle *style)
: NXWidgets::CWidgetControl(style)
{
// Open a message queue to communicate with the start window task. We need to create
// the message queue if it does not exist.
struct mq_attr attr;
attr.mq_maxmsg = CONFIG_NXWM_STARTWINDOW_MXMSGS;
attr.mq_msgsize = sizeof(struct SStartWindowMessage);
attr.mq_flags = 0;
m_mqd = mq_open(CONFIG_NXWM_STARTWINDOW_MQNAME, O_WRONLY|O_CREAT, 0666, &attr);
if (m_mqd == (mqd_t)-1)
{
gdbg("ERROR: mq_open(%s) failed: %d\n", CONFIG_NXWM_STARTWINDOW_MQNAME, errno);
}
// Add ourself as the window callback
addWindowEventHandler(this);
@ -73,11 +94,41 @@ CWindowControl::CWindowControl(FAR const NXWidgets::CWidgetStyle *style)
CWindowControl::~CWindowControl(void)
{
// Close the message queue
(void)mq_close(m_mqd);
// Remove ourself from the window callback
removeWindowEventHandler(this);
}
/**
* Destroy the application window and everything in it. This is
* handled by CWindowControl (vs just calling the destructors) because
* in the case where an application destroys itself (because of pressing
* the stop button), then we need to unwind and get out of the application
* logic before destroying all of its objects.
*/
void CWindowControl::destroy(IApplication *app)
{
// Send a message to destroy the window isntance at a later time
struct SStartWindowMessage outmsg;
outmsg.msgId = MSGID_DESTROY_APP;
outmsg.instance = (FAR void *)app;
gdbg("Sending MSGID_DESTROY_APP with instance=%p\n", app);
int ret = mq_send(m_mqd, &outmsg, sizeof(struct SStartWindowMessage),
CONFIG_NXWM_STARTWINDOW_MXMPRIO);
if (ret < 0)
{
gdbg("ERROR: mq_send failed: %d\n", errno);
}
}
/**
* Handle an NX window mouse input event.
*
@ -89,24 +140,40 @@ void CWindowControl::handleMouseEvent(void)
{
// The logic path here is tortuous but flexible:
//
// 1. A listener thread receives mouse input and injects that into NX
// 1. A listener thread receives mouse or touchscreen input and injects
// that into NX via nx_mousein
// 2. In the multi-user mode, this will send a message to the NX server
// 3. The NX server will determine which window gets the mouse input
// and send a message to the listener.
// 4. The listener will call the NX message dispatcher will will do the
// message callback.
// 5. The callback goes into an instance of NXWidgets::CCallback that is
// part of the CWidget control.
// 6. That callback will update mouse information then raise the
// mouse event,
// 7. Which will finally call this function -- still running deep on the
// stack in the listener thread.
// 8. This function will then call back into the widget control to process
// the mouse input.
// and send a window event message to the NX listener thread.
// 4. The NX listener thread receives a windows event. The NX listener thread
// which is part of CTaskBar and was created when NX server connection was
// established). This event may be a positional change notification, a
// redraw request, or mouse or keyboard input. In this case, mouse input.
// 5. The NX listener thread handles the message by calling nx_eventhandler().
// nx_eventhandler() dispatches the message by calling a method in the
// NXWidgets::CCallback instance associated with the window.
// NXWidgets::CCallback is a part of the CWidgetControl.
// 6. NXWidgets::CCallback calls into NXWidgets::CWidgetControl to process
// the event.
// 7. NXWidgets::CWidgetControl records the new state data and raises a
// window event.
// 8. NXWidgets::CWindowEventHandlerList will give the event to this method
// NxWM::CWindowControl.
// 9. This NxWM::CWindowControl method will send the a message on a well-
// known message queue.
// 10. This CStartWindow::startWindow task will receive and process that
// message by calling CWidgetControl::pollEvents()
// Perform the poll
struct SStartWindowMessage outmsg;
outmsg.msgId = MSGID_MOUSE_INPUT;
outmsg.instance = (FAR void *)static_cast<CWidgetControl*>(this);
pollEvents();
int ret = mq_send(m_mqd, &outmsg, sizeof(struct SStartWindowMessage),
CONFIG_NXWM_STARTWINDOW_MXMPRIO);
if (ret < 0)
{
gdbg("ERROR: mq_send failed: %d\n", errno);
}
}
#endif
@ -120,24 +187,38 @@ void CWindowControl::handleKeyboardEvent(void)
// The logic path here is tortuous but flexible:
//
// 1. A listener thread receives keyboard input and injects that into NX
// via nx_kbdin.
// 2. In the multi-user mode, this will send a message to the NX server
// 3. The NX server will determine which window gets the keyboard input
// and send a message to the listener.
// 4. The listener will call the NX message dispatcher will will do the
// message callback.
// 5. The callback goes into an instance of NXWidgets::CCallback that is
// part of the CWidget control.
// 6. That callback will update keyboard information then raise the
// keyboard event,
// 7. Which will finally call this function -- still running deep on the
// stack in the listener thread.
// 8. This function will then call back into the widget control to process
// the keyboard input.
// and send a window event message to the NX listener thread.
// 4. The NX listener thread receives a windows event. The NX listener thread
// which is part of CTaskBar and was created when NX server connection was
// established). This event may be a positional change notification, a
// redraw request, or mouse or keyboard input. In this case, keyboard input.
// 5. The NX listener thread handles the message by calling nx_eventhandler().
// nx_eventhandler() dispatches the message by calling a method in the
// NXWidgets::CCallback instance associated with the window.
// NXWidgets::CCallback is a part of the CWidgetControl.
// 6. NXWidgets::CCallback calls into NXWidgets::CWidgetControl to process
// the event.
// 7. NXWidgets::CWidgetControl records the new state data and raises a
// window event.
// 8. NXWidgets::CWindowEventHandlerList will give the event to this method
// NxWM::CWindowControl.
// 9. This NxWM::CWindowControl method will send the a message on a well-
// known message queue.
// 10. This CStartWindow::startWindow task will receive and process that
// message by calling CWidgetControl::pollEvents()
// Perform the poll
struct SStartWindowMessage outmsg;
outmsg.msgId = MSGID_KEYBOARD_INPUT;
outmsg.instance = (FAR void *)static_cast<CWidgetControl*>(this);
pollEvents();
int ret = mq_send(m_mqd, &outmsg, sizeof(struct SStartWindowMessage),
CONFIG_NXWM_STARTWINDOW_MXMPRIO);
if (ret < 0)
{
gdbg("ERROR: mq_send failed: %d\n", errno);
}
}
#endif

View File

@ -2771,3 +2771,5 @@
compilation errors when CONFIG_SCHED_ONEXIT is defined.
* configs/stm3240g-eval/nxwm/defconfig: The default NxWM not uses the STMPE11
touchscreen.
* include/cxx/csched: Added

View File

@ -1014,8 +1014,8 @@ CONFIG_STMPE11_GPIOINT_DISABLE=y
CONFIG_STMPE11_SWAPXY=n
CONFIG_STMPE11_TEMP_DISABLE=y
CONFIG_STMPE11_REGDEBUG=n
CONFIG_STMPE11_THRESHX=26
CONFIG_STMPE11_THRESHY=34
CONFIG_STMPE11_THRESHX=39
CONFIG_STMPE11_THRESHY=51
#
# USB Device Configuration
@ -1324,7 +1324,7 @@ CONFIG_NXWM_TOUCHSCREEN=y
#
CONFIG_NXCONSOLE=y
CONFIG_NXCONSOLE_BPP=16
CONFIG_NXCONSOLE_MXCHARS=256
CONFIG_NXCONSOLE_MXCHARS=325
CONFIG_NXCONSOLE_CACHESIZE=32
# CONFIG_NXCONSOLE_LINESEPARATION
# CONFIG_NXCONSOLE_NOWRAP

74
nuttx/include/cxx/csched Normal file
View File

@ -0,0 +1,74 @@
//***************************************************************************
// include/cxx/cfcntl
//
// 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 nor the names of its contributors may 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 __INCLUDE_CXX_CSCHED
#define __INCLUDE_CXX_CSCHED
//***************************************************************************
// Included Files
//***************************************************************************
#include <sched.h>
//***************************************************************************
// Namespace
//***************************************************************************
namespace std
{
using ::sched_param;
using ::task_init;
using ::task_activate;
using ::task_create;
using ::task_delete;
using ::task_restart;
using ::sched_setparam;
using ::sched_getparam;
using ::sched_setscheduler;
using ::sched_getscheduler;
using ::sched_get_priority_max;
using ::sched_get_priority_min;
using ::sched_rr_get_interval;
using ::sched_lock;
using ::sched_unlock;
using ::sched_lockcount;
#ifdef CONFIG_SCHED_INSTRUMENTATION
using ::sched_note_start;
using ::sched_note_stop;
using ::sched_note_switch;
#endif
}
#endif // __INCLUDE_CXX_CSCHED