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
Executable → Regular
+18 -1
View File
@@ -90,5 +90,22 @@
* NXWidgets::CNxWidget: Add a new onPreRelease() method. * NXWidgets::CNxWidget: Add a new onPreRelease() method.
* NXWidgets::CButton, CButtonArry, CImage now post action event at pre-release time. * 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. * 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) 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.
Executable → Regular
View File
Executable → Regular
View File
Executable → Regular
+15 -8
View File
@@ -26,13 +26,20 @@ NxWM
Status: Open Status: Open
Priority: Medium low Priority: Medium low
Title: MULTIPLE COPIES OF AN APPLICATION Title: MULTIPLE COPIES OF AN NxCONSOLE
Description: There is a limitation now in that one instance of an application Description: From the start window, you an create multiple copies of the
an be started at a time. This limitation is because the NxConsole. However, there is a problem in the current
application container class is created at start-up time; in implementation: Each NxConsole receives its input from the
order to have multiple instances of tasks, you would have to serial console so, for example, it you enter text one character
be able to create multiple container classes from the start will go to one NxConsole instance and the next character goes
window. 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 Status: Open
Priority: High Priority: Medium High
View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

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

View File

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

+7 -3
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 for the STM3210E-EVAL available. However, the unit test can be run on
other configurations (see steps d and e below). other configurations (see steps d and e below).
NOTE: Another special configuration, sim/nxwm, is recommended for unit-leveling NOTE: There are some other special configurationsrecommended for unit-leveling
testing of NxWM because the configuration is more complex in that case. 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 We will assume the sim/nsh2 configuration in this discussion. The
sim/nsh2 configuration is installed as follows: sim/nsh2 configuration is installed as follows:
@@ -286,7 +290,7 @@ CTextBox
nxwm nxwm
Exercises the NxWM window manager. 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 Example
======= =======
View File
+75 -102
View File
@@ -83,7 +83,6 @@ struct SNxWmTest
NxWM::CStartWindow *startwindow; // The start window NxWM::CStartWindow *startwindow; // The start window
#ifdef CONFIG_NXWM_TOUCHSCREEN #ifdef CONFIG_NXWM_TOUCHSCREEN
NxWM::CTouchscreen *touchscreen; // The touchscreen NxWM::CTouchscreen *touchscreen; // The touchscreen
NxWM::CCalibration *calibration; // The touchscreen calibration application
struct NxWM::SCalibrationData calibData; // Calibration data struct NxWM::SCalibrationData calibData; // Calibration data
#endif #endif
unsigned int mmInitial; // Initial memory usage 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 // 3. Call CTaskBar::startApplication repeatedly to add applications to the task bar
// 4. Call CTaskBar::startWindowManager to start the display with applications in place // 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(); g_nxwmtest.taskbar = new NxWM::CTaskbar();
if (!g_nxwmtest.taskbar) if (!g_nxwmtest.taskbar)
{ {
printf(MAIN_STRING "ERROR: Failed to instantiate CTaskbar\n"); printf("createTaskbar: ERROR: Failed to instantiate CTaskbar\n");
return false; return false;
} }
showTestCaseMemory("After create taskbar"); showTestCaseMemory("createTaskbar: After create taskbar");
// Connect to the NX server // 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()) 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; return false;
} }
showTestCaseMemory("After connecting to the server"); showTestCaseMemory("createTaskbar: After connecting to the server");
// Initialize the task bar // Initialize the task bar
// //
@@ -275,14 +274,14 @@ static bool createTaskbar(void)
// CTaskBar::startWindowManager() brings the window manager up with those applications // CTaskBar::startWindowManager() brings the window manager up with those applications
// in place. // in place.
printf(MAIN_STRING "Initialize CTaskbar instance\n"); printf("createTaskbar: Initialize CTaskbar instance\n");
if (!g_nxwmtest.taskbar->initWindowManager()) 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; return false;
} }
showTestCaseMemory("After initializing window manager"); showTestCaseMemory("createTaskbar: After initializing window manager");
return true; return true;
} }
@@ -292,55 +291,58 @@ static bool createTaskbar(void)
static bool createStartWindow(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, // 1. Create and open a CApplicationWindow
// 2. Use the window to instantiate Cstartwindow // 2. Use the window to create the CStartWindow the start window application
// 3. Call Cstartwindow::addApplication numerous times to install applications // 2. Call Cstartwindow::addApplication numerous times to install applications
// in the start window. // 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. // window application.
// //
// NOTE: that the start window should not have a stop button. // 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); NxWM::CApplicationWindow *window = g_nxwmtest.taskbar->openApplicationWindow(NxWM::CApplicationWindow::WINDOW_PERSISTENT);
if (!window) 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; 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()) if (!window->open())
{ {
printf(MAIN_STRING "ERROR: Failed to open CApplicationWindow \n"); printf("createStartWindow: ERROR: Failed to open CApplicationWindow \n");
delete window; delete window;
return false; 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); g_nxwmtest.startwindow = new NxWM::CStartWindow(g_nxwmtest.taskbar, window);
if (!g_nxwmtest.startwindow) if (!g_nxwmtest.startwindow)
{ {
printf(MAIN_STRING "ERROR: Failed to instantiate CStartWindow\n"); gdbg("ERROR: Failed to instantiate CStartWindow\n");
delete window; delete window;
return false; 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)) 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; return false;
} }
showTestCaseMemory("After starting the start window application"); showTestCaseMemory("createStartWindow: After starting the start window application");
showTestCaseMemory("After create the start window application");
return true; return true;
} }
@@ -352,14 +354,14 @@ static bool startWindowManager(void)
{ {
// Start the window manager // Start the window manager
printf(MAIN_STRING "Start the window manager\n"); printf("startWindowManager: Start the window manager\n");
if (!g_nxwmtest.taskbar->startWindowManager()) 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; return false;
} }
showTestCaseMemory("After starting the window manager"); showTestCaseMemory("AstartWindowManager: fter starting the window manager");
return true; return true;
} }
@@ -377,23 +379,24 @@ static bool createTouchScreen(void)
// Create the touchscreen device // 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); g_nxwmtest.touchscreen = new NxWM::CTouchscreen(g_nxwmtest.taskbar, &displaySize);
if (!g_nxwmtest.touchscreen) if (!g_nxwmtest.touchscreen)
{ {
printf(MAIN_STRING "ERROR: Failed to create CTouchscreen\n"); printf("createTouchScreen: ERROR: Failed to create CTouchscreen\n");
return false; 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()) 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; delete g_nxwmtest.touchscreen;
return false; return false;
} }
showTestCaseMemory("After starting the touchscreen listener"); showTestCaseMemory("createTouchScreen: After starting the touchscreen listener");
return true; return true;
} }
#endif #endif
@@ -405,61 +408,50 @@ static bool createTouchScreen(void)
#ifdef CONFIG_NXWM_TOUCHSCREEN #ifdef CONFIG_NXWM_TOUCHSCREEN
static bool createCalibration(void) static bool createCalibration(void)
{ {
// 1. Call CTaskBar::openFullScreenWindow to create a window for the application, // 1Create the CCalibrationFactory application factory
// 2. Instantiate the application, providing the window to the application's
// constructor,
printf(MAIN_STRING "Opening the calibration application window\n"); printf("createCalibration: Creating CCalibrationFactory\n");
NxWM::CFullScreenWindow *window = g_nxwmtest.taskbar->openFullScreenWindow(); NxWM::CCalibrationFactory *factory = new NxWM::CCalibrationFactory(g_nxwmtest.taskbar, g_nxwmtest.touchscreen);
if (!window) 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; return false;
} }
showTestCaseMemory("After creating calibration full screen window"); showTestCaseMemory("createCalibration: After creating CCalibrationFactory");
printf(MAIN_STRING "Initialize CFullScreenWindow\n"); // Add the calibration application to the start window.
if (!window->open())
printf("createCalibration: Adding CCalibration to the start window\n");
if (!g_nxwmtest.startwindow->addApplication(factory))
{ {
printf(MAIN_STRING "ERROR: Failed to open CFullScreenWindow \n"); printf("createCalibration: ERROR: Failed to add CCalibrationto the start window\n");
delete window; delete factory;
return false; return false;
} }
showTestCaseMemory("After initializing the calibration full screen window"); showTestCaseMemory("createCalibration: After adding CCalibration");
printf(MAIN_STRING "Creating CCalibration application\n"); // Call StartWindowFactory::create to to create the start window application
g_nxwmtest.calibration = new NxWM::CCalibration(g_nxwmtest.taskbar, window, g_nxwmtest.touchscreen);
if (!g_nxwmtest.calibration) printf("createCalibration: Creating CCalibration\n");
NxWM::IApplication *calibration = factory->create();
if (!calibration)
{ {
printf(MAIN_STRING "ERROR: Failed to instantiate CCalibration\n"); printf("createCalibration: ERROR: Failed to create CCalibration\n");
delete window;
return false; return false;
} }
showTestCaseMemory("After creating CCalibration application"); showTestCaseMemory("createCalibration: After creating CCalibration");
// 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");
// Call CTaskBar::startApplication to start the Calibration application. Nothing // Call CTaskBar::startApplication to start the Calibration application. Nothing
// will be displayed because the window manager has not yet been started. // will be displayed because the window manager has not yet been started.
printf(MAIN_STRING "Start the calibration application\n"); printf("createCalibration: Start the calibration application\n");
if (!g_nxwmtest.taskbar->startApplication(g_nxwmtest.calibration, false)) if (!g_nxwmtest.taskbar->startApplication(calibration, false))
{ {
printf(MAIN_STRING "ERROR: Failed to start the calibration application\n"); printf(MAIN_STRING "ERROR: Failed to start the calibration application\n");
delete calibration;
return false; return false;
} }
showTestCaseMemory("After starting the start window application"); showTestCaseMemory("createCalibration: After starting the start window application");
return true; return true;
} }
#endif #endif
@@ -472,43 +464,24 @@ static bool createNxConsole(void)
{ {
// Add the NxConsole application to the start window // Add the NxConsole application to the start window
printf(MAIN_STRING "Opening the NxConsole application window\n"); printf("createNxConsole: Creating the NxConsole application\n");
NxWM::CApplicationWindow *window = g_nxwmtest.taskbar->openApplicationWindow(); NxWM::CNxConsoleFactory *console = new NxWM::CNxConsoleFactory(g_nxwmtest.taskbar);
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);
if (!console) if (!console)
{ {
printf(MAIN_STRING "ERROR: Failed to instantiate CNxConsole\n"); printf("createNxConsole: ERROR: Failed to instantiate CNxConsoleFactory\n");
delete window;
return false; 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)) 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; delete console;
return false; return false;
} }
showTestCaseMemory("After adding the NxConsole application"); showTestCaseMemory("createNxConsole: After adding the NxConsole application");
return true; return true;
} }
@@ -557,7 +530,7 @@ int MAIN_NAME(int argc, char *argv[])
printf(MAIN_STRING "ERROR: Failed to initialize the NSH library\n"); printf(MAIN_STRING "ERROR: Failed to initialize the NSH library\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
showTestCaseMemory("After initializing the NSH library"); showTestCaseMemory(MAIN_STRING "After initializing the NSH library");
// Create the task bar. // Create the task bar.
@@ -641,20 +614,20 @@ int MAIN_NAME(int argc, char *argv[])
#ifndef CONFIG_NXWM_TOUCHSCREEN #ifndef CONFIG_NXWM_TOUCHSCREEN
sleep(2); sleep(2);
g_nxwmtest.taskbar->clickIcon(0); 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 // 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. // in the start menu. That should be the NxConsole icon.
sleep(2); sleep(2);
g_nxwmtest.startwindow->clickIcon(0); g_nxwmtest.startwindow->clickIcon(0);
showTestCaseMemory("After clicking the NxConsole icon"); showTestCaseMemory(MAIN_STRING "After clicking the NxConsole icon");
#endif #endif
// Wait bit to see the result of the button press. // Wait bit to see the result of the button press.
sleep(2); sleep(2);
showTestMemory("Final memory usage"); showTestMemory(MAIN_STRING "Final memory usage");
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
@@ -346,7 +346,7 @@ namespace NXWidgets
* Destructor. * Destructor.
*/ */
~CWidgetControl(void); virtual ~CWidgetControl(void);
/** /**
* Wait for an interesting window event to occur (like a mouse or keyboard event) * Wait for an interesting window event to occur (like a mouse or keyboard event)
+3 -3
View File
@@ -36,7 +36,7 @@
/**************************************************************************** /****************************************************************************
* Included Files * Included Files
****************************************************************************/ ****************************************************************************/
#include <nuttx/config.h> #include <nuttx/config.h>
#include <stdint.h> #include <stdint.h>
@@ -152,7 +152,7 @@ CNxToolbar *CNxTkWindow::openToolbar(nxgl_coord_t height, CWidgetControl *widget
{ {
// Create a new widget control if none was provided // Create a new widget control if none was provided
CWidgetControl *allocControl = (CWidgetControl *)0; CWidgetControl *allocControl = (CWidgetControl *)0;
if (!widgetControl) if (!widgetControl)
{ {
// NOTE: This constructor would accept the toolbar "style" as a argument. // NOTE: This constructor would accept the toolbar "style" as a argument.
@@ -226,7 +226,7 @@ CNxToolbar *CNxTkWindow::openToolbar(nxgl_coord_t height, CWidgetControl *widget
sched_lock(); sched_lock();
// Get the physical bounding box of the window in display coordinates // Get the physical bounding box of the window in display coordinates
struct nxgl_rect_s windowBounds; struct nxgl_rect_s windowBounds;
m_widgetControl->getWindowBoundingBox(&windowBounds); m_widgetControl->getWindowBoundingBox(&windowBounds);
+1 -1
View File
@@ -36,7 +36,7 @@
/**************************************************************************** /****************************************************************************
* Included Files * Included Files
****************************************************************************/ ****************************************************************************/
#include <nuttx/config.h> #include <nuttx/config.h>
#include <stdint.h> #include <stdint.h>
@@ -143,7 +143,7 @@ CWidgetControl::CWidgetControl(FAR const CWidgetStyle *style)
CWidgetControl::~CWidgetControl(void) 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 // it is probably already too late
#ifdef CONFIG_NXWIDGET_EVENTWAIT #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) 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; CRect rect;
rect.setNxRect(nxRect); rect.setNxRect(nxRect);
m_eventHandlers.raiseRedrawEvent(); m_eventHandlers.raiseRedrawEvent();
@@ -100,7 +100,7 @@ using namespace NXWidgets;
CWidgetEventHandlerList::CWidgetEventHandlerList(CNxWidget *widget) CWidgetEventHandlerList::CWidgetEventHandlerList(CNxWidget *widget)
{ {
m_widget = widget; m_widget = widget;
m_isEnabled = true; m_isEnabled = true;
} }
@@ -125,7 +125,7 @@ void CWidgetEventHandlerList::addWidgetEventHandler(CWidgetEventHandler *eventHa
{ {
// Prevent insertion if the handler already exists // 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) if (m_widgetEventHandlers.at(i) == eventHandler)
{ {
@@ -146,7 +146,7 @@ void CWidgetEventHandlerList::addWidgetEventHandler(CWidgetEventHandler *eventHa
void CWidgetEventHandlerList::removeWidgetEventHandler(CWidgetEventHandler *eventHandler) 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) 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); m_widgetEventHandlers.at(i)->handleScrollEvent(e);
} }
@@ -159,3 +159,4 @@ void CWindowEventHandlerList::raiseKeyboardEvent(void)
} }
#endif #endif
} }
Binary file not shown.
@@ -150,6 +150,14 @@ namespace NxWM
NXWidgets::INxWindow *getWindow(void) const; 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 * Set the window label
* *
+40
View File
@@ -314,6 +314,46 @@ namespace NxWM
bool isFullScreen(void) const; 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 #endif // __INCLUDE_CCALIBRATION_HXX
@@ -114,6 +114,14 @@ namespace NxWM
NXWidgets::INxWindow *getWindow(void) const; 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 * Set the window label
* *
+37
View File
@@ -191,6 +191,43 @@ namespace NxWM
bool isFullScreen(void) const; 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 #endif // __cplusplus
+62 -9
View File
@@ -42,6 +42,8 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <debug.h>
#include "tnxarray.hxx" #include "tnxarray.hxx"
#include "iapplication.hxx" #include "iapplication.hxx"
@@ -59,8 +61,35 @@
namespace NxWM namespace NxWM
{ {
/**
* Forward references
*/
class CTaskbar; 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, class CStartWindow : public IApplication,
private IApplicationCallback, private IApplicationCallback,
private NXWidgets::CWidgetEventHandler private NXWidgets::CWidgetEventHandler
@@ -72,7 +101,7 @@ namespace NxWM
struct SStartWindowSlot 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 */ 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 */ CApplicationWindow *m_window; /**< Reference to the application window */
TNxArray<struct SStartWindowSlot> m_slots; /**< List of apps in the start 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 */ 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. * Called when the window minimize button is pressed.
@@ -107,7 +163,7 @@ namespace NxWM
* Stop all applications * Stop all applications
*/ */
void stopAllApplications(void); void removeAllApplications(void);
/** /**
* Handle a widget action event. For CImage, this is a mouse button pre-release event. * 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 * Add the application to the start window. The general sequence for
* setting up the start window is: * setting up the start window is:
* *
* 1. Call CTaskBar::openApplicationWindow to create a window for the start window, * 1. Call IAppicationFactory::create to a new instance of the application
* 2. Use the window to instantiate CStartWindow * 2. Call CStartWindow::addApplication to add the application to the
* 3. Call CStartWindow::addApplication numerous times to install applications * start window.
* in the start window.
* 4. Call CTaskBar::startApplication (initially minimized) to start the start
* window application.
* *
* @param app. The new application to add to the start window * @param app. The new application to add to the start window
* @return true on success * @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 * Simulate a mouse click on the icon at index. This inline method is only
+21
View File
@@ -43,6 +43,8 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <sys/types.h> #include <sys/types.h>
#include <mqueue.h>
#include <nuttx/nx/nxtk.h> #include <nuttx/nx/nxtk.h>
#include <nuttx/nx/nxconsole.h> #include <nuttx/nx/nxconsole.h>
@@ -61,6 +63,12 @@
namespace NxWM namespace NxWM
{ {
/**
* Forward references.
*/
class IApplication;
/** /**
* The class CWindowControl integrates the widget control with some special * The class CWindowControl integrates the widget control with some special
* handling of mouse and keyboard inputs neesed by NxWM * handling of mouse and keyboard inputs neesed by NxWM
@@ -70,6 +78,9 @@ namespace NxWM
private NXWidgets::CWindowEventHandler private NXWidgets::CWindowEventHandler
{ {
private: private:
mqd_t m_mqd; /**< Message queue descriptor used to commincate with the
** start window thread. */
/** /**
* Handle an NX window mouse input event. * Handle an NX window mouse input event.
* *
@@ -105,6 +116,16 @@ namespace NxWM
*/ */
~CWindowControl(void); ~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 #endif // __cplusplus
+53 -3
View File
@@ -44,6 +44,8 @@
#include "cnxstring.hxx" #include "cnxstring.hxx"
#include "ibitmap.hxx" #include "ibitmap.hxx"
#include "cwindowcontrol.hxx"
#include "capplicationwindow.hxx" #include "capplicationwindow.hxx"
/**************************************************************************** /****************************************************************************
@@ -65,14 +67,25 @@ namespace NxWM
class IApplication class IApplication
{ {
protected: 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: * These values (and the accessors that go with them) violate the "purity"
// Each application provides this state information needed by the taskbar. * 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_minimized; /**< True if the application is minimized */
bool m_topapp; /**< True if this application is at the top in the hiearchy */ bool m_topapp; /**< True if this application is at the top in the hiearchy */
public: 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 * Each implementation of IApplication must provide a method to recover
* the contained CApplicationWindow instance. * the contained CApplicationWindow instance.
@@ -80,6 +93,18 @@ namespace NxWM
virtual IApplicationWindow *getWindow(void) const = 0; 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 * Get the icon associated with the application
* *
@@ -181,6 +206,31 @@ namespace NxWM
virtual bool isFullScreen(void) const = 0; 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 #endif // __cplusplus
+12 -7
View File
@@ -42,13 +42,10 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include "cnxtkwindow.hxx" #include "inxwindow.hxx"
#include "cnxtoolbar.hxx" #include "cnxstring.hxx"
#include "cwidgeteventargs.hxx"
#include "cwidgeteventhandler.hxx" #include "cwindowcontrol.hxx"
#include "cimage.hxx"
#include "clabel.hxx"
#include "crlepalettebitmap.hxx"
/**************************************************************************** /****************************************************************************
* Pre-Processor Definitions * Pre-Processor Definitions
@@ -121,6 +118,14 @@ namespace NxWM
virtual NXWidgets::INxWindow *getWindow(void) const = 0; 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 * Set the window label
* *
+48 -2
View File
@@ -263,6 +263,19 @@
* CONFIG_NXWM_STARTWINDOW_VSPACING - Vertical spacing. Default: 2 pixels * CONFIG_NXWM_STARTWINDOW_VSPACING - Vertical spacing. Default: 2 pixels
* CONFIG_NXWM_STARTWINDOW_HSPACING - Horizontal spacing. Default: 2 rows * 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_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 #ifndef CONFIG_NXWM_STARTWINDOW_VSPACING
@@ -281,6 +294,39 @@
# define CONFIG_NXWM_STARTWINDOW_ICON NxWM::g_playBitmap # define CONFIG_NXWM_STARTWINDOW_ICON NxWM::g_playBitmap
#endif #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 *********************************************************/
/** /**
* NxConsole Window Configuration * NxConsole Window Configuration
@@ -347,7 +393,7 @@
* CONFIG_NXWM_TOUCHSCREEN_LISTENERPRIO - Priority of the touchscreen listener * CONFIG_NXWM_TOUCHSCREEN_LISTENERPRIO - Priority of the touchscreen listener
* thread. Default: SCHED_PRIORITY_DEFAULT * thread. Default: SCHED_PRIORITY_DEFAULT
* CONFIG_NXWM_TOUCHSCREEN_LISTENERSTACK - Touchscreen listener thread stack * CONFIG_NXWM_TOUCHSCREEN_LISTENERSTACK - Touchscreen listener thread stack
* size. Default 2048 * size. Default 1024
*/ */
#ifndef CONFIG_NXWM_TOUCHSCREEN_DEVNO #ifndef CONFIG_NXWM_TOUCHSCREEN_DEVNO
@@ -367,7 +413,7 @@
#endif #endif
#ifndef CONFIG_NXWM_TOUCHSCREEN_LISTENERSTACK #ifndef CONFIG_NXWM_TOUCHSCREEN_LISTENERSTACK
# define CONFIG_NXWM_TOUCHSCREEN_LISTENERSTACK 2048 # define CONFIG_NXWM_TOUCHSCREEN_LISTENERSTACK 1024
#endif #endif
/* Calibration display ******************************************************/ /* Calibration display ******************************************************/
+12
View File
@@ -413,6 +413,18 @@ NXWidgets::INxWindow *CApplicationWindow::getWindow(void) const
return static_cast<NXWidgets::INxWindow*>(m_window); 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 * Set the window label
* *
+73 -1
View File
@@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* NxWidgets/nxwm/src/capplicationwindow.cxx * NxWidgets/nxwm/src/ccalibration.cxx
* *
* Copyright (C) 2012 Gregory Nutt. All rights reserved. * Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
@@ -107,6 +107,11 @@ CCalibration::CCalibration(CTaskbar *taskbar, CFullScreenWindow *window,
CCalibration::~CCalibration(void) 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 // Although we did not create the window, the rule is that I have to dispose
// of it // of it
@@ -788,4 +793,71 @@ bool CCalibration::createCalibrationData(struct SCalibrationData &data)
return true; 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;
}
+12
View File
@@ -127,6 +127,18 @@ NXWidgets::INxWindow *CFullScreenWindow::getWindow(void) const
return static_cast<NXWidgets::INxWindow*>(m_window); 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 * Set the window label
* *
+72
View File
@@ -47,6 +47,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <semaphore.h> #include <semaphore.h>
#include <sched.h> #include <sched.h>
#include <debug.h>
#include <apps/nsh.h> #include <apps/nsh.h>
@@ -141,6 +142,11 @@ CNxConsole::CNxConsole(CTaskbar *taskbar, CApplicationWindow *window)
CNxConsole::~CNxConsole(void) 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 // Although we didn't create it, we are responsible for deleting the
// application window // application window
@@ -504,6 +510,72 @@ void CNxConsole::close(void)
m_taskbar->stopApplication(static_cast<IApplication*>(this)); 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 * One time NSH initialization. This function must be called exactly
* once during the boot-up sequence to initialize the NSH library. * once during the boot-up sequence to initialize the NSH library.
+174 -22
View File
@@ -39,6 +39,13 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <cstdlib>
#include <cfcntl>
#include <csched>
#include <cerrno>
#include <mqueue.h>
#include "cwidgetcontrol.hxx" #include "cwidgetcontrol.hxx"
#include "nxwmconfig.hxx" #include "nxwmconfig.hxx"
@@ -51,7 +58,7 @@
********************************************************************************************/ ********************************************************************************************/
/******************************************************************************************** /********************************************************************************************
* CNxConsole Method Implementations * CStartWindow Method Implementations
********************************************************************************************/ ********************************************************************************************/
using namespace NxWM; using namespace NxWM;
@@ -70,6 +77,10 @@ CStartWindow::CStartWindow(CTaskbar *taskbar, CApplicationWindow *window)
m_taskbar = taskbar; m_taskbar = taskbar;
m_window = window; m_window = window;
// The start window task is not running
m_taskId = -1;
// Add our personalized window label // Add our personalized window label
NXWidgets::CNxString myName = getName(); NXWidgets::CNxString myName = getName();
@@ -86,6 +97,11 @@ CStartWindow::CStartWindow(CTaskbar *taskbar, CApplicationWindow *window)
CStartWindow::~CStartWindow(void) 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 // Although we didn't create it, we are responsible for deleting the
// application window // application window
@@ -96,7 +112,7 @@ CStartWindow::~CStartWindow(void)
// Then stop and delete all applications // Then stop and delete all applications
stopAllApplications(); removeAllApplications();
} }
/** /**
@@ -144,9 +160,24 @@ NXWidgets::CNxString CStartWindow::getName(void)
bool CStartWindow::run(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) 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 * Add the application to the start window. The general sequence is:
* setting up the start window is:
* *
* 1. Call CTaskBar::openApplicationWindow to create a window for the start window, * 1. Call IAppicationFactory::create to a new instance of the application
* 2. Use the window to instantiate CStartWindow * 2. Call CStartWindow::addApplication to add the application to the
* 3. Call CStartWindow::addApplication numerous times to install applications * start window.
* in the start window.
* 4. Call CTaskBar::startApplication (initially minimized) to start the start
* window application.
* *
* @param app. The new application to add to the start window * @param app. The new application to add to the start window
* @return true on success * @return true on success
*/ */
bool CStartWindow::addApplication(IApplication *app) bool CStartWindow::addApplication(IApplicationFactory *app)
{ {
// Recover the NXTK window instance contained in the application window // Recover the NXTK window instance contained in the application window
@@ -418,18 +458,17 @@ void CStartWindow::getIconBounds(void)
* Stop all applications * 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 // are some ordering issues here... On an orderly system shutdown, disconnection
// should really occur priority to deleting instances // should really occur priority to deleting instances
while (!m_slots.empty()) 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; IApplicationFactory *app = m_slots.at(0).app;
m_taskbar->stopApplication(app);
// Now, delete the image and the application // 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; NXWidgets::CImage *image = m_slots.at(i).image;
if (image->isClicked()) 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
// Then break out of the loop 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; break;
} }
} }
+8 -1
View File
@@ -609,7 +609,9 @@ bool CTaskbar::stopApplication(IApplication *app)
hideApplicationWindow(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(); 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 // Re-draw the new top, non-minimized application
bool ret = redrawTopWindow(); bool ret = redrawTopWindow();
+116 -35
View File
@@ -36,9 +36,16 @@
/******************************************************************************************** /********************************************************************************************
* Included Files * Included Files
********************************************************************************************/ ********************************************************************************************/
#include <nuttx/config.h> #include <nuttx/config.h>
#include <cfcntl>
#include <cerrno>
#include <debug.h>
#include "nxwmconfig.hxx"
#include "cstartwindow.hxx"
#include "cwindowcontrol.hxx" #include "cwindowcontrol.hxx"
/******************************************************************************************** /********************************************************************************************
@@ -62,6 +69,20 @@ using namespace NxWM;
CWindowControl::CWindowControl(FAR const NXWidgets::CWidgetStyle *style) CWindowControl::CWindowControl(FAR const NXWidgets::CWidgetStyle *style)
: NXWidgets::CWidgetControl(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 // Add ourself as the window callback
addWindowEventHandler(this); addWindowEventHandler(this);
@@ -73,11 +94,41 @@ CWindowControl::CWindowControl(FAR const NXWidgets::CWidgetStyle *style)
CWindowControl::~CWindowControl(void) CWindowControl::~CWindowControl(void)
{ {
// Close the message queue
(void)mq_close(m_mqd);
// Remove ourself from the window callback // Remove ourself from the window callback
removeWindowEventHandler(this); 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. * Handle an NX window mouse input event.
* *
@@ -89,24 +140,40 @@ void CWindowControl::handleMouseEvent(void)
{ {
// The logic path here is tortuous but flexible: // 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
// 2. In the multi-user mode, this will send a message to the NX server // that into NX via nx_mousein
// 3. The NX server will determine which window gets the mouse input // 2. In the multi-user mode, this will send a message to the NX server
// and send a message to the listener. // 3. The NX server will determine which window gets the mouse input
// 4. The listener will call the NX message dispatcher will will do the // and send a window event message to the NX listener thread.
// message callback. // 4. The NX listener thread receives a windows event. The NX listener thread
// 5. The callback goes into an instance of NXWidgets::CCallback that is // which is part of CTaskBar and was created when NX server connection was
// part of the CWidget control. // established). This event may be a positional change notification, a
// 6. That callback will update mouse information then raise the // redraw request, or mouse or keyboard input. In this case, mouse input.
// mouse event, // 5. The NX listener thread handles the message by calling nx_eventhandler().
// 7. Which will finally call this function -- still running deep on the // nx_eventhandler() dispatches the message by calling a method in the
// stack in the listener thread. // NXWidgets::CCallback instance associated with the window.
// 8. This function will then call back into the widget control to process // NXWidgets::CCallback is a part of the CWidgetControl.
// the mouse input. // 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 #endif
@@ -119,25 +186,39 @@ void CWindowControl::handleKeyboardEvent(void)
{ {
// The logic path here is tortuous but flexible: // The logic path here is tortuous but flexible:
// //
// 1. A listener thread receives keyboard input and injects that into NX // 1. A listener thread receives keyboard input and injects that into NX
// 2. In the multi-user mode, this will send a message to the NX server // via nx_kbdin.
// 3. The NX server will determine which window gets the keyboard input // 2. In the multi-user mode, this will send a message to the NX server
// and send a message to the listener. // 3. The NX server will determine which window gets the keyboard input
// 4. The listener will call the NX message dispatcher will will do the // and send a window event message to the NX listener thread.
// message callback. // 4. The NX listener thread receives a windows event. The NX listener thread
// 5. The callback goes into an instance of NXWidgets::CCallback that is // which is part of CTaskBar and was created when NX server connection was
// part of the CWidget control. // established). This event may be a positional change notification, a
// 6. That callback will update keyboard information then raise the // redraw request, or mouse or keyboard input. In this case, keyboard input.
// keyboard event, // 5. The NX listener thread handles the message by calling nx_eventhandler().
// 7. Which will finally call this function -- still running deep on the // nx_eventhandler() dispatches the message by calling a method in the
// stack in the listener thread. // NXWidgets::CCallback instance associated with the window.
// 8. This function will then call back into the widget control to process // NXWidgets::CCallback is a part of the CWidgetControl.
// the keyboard input. // 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 #endif
+2
View File
@@ -2771,3 +2771,5 @@
compilation errors when CONFIG_SCHED_ONEXIT is defined. compilation errors when CONFIG_SCHED_ONEXIT is defined.
* configs/stm3240g-eval/nxwm/defconfig: The default NxWM not uses the STMPE11 * configs/stm3240g-eval/nxwm/defconfig: The default NxWM not uses the STMPE11
touchscreen. touchscreen.
* include/cxx/csched: Added
+3 -3
View File
@@ -1014,8 +1014,8 @@ CONFIG_STMPE11_GPIOINT_DISABLE=y
CONFIG_STMPE11_SWAPXY=n CONFIG_STMPE11_SWAPXY=n
CONFIG_STMPE11_TEMP_DISABLE=y CONFIG_STMPE11_TEMP_DISABLE=y
CONFIG_STMPE11_REGDEBUG=n CONFIG_STMPE11_REGDEBUG=n
CONFIG_STMPE11_THRESHX=26 CONFIG_STMPE11_THRESHX=39
CONFIG_STMPE11_THRESHY=34 CONFIG_STMPE11_THRESHY=51
# #
# USB Device Configuration # USB Device Configuration
@@ -1324,7 +1324,7 @@ CONFIG_NXWM_TOUCHSCREEN=y
# #
CONFIG_NXCONSOLE=y CONFIG_NXCONSOLE=y
CONFIG_NXCONSOLE_BPP=16 CONFIG_NXCONSOLE_BPP=16
CONFIG_NXCONSOLE_MXCHARS=256 CONFIG_NXCONSOLE_MXCHARS=325
CONFIG_NXCONSOLE_CACHESIZE=32 CONFIG_NXCONSOLE_CACHESIZE=32
# CONFIG_NXCONSOLE_LINESEPARATION # CONFIG_NXCONSOLE_LINESEPARATION
# CONFIG_NXCONSOLE_NOWRAP # CONFIG_NXCONSOLE_NOWRAP
+74
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