From 0efb245d6def577e7a457d17a41a0c170277062e Mon Sep 17 00:00:00 2001 From: patacongo Date: Wed, 16 May 2012 22:43:40 +0000 Subject: [PATCH] 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: svn://svn.code.sf.net/p/nuttx/code/trunk@4742 42af7a65-404d-4744-a932-0658087f49c3 --- ChangeLog.txt | 19 +- README.txt | 0 ReleaseNotes.txt | 0 TODO.txt | 23 +- UnitTests/CButton/cbutton-pushed.png | Bin UnitTests/CButton/cbutton-released.png | Bin UnitTests/CButtonArray/cbuttonarray.png | Bin UnitTests/CCheckBox/ccheckbox.png | Bin UnitTests/CLabel/clabel.png | Bin UnitTests/CProgressBar/cprogressbar.png | Bin UnitTests/CRadioButton/cradiobutton.png | Bin .../cscrollbarhorizontal.png | Bin .../CScrollbarVertical/cscrollbarvertical.png | Bin .../CSliderHorizonal/csliderhorizontal.png | Bin UnitTests/CSliderVertical/cslidervertical.png | Bin UnitTests/CTextBox/ctextbox.png | Bin UnitTests/README.txt | 10 +- UnitTests/TestStatus.txt | 0 UnitTests/nxwm/main.cxx | 177 +++++++--------- libnxwidgets/include/cwidgetcontrol.hxx | 2 +- libnxwidgets/src/cnxtkwindow.cxx | 6 +- libnxwidgets/src/cnxtoolbar.cxx | 2 +- libnxwidgets/src/cwidgetcontrol.cxx | 3 +- libnxwidgets/src/cwidgeteventhandlerlist.cxx | 46 ++-- libnxwidgets/src/cwindoweventhandlerlist.cxx | 1 + nxwm/doc/NxWM-ThreadingModel.ppt | Bin 0 -> 92672 bytes nxwm/include/capplicationwindow.hxx | 8 + nxwm/include/ccalibration.hxx | 40 ++++ nxwm/include/cfullscreenwindow.hxx | 8 + nxwm/include/cnxconsole.hxx | 37 ++++ nxwm/include/cstartwindow.hxx | 71 ++++++- nxwm/include/cwindowcontrol.hxx | 21 ++ nxwm/include/iapplication.hxx | 56 ++++- nxwm/include/iapplicationwindow.hxx | 19 +- nxwm/include/nxwmconfig.hxx | 50 ++++- nxwm/src/capplicationwindow.cxx | 12 ++ nxwm/src/ccalibration.cxx | 74 ++++++- nxwm/src/cfullscreenwindow.cxx | 12 ++ nxwm/src/cnxconsole.cxx | 72 +++++++ nxwm/src/cstartwindow.cxx | 196 ++++++++++++++++-- nxwm/src/ctaskbar.cxx | 9 +- nxwm/src/cwindowcontrol.cxx | 151 ++++++++++---- 42 files changed, 902 insertions(+), 223 deletions(-) mode change 100755 => 100644 ChangeLog.txt mode change 100755 => 100644 README.txt mode change 100755 => 100644 ReleaseNotes.txt mode change 100755 => 100644 TODO.txt mode change 100755 => 100644 UnitTests/CButton/cbutton-pushed.png mode change 100755 => 100644 UnitTests/CButton/cbutton-released.png mode change 100755 => 100644 UnitTests/CButtonArray/cbuttonarray.png mode change 100755 => 100644 UnitTests/CCheckBox/ccheckbox.png mode change 100755 => 100644 UnitTests/CLabel/clabel.png mode change 100755 => 100644 UnitTests/CProgressBar/cprogressbar.png mode change 100755 => 100644 UnitTests/CRadioButton/cradiobutton.png mode change 100755 => 100644 UnitTests/CScrollbarHorizontal/cscrollbarhorizontal.png mode change 100755 => 100644 UnitTests/CScrollbarVertical/cscrollbarvertical.png mode change 100755 => 100644 UnitTests/CSliderHorizonal/csliderhorizontal.png mode change 100755 => 100644 UnitTests/CSliderVertical/cslidervertical.png mode change 100755 => 100644 UnitTests/CTextBox/ctextbox.png mode change 100755 => 100644 UnitTests/TestStatus.txt create mode 100644 nxwm/doc/NxWM-ThreadingModel.ppt diff --git a/ChangeLog.txt b/ChangeLog.txt old mode 100755 new mode 100644 index 0e93187c1..1a51aacda --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -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. diff --git a/README.txt b/README.txt old mode 100755 new mode 100644 diff --git a/ReleaseNotes.txt b/ReleaseNotes.txt old mode 100755 new mode 100644 diff --git a/TODO.txt b/TODO.txt old mode 100755 new mode 100644 index 2a55c8197..009ce9039 --- a/TODO.txt +++ b/TODO.txt @@ -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 \ No newline at end of file diff --git a/UnitTests/CButton/cbutton-pushed.png b/UnitTests/CButton/cbutton-pushed.png old mode 100755 new mode 100644 diff --git a/UnitTests/CButton/cbutton-released.png b/UnitTests/CButton/cbutton-released.png old mode 100755 new mode 100644 diff --git a/UnitTests/CButtonArray/cbuttonarray.png b/UnitTests/CButtonArray/cbuttonarray.png old mode 100755 new mode 100644 diff --git a/UnitTests/CCheckBox/ccheckbox.png b/UnitTests/CCheckBox/ccheckbox.png old mode 100755 new mode 100644 diff --git a/UnitTests/CLabel/clabel.png b/UnitTests/CLabel/clabel.png old mode 100755 new mode 100644 diff --git a/UnitTests/CProgressBar/cprogressbar.png b/UnitTests/CProgressBar/cprogressbar.png old mode 100755 new mode 100644 diff --git a/UnitTests/CRadioButton/cradiobutton.png b/UnitTests/CRadioButton/cradiobutton.png old mode 100755 new mode 100644 diff --git a/UnitTests/CScrollbarHorizontal/cscrollbarhorizontal.png b/UnitTests/CScrollbarHorizontal/cscrollbarhorizontal.png old mode 100755 new mode 100644 diff --git a/UnitTests/CScrollbarVertical/cscrollbarvertical.png b/UnitTests/CScrollbarVertical/cscrollbarvertical.png old mode 100755 new mode 100644 diff --git a/UnitTests/CSliderHorizonal/csliderhorizontal.png b/UnitTests/CSliderHorizonal/csliderhorizontal.png old mode 100755 new mode 100644 diff --git a/UnitTests/CSliderVertical/cslidervertical.png b/UnitTests/CSliderVertical/cslidervertical.png old mode 100755 new mode 100644 diff --git a/UnitTests/CTextBox/ctextbox.png b/UnitTests/CTextBox/ctextbox.png old mode 100755 new mode 100644 diff --git a/UnitTests/README.txt b/UnitTests/README.txt index f501f30f6..cc01c3855 100644 --- a/UnitTests/README.txt +++ b/UnitTests/README.txt @@ -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 ======= diff --git a/UnitTests/TestStatus.txt b/UnitTests/TestStatus.txt old mode 100755 new mode 100644 diff --git a/UnitTests/nxwm/main.cxx b/UnitTests/nxwm/main.cxx index d4b7caa6b..6a2e952d8 100644 --- a/UnitTests/nxwm/main.cxx +++ b/UnitTests/nxwm/main.cxx @@ -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; } diff --git a/libnxwidgets/include/cwidgetcontrol.hxx b/libnxwidgets/include/cwidgetcontrol.hxx index 565e9cc36..757dc1c5b 100644 --- a/libnxwidgets/include/cwidgetcontrol.hxx +++ b/libnxwidgets/include/cwidgetcontrol.hxx @@ -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) diff --git a/libnxwidgets/src/cnxtkwindow.cxx b/libnxwidgets/src/cnxtkwindow.cxx index f1ea58692..6a9c115e1 100644 --- a/libnxwidgets/src/cnxtkwindow.cxx +++ b/libnxwidgets/src/cnxtkwindow.cxx @@ -36,7 +36,7 @@ /**************************************************************************** * Included Files ****************************************************************************/ - + #include #include @@ -152,7 +152,7 @@ CNxToolbar *CNxTkWindow::openToolbar(nxgl_coord_t height, CWidgetControl *widget { // Create a new widget control if none was provided - CWidgetControl *allocControl = (CWidgetControl *)0; + CWidgetControl *allocControl = (CWidgetControl *)0; if (!widgetControl) { // 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(); // Get the physical bounding box of the window in display coordinates - + struct nxgl_rect_s windowBounds; m_widgetControl->getWindowBoundingBox(&windowBounds); diff --git a/libnxwidgets/src/cnxtoolbar.cxx b/libnxwidgets/src/cnxtoolbar.cxx index b14a0b611..12b6bea4c 100644 --- a/libnxwidgets/src/cnxtoolbar.cxx +++ b/libnxwidgets/src/cnxtoolbar.cxx @@ -36,7 +36,7 @@ /**************************************************************************** * Included Files ****************************************************************************/ - + #include #include diff --git a/libnxwidgets/src/cwidgetcontrol.cxx b/libnxwidgets/src/cwidgetcontrol.cxx index 286c9c46a..9d2c5c7e9 100644 --- a/libnxwidgets/src/cwidgetcontrol.cxx +++ b/libnxwidgets/src/cwidgetcontrol.cxx @@ -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(); diff --git a/libnxwidgets/src/cwidgeteventhandlerlist.cxx b/libnxwidgets/src/cwidgeteventhandlerlist.cxx index 91722725a..bebab89aa 100644 --- a/libnxwidgets/src/cwidgeteventhandlerlist.cxx +++ b/libnxwidgets/src/cwidgeteventhandlerlist.cxx @@ -100,7 +100,7 @@ using namespace NXWidgets; CWidgetEventHandlerList::CWidgetEventHandlerList(CNxWidget *widget) { - m_widget = widget; + m_widget = widget; m_isEnabled = true; } @@ -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); } diff --git a/libnxwidgets/src/cwindoweventhandlerlist.cxx b/libnxwidgets/src/cwindoweventhandlerlist.cxx index 1c95264d1..5f3048b63 100644 --- a/libnxwidgets/src/cwindoweventhandlerlist.cxx +++ b/libnxwidgets/src/cwindoweventhandlerlist.cxx @@ -159,3 +159,4 @@ void CWindowEventHandlerList::raiseKeyboardEvent(void) } #endif } + diff --git a/nxwm/doc/NxWM-ThreadingModel.ppt b/nxwm/doc/NxWM-ThreadingModel.ppt new file mode 100644 index 0000000000000000000000000000000000000000..382f69dd84bc787bb639cc4ffe0563e0affb942c GIT binary patch literal 92672 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 literal 0 HcmV?d00001 diff --git a/nxwm/include/capplicationwindow.hxx b/nxwm/include/capplicationwindow.hxx index 8eda8d28a..f923f28b4 100644 --- a/nxwm/include/capplicationwindow.hxx +++ b/nxwm/include/capplicationwindow.hxx @@ -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 * diff --git a/nxwm/include/ccalibration.hxx b/nxwm/include/ccalibration.hxx index 3d90d59a8..55cef6d84 100644 --- a/nxwm/include/ccalibration.hxx +++ b/nxwm/include/ccalibration.hxx @@ -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 diff --git a/nxwm/include/cfullscreenwindow.hxx b/nxwm/include/cfullscreenwindow.hxx index 3c4117689..2e3fbd45d 100644 --- a/nxwm/include/cfullscreenwindow.hxx +++ b/nxwm/include/cfullscreenwindow.hxx @@ -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 * diff --git a/nxwm/include/cnxconsole.hxx b/nxwm/include/cnxconsole.hxx index 91fb941d8..b95c86406 100644 --- a/nxwm/include/cnxconsole.hxx +++ b/nxwm/include/cnxconsole.hxx @@ -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 diff --git a/nxwm/include/cstartwindow.hxx b/nxwm/include/cstartwindow.hxx index d0ae5ec84..b0cad6127 100644 --- a/nxwm/include/cstartwindow.hxx +++ b/nxwm/include/cstartwindow.hxx @@ -42,6 +42,8 @@ #include +#include + #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 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 diff --git a/nxwm/include/cwindowcontrol.hxx b/nxwm/include/cwindowcontrol.hxx index acec12727..91e430c5c 100644 --- a/nxwm/include/cwindowcontrol.hxx +++ b/nxwm/include/cwindowcontrol.hxx @@ -43,6 +43,8 @@ #include #include +#include + #include #include @@ -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 diff --git a/nxwm/include/iapplication.hxx b/nxwm/include/iapplication.hxx index 0d33db7bc..45067d900 100644 --- a/nxwm/include/iapplication.hxx +++ b/nxwm/include/iapplication.hxx @@ -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 diff --git a/nxwm/include/iapplicationwindow.hxx b/nxwm/include/iapplicationwindow.hxx index b00a03fa2..fe8830c2f 100644 --- a/nxwm/include/iapplicationwindow.hxx +++ b/nxwm/include/iapplicationwindow.hxx @@ -42,13 +42,10 @@ #include -#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 * diff --git a/nxwm/include/nxwmconfig.hxx b/nxwm/include/nxwmconfig.hxx index 34721d777..3605f8c4f 100644 --- a/nxwm/include/nxwmconfig.hxx +++ b/nxwm/include/nxwmconfig.hxx @@ -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 ******************************************************/ diff --git a/nxwm/src/capplicationwindow.cxx b/nxwm/src/capplicationwindow.cxx index df8c69f11..15d4a4a9d 100644 --- a/nxwm/src/capplicationwindow.cxx +++ b/nxwm/src/capplicationwindow.cxx @@ -413,6 +413,18 @@ NXWidgets::INxWindow *CApplicationWindow::getWindow(void) const return static_cast(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(control); +} + /** * Set the window label * diff --git a/nxwm/src/ccalibration.cxx b/nxwm/src/ccalibration.cxx index 2f9adb2e0..248aca838 100644 --- a/nxwm/src/ccalibration.cxx +++ b/nxwm/src/ccalibration.cxx @@ -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 @@ -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(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; +} diff --git a/nxwm/src/cfullscreenwindow.cxx b/nxwm/src/cfullscreenwindow.cxx index 7d63b02d7..40647d8e9 100644 --- a/nxwm/src/cfullscreenwindow.cxx +++ b/nxwm/src/cfullscreenwindow.cxx @@ -127,6 +127,18 @@ NXWidgets::INxWindow *CFullScreenWindow::getWindow(void) const return static_cast(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(control); +} + /** * Set the window label * diff --git a/nxwm/src/cnxconsole.cxx b/nxwm/src/cnxconsole.cxx index ec43c5656..577bf661e 100644 --- a/nxwm/src/cnxconsole.cxx +++ b/nxwm/src/cnxconsole.cxx @@ -47,6 +47,7 @@ #include #include #include +#include #include @@ -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(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(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. diff --git a/nxwm/src/cstartwindow.cxx b/nxwm/src/cstartwindow.cxx index de35662d5..1c997fbb7 100644 --- a/nxwm/src/cstartwindow.cxx +++ b/nxwm/src/cstartwindow.cxx @@ -39,6 +39,13 @@ #include +#include +#include +#include +#include + +#include + #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 - // 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; } } diff --git a/nxwm/src/ctaskbar.cxx b/nxwm/src/ctaskbar.cxx index ec3d8460b..ab686f81c 100644 --- a/nxwm/src/ctaskbar.cxx +++ b/nxwm/src/ctaskbar.cxx @@ -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(); diff --git a/nxwm/src/cwindowcontrol.cxx b/nxwm/src/cwindowcontrol.cxx index 841397a14..2c575d35b 100644 --- a/nxwm/src/cwindowcontrol.cxx +++ b/nxwm/src/cwindowcontrol.cxx @@ -36,9 +36,16 @@ /******************************************************************************************** * Included Files ********************************************************************************************/ - + #include +#include +#include + +#include + +#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 - // 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. + // 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 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(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 @@ -119,25 +186,39 @@ void CWindowControl::handleKeyboardEvent(void) { // The logic path here is tortuous but flexible: // - // 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 - // 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. + // 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 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(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 - -