summaryrefslogtreecommitdiff
path: root/NxWidgets/nxwm/src
diff options
context:
space:
mode:
Diffstat (limited to 'NxWidgets/nxwm/src')
-rw-r--r--NxWidgets/nxwm/src/capplicationwindow.cxx12
-rw-r--r--NxWidgets/nxwm/src/ccalibration.cxx74
-rw-r--r--NxWidgets/nxwm/src/cfullscreenwindow.cxx12
-rw-r--r--NxWidgets/nxwm/src/cnxconsole.cxx72
-rw-r--r--NxWidgets/nxwm/src/cstartwindow.cxx196
-rw-r--r--NxWidgets/nxwm/src/ctaskbar.cxx9
-rw-r--r--NxWidgets/nxwm/src/cwindowcontrol.cxx159
7 files changed, 471 insertions, 63 deletions
diff --git a/NxWidgets/nxwm/src/capplicationwindow.cxx b/NxWidgets/nxwm/src/capplicationwindow.cxx
index df8c69f11..15d4a4a9d 100644
--- a/NxWidgets/nxwm/src/capplicationwindow.cxx
+++ b/NxWidgets/nxwm/src/capplicationwindow.cxx
@@ -414,6 +414,18 @@ NXWidgets::INxWindow *CApplicationWindow::getWindow(void) const
}
/**
+ * 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
*
* @param appname. The name of the application to place on the window
diff --git a/NxWidgets/nxwm/src/ccalibration.cxx b/NxWidgets/nxwm/src/ccalibration.cxx
index 2f9adb2e0..248aca838 100644
--- a/NxWidgets/nxwm/src/ccalibration.cxx
+++ b/NxWidgets/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 <gnutt@nuttx.org>
@@ -107,6 +107,11 @@ CCalibration::CCalibration(CTaskbar *taskbar, CFullScreenWindow *window,
CCalibration::~CCalibration(void)
{
+ // Make sure that the application is not running (it should already
+ // have been stopped)
+
+ stop();
+
// Although we did not create the window, the rule is that I have to dispose
// of it
@@ -788,4 +793,71 @@ bool CCalibration::createCalibrationData(struct SCalibrationData &data)
return true;
}
+/**
+ * CCalibrationFactory Constructor
+ *
+ * @param taskbar. The taskbar instance used to terminate calibration
+ * @param touchscreen. An instance of the class that wraps the
+ * touchscreen device.
+ */
+
+CCalibrationFactory::CCalibrationFactory(CTaskbar *taskbar, CTouchscreen *touchscreen)
+{
+ m_taskbar = taskbar;
+ m_touchscreen = touchscreen;
+}
+
+/**
+ * Create a new instance of an CCalibration (as IApplication).
+ */
+
+IApplication *CCalibrationFactory::create(void)
+{
+ // Call CTaskBar::openFullScreenWindow to create a full screen window for
+ // the calibation application
+
+ CFullScreenWindow *window = m_taskbar->openFullScreenWindow();
+ if (!window)
+ {
+ gdbg("ERROR: Failed to create CFullScreenWindow\n");
+ return (IApplication *)0;
+ }
+
+ // Open the window (it is hot in here)
+
+ if (!window->open())
+ {
+ gdbg("ERROR: Failed to open CFullScreenWindow \n");
+ delete window;
+ return (IApplication *)0;
+ }
+ // Instantiate the application, providing the window to the application's
+ // constructor
+
+ CCalibration *calibration = new CCalibration(m_taskbar, window, m_touchscreen);
+ if (!calibration)
+ {
+ gdbg("ERROR: Failed to instantiate CCalibration\n");
+ delete window;
+ return (IApplication *)0;
+ }
+
+ return static_cast<IApplication*>(calibration);
+}
+
+/**
+ * Get the icon associated with the application
+ *
+ * @return An instance if IBitmap that may be used to rend the
+ * application's icon. This is an new IBitmap instance that must
+ * be deleted by the caller when it is no long needed.
+ */
+
+NXWidgets::IBitmap *CCalibrationFactory::getIcon(void)
+{
+ NXWidgets::CRlePaletteBitmap *bitmap =
+ new NXWidgets::CRlePaletteBitmap(&CONFIG_NXWM_CALIBRATION_ICON);
+
+ return bitmap;
+}
diff --git a/NxWidgets/nxwm/src/cfullscreenwindow.cxx b/NxWidgets/nxwm/src/cfullscreenwindow.cxx
index 7d63b02d7..40647d8e9 100644
--- a/NxWidgets/nxwm/src/cfullscreenwindow.cxx
+++ b/NxWidgets/nxwm/src/cfullscreenwindow.cxx
@@ -128,6 +128,18 @@ NXWidgets::INxWindow *CFullScreenWindow::getWindow(void) const
}
/**
+ * 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
*
* @param appname. The name of the application to place on the window
diff --git a/NxWidgets/nxwm/src/cnxconsole.cxx b/NxWidgets/nxwm/src/cnxconsole.cxx
index ec43c5656..577bf661e 100644
--- a/NxWidgets/nxwm/src/cnxconsole.cxx
+++ b/NxWidgets/nxwm/src/cnxconsole.cxx
@@ -47,6 +47,7 @@
#include <fcntl.h>
#include <semaphore.h>
#include <sched.h>
+#include <debug.h>
#include <apps/nsh.h>
@@ -141,6 +142,11 @@ CNxConsole::CNxConsole(CTaskbar *taskbar, CApplicationWindow *window)
CNxConsole::~CNxConsole(void)
{
+ // There would be a problem if we were stopped with the NxConsole task
+ // running... that should never happen but we'll check anyway:
+
+ stop();
+
// Although we didn't create it, we are responsible for deleting the
// application window
@@ -505,6 +511,72 @@ void CNxConsole::close(void)
}
/**
+ * CNxConsoleFactory Constructor
+ *
+ * @param taskbar. The taskbar instance used to terminate the console
+ */
+
+CNxConsoleFactory::CNxConsoleFactory(CTaskbar *taskbar)
+{
+ m_taskbar = taskbar;
+}
+
+/**
+ * Create a new instance of an CNxConsole (as IApplication).
+ */
+
+IApplication *CNxConsoleFactory::create(void)
+{
+ // Call CTaskBar::openFullScreenWindow to create a full screen window for
+ // the NxConsole application
+
+ CApplicationWindow *window = m_taskbar->openApplicationWindow();
+ if (!window)
+ {
+ gdbg("ERROR: Failed to create CApplicationWindow\n");
+ return (IApplication *)0;
+ }
+
+ // Open the window (it is hot in here)
+
+ if (!window->open())
+ {
+ gdbg("ERROR: Failed to open CApplicationWindow\n");
+ delete window;
+ return (IApplication *)0;
+ }
+
+ // Instantiate the application, providing the window to the application's
+ // constructor
+
+ CNxConsole *nxconsole = new CNxConsole(m_taskbar, window);
+ if (!nxconsole)
+ {
+ gdbg("ERROR: Failed to instantiate CNxConsole\n");
+ delete window;
+ return (IApplication *)0;
+ }
+
+ return static_cast<IApplication*>(nxconsole);
+}
+
+/**
+ * Get the icon associated with the application
+ *
+ * @return An instance if IBitmap that may be used to rend the
+ * application's icon. This is an new IBitmap instance that must
+ * be deleted by the caller when it is no long needed.
+ */
+
+NXWidgets::IBitmap *CNxConsoleFactory::getIcon(void)
+{
+ NXWidgets::CRlePaletteBitmap *bitmap =
+ new NXWidgets::CRlePaletteBitmap(&CONFIG_NXWM_NXCONSOLE_ICON);
+
+ return bitmap;
+}
+
+/**
* One time NSH initialization. This function must be called exactly
* once during the boot-up sequence to initialize the NSH library.
*
diff --git a/NxWidgets/nxwm/src/cstartwindow.cxx b/NxWidgets/nxwm/src/cstartwindow.cxx
index de35662d5..1c997fbb7 100644
--- a/NxWidgets/nxwm/src/cstartwindow.cxx
+++ b/NxWidgets/nxwm/src/cstartwindow.cxx
@@ -39,6 +39,13 @@
#include <nuttx/config.h>
+#include <cstdlib>
+#include <cfcntl>
+#include <csched>
+#include <cerrno>
+
+#include <mqueue.h>
+
#include "cwidgetcontrol.hxx"
#include "nxwmconfig.hxx"
@@ -51,7 +58,7 @@
********************************************************************************************/
/********************************************************************************************
- * CNxConsole Method Implementations
+ * CStartWindow Method Implementations
********************************************************************************************/
using namespace NxWM;
@@ -70,6 +77,10 @@ CStartWindow::CStartWindow(CTaskbar *taskbar, CApplicationWindow *window)
m_taskbar = taskbar;
m_window = window;
+ // The start window task is not running
+
+ m_taskId = -1;
+
// Add our personalized window label
NXWidgets::CNxString myName = getName();
@@ -86,6 +97,11 @@ CStartWindow::CStartWindow(CTaskbar *taskbar, CApplicationWindow *window)
CStartWindow::~CStartWindow(void)
{
+ // There would be a problem if we were stopped with the start window task
+ // running... that should never happen but we'll check anyway:
+
+ stop();
+
// Although we didn't create it, we are responsible for deleting the
// application window
@@ -96,7 +112,7 @@ CStartWindow::~CStartWindow(void)
// Then stop and delete all applications
- stopAllApplications();
+ removeAllApplications();
}
/**
@@ -144,9 +160,24 @@ NXWidgets::CNxString CStartWindow::getName(void)
bool CStartWindow::run(void)
{
- // We don't have a thread of execution. We only respond to button presses
+ // Some sanity checking
- return true;
+ if (m_taskId >= 0)
+ {
+ // The start window task is already running???
+
+ return false;
+ }
+
+ // Start the start window task
+
+ m_taskId = TASK_CREATE("StartWindow", CONFIG_NXWM_STARTWINDOW_PRIO,
+ CONFIG_NXWM_STARTWINDOW_STACKSIZE, startWindow,
+ (FAR const char **)0);
+
+ // Did we successfully start the NxConsole task?
+
+ return m_taskId >= 0;
}
/**
@@ -155,7 +186,20 @@ bool CStartWindow::run(void)
void CStartWindow::stop(void)
{
- // We don't have a thread of execution. We only respond to button presses
+ // Delete the start window task --- what are we doing? This should never
+ // happen because the start window task is persistent!
+
+ if (m_taskId >= 0)
+ {
+ // Call task_delete(), possibly stranding resources
+
+ pid_t pid = m_taskId;
+ m_taskId = -1;
+
+ // Then delete the NSH task
+
+ task_delete(pid);
+ }
}
/**
@@ -293,21 +337,17 @@ bool CStartWindow::isFullScreen(void) const
}
/**
- * Add the application to the start window. The general sequence for
- * setting up the start window is:
+ * Add the application to the start window. The general sequence is:
*
- * 1. Call CTaskBar::openApplicationWindow to create a window for the start window,
- * 2. Use the window to instantiate CStartWindow
- * 3. Call CStartWindow::addApplication numerous times to install applications
- * in the start window.
- * 4. Call CTaskBar::startApplication (initially minimized) to start the start
- * window application.
+ * 1. Call IAppicationFactory::create to a new instance of the application
+ * 2. Call CStartWindow::addApplication to add the application to the
+ * start window.
*
* @param app. The new application to add to the start window
* @return true on success
*/
-bool CStartWindow::addApplication(IApplication *app)
+bool CStartWindow::addApplication(IApplicationFactory *app)
{
// Recover the NXTK window instance contained in the application window
@@ -418,18 +458,17 @@ void CStartWindow::getIconBounds(void)
* Stop all applications
*/
-void CStartWindow::stopAllApplications(void)
+void CStartWindow::removeAllApplications(void)
{
- // Stop all applications and remove them from the task bar. Clearly, there
+ // Stop all applications and remove them from the start window. Clearly, there
// are some ordering issues here... On an orderly system shutdown, disconnection
// should really occur priority to deleting instances
while (!m_slots.empty())
{
- // Stop the application (and remove it from the task bar)
+ // Remove the application factory from the start menu
- IApplication *app = m_slots.at(0).app;
- m_taskbar->stopApplication(app);
+ IApplicationFactory *app = m_slots.at(0).app;
// Now, delete the image and the application
@@ -459,12 +498,125 @@ void CStartWindow::handleActionEvent(const NXWidgets::CWidgetEventArgs &e)
NXWidgets::CImage *image = m_slots.at(i).image;
if (image->isClicked())
{
- // Start a new copy of the application
+ // Create a new copy of the application
- m_taskbar->startApplication(m_slots.at(i).app, false);
+ IApplication *app = m_slots.at(i).app->create();
+ if (app)
+ {
+ // Start the new copy of the application
+
+ if (m_taskbar->startApplication(app, false))
+ {
+ // Then break out of the loop
+
+ break;
+ }
+ else
+ {
+ // If we cannot start the app. Destroy the
+ // instance we created and see what happens next.
+
+ CWindowControl *control = app->getWindowControl();
+ control->destroy(app);
+ }
+ }
+ }
+ }
+}
- // Then break out of the loop
+/**
+ * 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/NxWidgets/nxwm/src/ctaskbar.cxx b/NxWidgets/nxwm/src/ctaskbar.cxx
index ec3d8460b..ab686f81c 100644
--- a/NxWidgets/nxwm/src/ctaskbar.cxx
+++ b/NxWidgets/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/NxWidgets/nxwm/src/cwindowcontrol.cxx b/NxWidgets/nxwm/src/cwindowcontrol.cxx
index 841397a14..2c575d35b 100644
--- a/NxWidgets/nxwm/src/cwindowcontrol.cxx
+++ b/NxWidgets/nxwm/src/cwindowcontrol.cxx
@@ -36,9 +36,16 @@
/********************************************************************************************
* Included Files
********************************************************************************************/
-
+
#include <nuttx/config.h>
+#include <cfcntl>
+#include <cerrno>
+
+#include <debug.h>
+
+#include "nxwmconfig.hxx"
+#include "cstartwindow.hxx"
#include "cwindowcontrol.hxx"
/********************************************************************************************
@@ -62,6 +69,20 @@ using namespace NxWM;
CWindowControl::CWindowControl(FAR const NXWidgets::CWidgetStyle *style)
: NXWidgets::CWidgetControl(style)
{
+ // Open a message queue to communicate with the start window task. We need to create
+ // the message queue if it does not exist.
+
+ struct mq_attr attr;
+ attr.mq_maxmsg = CONFIG_NXWM_STARTWINDOW_MXMSGS;
+ attr.mq_msgsize = sizeof(struct SStartWindowMessage);
+ attr.mq_flags = 0;
+
+ m_mqd = mq_open(CONFIG_NXWM_STARTWINDOW_MQNAME, O_WRONLY|O_CREAT, 0666, &attr);
+ if (m_mqd == (mqd_t)-1)
+ {
+ gdbg("ERROR: mq_open(%s) failed: %d\n", CONFIG_NXWM_STARTWINDOW_MQNAME, errno);
+ }
+
// Add ourself as the window callback
addWindowEventHandler(this);
@@ -73,12 +94,42 @@ 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.
*
* @param e The event data.
@@ -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.
-
- // Perform the poll
-
- pollEvents();
+ // 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()
+
+ struct SStartWindowMessage outmsg;
+ outmsg.msgId = MSGID_MOUSE_INPUT;
+ outmsg.instance = (FAR void *)static_cast<CWidgetControl*>(this);
+
+ 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.
-
- // Perform the poll
-
- pollEvents();
+ // 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()
+
+ struct SStartWindowMessage outmsg;
+ outmsg.msgId = MSGID_KEYBOARD_INPUT;
+ outmsg.instance = (FAR void *)static_cast<CWidgetControl*>(this);
+
+ 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
-
-