summaryrefslogtreecommitdiff
path: root/NxWidgets
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-05-14 20:46:47 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-05-14 20:46:47 +0000
commit8c194ec17b4fc4810bde451e803d9cb29db28e59 (patch)
tree5828697d06531c289a2027a08cf997598923738d /NxWidgets
parent85875d96df46aefef80c0fa242525646b4090247 (diff)
downloadpx4-nuttx-8c194ec17b4fc4810bde451e803d9cb29db28e59.tar.gz
px4-nuttx-8c194ec17b4fc4810bde451e803d9cb29db28e59.tar.bz2
px4-nuttx-8c194ec17b4fc4810bde451e803d9cb29db28e59.zip
NxWM: Calibration is now done on a separate thread; Change mechanism for reporting calibration data; add method to determine if the application is full-screen
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4736 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'NxWidgets')
-rwxr-xr-xNxWidgets/ChangeLog.txt14
-rw-r--r--NxWidgets/UnitTests/nxwm/main.cxx139
-rw-r--r--NxWidgets/nxwm/include/capplicationwindow.hxx10
-rw-r--r--NxWidgets/nxwm/include/ccalibration.hxx105
-rw-r--r--NxWidgets/nxwm/include/cfullscreenwindow.hxx10
-rw-r--r--NxWidgets/nxwm/include/cnxconsole.hxx10
-rw-r--r--NxWidgets/nxwm/include/cstartwindow.hxx10
-rw-r--r--NxWidgets/nxwm/include/ctouchscreen.hxx29
-rw-r--r--NxWidgets/nxwm/include/iapplication.hxx10
-rw-r--r--NxWidgets/nxwm/include/iapplicationwindow.hxx10
-rw-r--r--NxWidgets/nxwm/include/nxwmconfig.hxx30
-rw-r--r--NxWidgets/nxwm/src/capplicationwindow.cxx13
-rw-r--r--NxWidgets/nxwm/src/ccalibration.cxx458
-rw-r--r--NxWidgets/nxwm/src/cfullscreenwindow.cxx13
-rw-r--r--NxWidgets/nxwm/src/cnxconsole.cxx13
-rw-r--r--NxWidgets/nxwm/src/cstartwindow.cxx13
-rw-r--r--NxWidgets/nxwm/src/ctaskbar.cxx315
-rw-r--r--NxWidgets/nxwm/src/ctouchscreen.cxx8
18 files changed, 866 insertions, 344 deletions
diff --git a/NxWidgets/ChangeLog.txt b/NxWidgets/ChangeLog.txt
index 0cb95cc13..5b14799bd 100755
--- a/NxWidgets/ChangeLog.txt
+++ b/NxWidgets/ChangeLog.txt
@@ -70,4 +70,16 @@
a button. Probably should separate basic imaging functionality as CImage
and create a new CImageButton.
* NxWM::CStartWindow: Now ignores any close application button presses
- (You can't close the start window). \ No newline at end of file
+ (You can't close the start window).
+* NxWM::CCalibration: The calibration application now has its own thread.
+ This was necessary for a proper integration with the taskbar.
+* NxWM::CCalibration and NxWM:CTouchscreen: Changed the mechanism use
+ to report calbration data. It is now reported directly from CCalibration
+ to CTouchscreen. If external logic needs calibration, it can now get it
+ from CTouchscreen instead of CCalibration. This change was necessary
+ to make the termination conditions of CCalibration clean (it used to
+ have to persist until some external logic got the Calibration data).
+* IApplication, IApplicationWindow, and all classes that inherit from
+ these: Now support method to report if the application is a full-screen
+ or a normal application. This is necessary to prevent CTaskbar from
+ displaying a task bar on top of a full-screen window.
diff --git a/NxWidgets/UnitTests/nxwm/main.cxx b/NxWidgets/UnitTests/nxwm/main.cxx
index 9026a670e..d4b7caa6b 100644
--- a/NxWidgets/UnitTests/nxwm/main.cxx
+++ b/NxWidgets/UnitTests/nxwm/main.cxx
@@ -428,7 +428,7 @@ static bool createCalibration(void)
showTestCaseMemory("After initializing the calibration full screen window");
printf(MAIN_STRING "Creating CCalibration application\n");
- g_nxwmtest.calibration = new NxWM::CCalibration(window, g_nxwmtest.touchscreen);
+ g_nxwmtest.calibration = new NxWM::CCalibration(g_nxwmtest.taskbar, window, g_nxwmtest.touchscreen);
if (!g_nxwmtest.calibration)
{
printf(MAIN_STRING "ERROR: Failed to instantiate CCalibration\n");
@@ -436,24 +436,22 @@ static bool createCalibration(void)
return false;
}
showTestCaseMemory("After creating CCalibration application");
- return true;
-}
-#endif
-/////////////////////////////////////////////////////////////////////////////
-// Name: runCalibration
-/////////////////////////////////////////////////////////////////////////////
+ // 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
-#ifdef CONFIG_NXWM_TOUCHSCREEN
-static bool runCalibration(void)
-{
- // 1. Start the calibration application
- // 2. Wait until calibration data is available
- // 3. Stop the calibration application
- // 4. Provide the calibration data to the touchscreen device application
- // 5. Enable forwarding of touchscreen input
+ printf(MAIN_STRING "Adding CCalibration application to the start window\n");
+ if (!g_nxwmtest.startwindow->addApplication(g_nxwmtest.calibration))
+ {
+ printf(MAIN_STRING "ERROR: Failed to add CCalibration to the start window\n");
+ delete g_nxwmtest.calibration;
+ return false;
+ }
+ showTestCaseMemory("After adding CCalibration application");
- // Call CTaskBar::startApplication to start the Calibration application
+ // 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))
@@ -462,50 +460,6 @@ static bool runCalibration(void)
return false;
}
showTestCaseMemory("After starting the start window application");
-
- // Wait for calibration data
-
- printf(MAIN_STRING "Get calibration data\n");
- if (!g_nxwmtest.calibration->waitCalibrationData(g_nxwmtest.calibData))
- {
- printf(MAIN_STRING "ERROR: Failed to get calibration data\n");
- return false;
- }
- showTestCaseMemory("After getting calibration data");
-
- printf(MAIN_STRING "Stop the calibration application\n");
- if (!g_nxwmtest.taskbar->stopApplication(g_nxwmtest.calibration))
- {
- printf(MAIN_STRING "ERROR: Failed to stop the calibration application\n");
- return false;
- }
- showTestCaseMemory("After stopping the calibration application");
-
- // Configure the touchscreen device and enable touch forwarding
-
- g_nxwmtest.touchscreen->setCalibrationData(g_nxwmtest.calibData);
- g_nxwmtest.touchscreen->setEnabled(true);
- showTestCaseMemory("After givin calibration dato to the touchscreen device\n");
- return true;
-}
-#endif
-
-/////////////////////////////////////////////////////////////////////////////
-// Name: addCalibrationToStartWindow
-/////////////////////////////////////////////////////////////////////////////
-
-#ifdef CONFIG_NXWM_TOUCHSCREEN
-static bool addCalibrationToStartWindow(void)
-{
- 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");
return true;
}
#endif
@@ -613,6 +567,14 @@ int MAIN_NAME(int argc, char *argv[])
testCleanUpAndExit(EXIT_FAILURE);
}
+ // Create the start window.
+
+ if (!createStartWindow())
+ {
+ printf(MAIN_STRING "ERROR: Failed to create the start window\n");
+ testCleanUpAndExit(EXIT_FAILURE);
+ }
+
// Create the touchscreen device
#ifdef CONFIG_NXWM_TOUCHSCREEN
@@ -623,64 +585,55 @@ int MAIN_NAME(int argc, char *argv[])
}
#endif
- // Perform touchscreen calibration. In a real system, you would only do this
- // if you have no saved touchscreen calibration. In this Unit Test, we run
- // the calibration unconditionally.
+ // Create the calibration application and add it to the start window
#ifdef CONFIG_NXWM_TOUCHSCREEN
- // Create the calibration application
-
if (!createCalibration())
{
printf(MAIN_STRING "ERROR: Failed to create the calibration application\n");
testCleanUpAndExit(EXIT_FAILURE);
}
+#endif
- // Run the touchscreen calibration application
+ // Create the NxConsole application and add it to the start window
- if (!runCalibration())
+ if (!createNxConsole())
{
- printf(MAIN_STRING "ERROR: Touchscreen Calibration failed\n");
+ printf(MAIN_STRING "ERROR: Failed to create the NxConsole application\n");
testCleanUpAndExit(EXIT_FAILURE);
}
-#endif
-
- // Create the start window.
+ // Call CTaskBar::startWindowManager to start the display with applications in place.
- if (!createStartWindow())
+ if (!startWindowManager())
{
- printf(MAIN_STRING "ERROR: Failed to create the start window\n");
+ printf(MAIN_STRING "ERROR: Failed to start the window manager\n");
testCleanUpAndExit(EXIT_FAILURE);
}
#ifdef CONFIG_NXWM_TOUCHSCREEN
- // 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
-
- if (!addCalibrationToStartWindow())
- {
- printf(MAIN_STRING "ERROR: Failed to add calibration to the start window\n");
- testCleanUpAndExit(EXIT_FAILURE);
- }
-#endif
+ // Since we started the touchscreen calibration program maximized, it will run
+ // immediately when we start the window manager. There is no positive handshake
+ // to know whenthe touchscreen has been calibrated. If we really want to know,
+ // we have to poll
- // Add the NxConsole application to the start window
-
- if (!createNxConsole())
+ printf(MAIN_STRING "Waiting for touchscreen calibration\n");
+ while (!g_nxwmtest.touchscreen->isCalibrated())
{
- printf(MAIN_STRING "ERROR: Failed to create the NxConsole application\n");
- testCleanUpAndExit(EXIT_FAILURE);
+ std::sleep(2);
}
- // Call CTaskBar::startWindowManager to start the display with applications in place.
+ // This is how we would then recover the calibration data. After the calibration
+ // application creates the calibration data, it hands it to the touchscreen driver
+ // After the touchscreen driver gets it, it will report isCalibrated() == true
+ // and then we can read the calibration data from the touchscreen driver.
- if (!startWindowManager())
+ printf(MAIN_STRING "Getting calibration data from the touchscreen\n");
+ if (!g_nxwmtest.touchscreen->getCalibrationData(g_nxwmtest.calibData))
{
- printf(MAIN_STRING "ERROR: Failed to start the window manager\n");
- testCleanUpAndExit(EXIT_FAILURE);
- }
+ printf(MAIN_STRING "ERROR: Failed to get calibration data from the touchscreen\n");
+ }
+#endif
// Wait a little bit for the display to stabilize. The simulation pressing of
// the 'start window' icon in the task bar
diff --git a/NxWidgets/nxwm/include/capplicationwindow.hxx b/NxWidgets/nxwm/include/capplicationwindow.hxx
index 807f268a6..1a3d7eb48 100644
--- a/NxWidgets/nxwm/include/capplicationwindow.hxx
+++ b/NxWidgets/nxwm/include/capplicationwindow.hxx
@@ -159,6 +159,16 @@ namespace NxWM
void setWindowLabel(NXWidgets::CNxString &appname);
/**
+ * Report of this is a "normal" window or a full screen window. The
+ * primary purpose of this method is so that window manager will know
+ * whether or not it show draw the task bar.
+ *
+ * @return True if this is a full screen window.
+ */
+
+ bool isFullScreen(void) const;
+
+ /**
* Register to receive callbacks when toolbar icons are selected
*/
diff --git a/NxWidgets/nxwm/include/ccalibration.hxx b/NxWidgets/nxwm/include/ccalibration.hxx
index 535a14804..3d90d59a8 100644
--- a/NxWidgets/nxwm/include/ccalibration.hxx
+++ b/NxWidgets/nxwm/include/ccalibration.hxx
@@ -42,12 +42,14 @@
#include <nuttx/nx/nxglib.h>
+#include <pthread.h>
#include <fixedmath.h>
#include "cnxstring.hxx"
#include "cwidgeteventhandler.hxx"
#include "cwidgetcontrol.hxx"
+#include "ctaskbar.hxx"
#include "iapplication.hxx"
#include "cfullscreenwindow.hxx"
@@ -98,17 +100,32 @@ namespace NxWM
{
private:
/**
+ * The state of the calibration thread.
+ */
+
+ enum ECalThreadState
+ {
+ CALTHREAD_NOTRUNNING = 0, /**< The calibration thread has not yet been started */
+ CALTHREAD_STARTED, /**< The calibration thread has been started, but is not yet running */
+ CALTHREAD_RUNNING, /**< The calibration thread is running normally */
+ CALTHREAD_STOPREQUESTED, /**< The calibration thread has been requested to stop */
+ CALTHREAD_HIDE, /**< The hide() called by calibration thread running */
+ CALTHREAD_SHOW, /**< The redraw() called by calibration thread running */
+ CALTHREAD_TERMINATED /**< The calibration thread terminated normally */
+ };
+
+ /**
* Identifies the current display state
*/
- enum ECalibState
+ enum ECalibrationPhase
{
- CALIB_NOT_STARTED = 0, /**< Constructed, but not yet started */
- CALIB_UPPER_LEFT, /**< Touch point is in the upper left corner */
- CALIB_UPPER_RIGHT, /**< Touch point is in the upper right corner */
- CALIB_LOWER_RIGHT, /**< Touch point is in the lower left corner */
- CALIB_LOWER_LEFT, /**< Touch point is in the lower right corner */
- CALIB_COMPLETE /**< Calibration is complete */
+ CALPHASE_NOT_STARTED = 0, /**< Constructed, but not yet started */
+ CALPHASE_UPPER_LEFT, /**< Touch point is in the upper left corner */
+ CALPHASE_UPPER_RIGHT, /**< Touch point is in the upper right corner */
+ CALPHASE_LOWER_RIGHT, /**< Touch point is in the lower left corner */
+ CALPHASE_LOWER_LEFT, /**< Touch point is in the lower right corner */
+ CALPHASE_COMPLETE /**< Calibration is complete */
};
/**
@@ -126,15 +143,17 @@ namespace NxWM
* CCalibration state data
*/
+ CTaskbar *m_taskbar; /**< The taskbar (used to terminate calibration) */
CFullScreenWindow *m_window; /**< The window for the calibration display */
CTouchscreen *m_touchscreen; /**< The touchscreen device */
- enum ECalibState m_state; /**< Current calibration display state */
+ pthread_t m_thread; /**< The calibration thread ID */
struct SCalibScreenInfo m_screenInfo; /**< Describes the current calibration display */
struct nxgl_point_s m_touchPos; /**< This is the last touch position */
+ volatile uint8_t m_calthread; /**< Current calibration display state (See ECalibThreadState)*/
+ uint8_t m_calphase; /**< Current calibration display state (See ECalibrationPhase)*/
bool m_stop; /**< True: We have been asked to stop the calibration */
bool m_touched; /**< True: The screen is touched */
uint8_t m_touchId; /**< The ID of the touch */
- sem_t m_waitSem; /**< Supports wait for calibration data */
struct nxgl_point_s m_calibData[CALIB_DATA_POINTS];
/**
@@ -146,6 +165,42 @@ namespace NxWM
void touchscreenInput(struct touch_sample_s &sample);
/**
+ * Start the calibration thread.
+ *
+ * @param initialState. The initial state of the calibration thread
+ * @return True if the thread was successfully started.
+ */
+
+ bool startCalibration(enum ECalThreadState initialState);
+
+ /**
+ * Return true if the calibration thread is running normally. There are
+ * lots of potential race conditions. Let's hope that things are running
+ * orderly and we that we do not have to concern ourself with them
+ *
+ * @return True if the calibration thread is runnning normally.
+ */
+
+ inline bool isRunning(void) const
+ {
+ // What if the boundary states CALTHREAD_STARTED and CALTHREAD_STOPREQUESTED?
+
+ return (m_calthread == CALTHREAD_RUNNING ||
+ m_calthread == CALTHREAD_HIDE ||
+ m_calthread == CALTHREAD_SHOW);
+ }
+
+ /**
+ * The calibration thread. This is the entry point of a thread that provides the
+ * calibration displays, waits for input, and collects calibration data.
+ *
+ * @param arg. The CCalibration 'this' pointer cast to a void*.
+ * @return This function always returns NULL when the thread exits
+ */
+
+ static FAR void *calibration(FAR void *arg);
+
+ /**
* This is the calibration state machine. It is called initially and then
* as new touchscreen data is received.
*/
@@ -158,16 +213,36 @@ namespace NxWM
void showCalibration(void);
+ /**
+ * Finish calibration steps and provide the calibration data to the
+ * touchscreen driver.
+ */
+
+ void finishCalibration(void);
+
+ /**
+ * Given the raw touch data collected by the calibration thread, create the
+ * massaged calibration data needed by CTouchscreen.
+ *
+ * @param data. A reference to the location to save the calibration data
+ * @return True if the calibration data was successfully created.
+ */
+
+ bool createCalibrationData(struct SCalibrationData &data);
+
public:
/**
* CCalibration Constructor
*
+ * @param taskbar. The taskbar instance used to terminate calibration
* @param window. The window to use for the calibration display
- * @param touchscreen. An instance of the class that wraps the touchscreen device.
+ * @param touchscreen. An instance of the class that wraps the
+ * touchscreen device.
*/
- CCalibration(CFullScreenWindow *window, CTouchscreen *touchscreen);
+ CCalibration(CTaskbar *taskbar, CFullScreenWindow *window,
+ CTouchscreen *touchscreen);
/**
* CCalibration Destructor
@@ -230,12 +305,14 @@ namespace NxWM
void redraw(void);
/**
- * Wait for calibration data to be received.
+ * Report of this is a "normal" window or a full screen window. The
+ * primary purpose of this method is so that window manager will know
+ * whether or not it show draw the task bar.
*
- * @return True if the calibration data was successfully obtained.
+ * @return True if this is a full screen window.
*/
- bool waitCalibrationData(struct SCalibrationData &data);
+ bool isFullScreen(void) const;
};
}
diff --git a/NxWidgets/nxwm/include/cfullscreenwindow.hxx b/NxWidgets/nxwm/include/cfullscreenwindow.hxx
index fb4788830..3c4117689 100644
--- a/NxWidgets/nxwm/include/cfullscreenwindow.hxx
+++ b/NxWidgets/nxwm/include/cfullscreenwindow.hxx
@@ -123,6 +123,16 @@ namespace NxWM
void setWindowLabel(NXWidgets::CNxString &appname);
/**
+ * Report of this is a "normal" window or a full screen window. The
+ * primary purpose of this method is so that window manager will know
+ * whether or not it show draw the task bar.
+ *
+ * @return True if this is a full screen window.
+ */
+
+ bool isFullScreen(void) const;
+
+ /**
* Register to receive callbacks when toolbar icons are selected
*/
diff --git a/NxWidgets/nxwm/include/cnxconsole.hxx b/NxWidgets/nxwm/include/cnxconsole.hxx
index 1c7aab193..426cf165f 100644
--- a/NxWidgets/nxwm/include/cnxconsole.hxx
+++ b/NxWidgets/nxwm/include/cnxconsole.hxx
@@ -173,6 +173,16 @@ namespace NxWM
*/
void redraw(void);
+
+ /**
+ * Report of this is a "normal" window or a full screen window. The
+ * primary purpose of this method is so that window manager will know
+ * whether or not it show draw the task bar.
+ *
+ * @return True if this is a full screen window.
+ */
+
+ bool isFullScreen(void) const;
};
}
#endif // __cplusplus
diff --git a/NxWidgets/nxwm/include/cstartwindow.hxx b/NxWidgets/nxwm/include/cstartwindow.hxx
index a04a4f1a5..5a5ea12f4 100644
--- a/NxWidgets/nxwm/include/cstartwindow.hxx
+++ b/NxWidgets/nxwm/include/cstartwindow.hxx
@@ -189,6 +189,16 @@ namespace NxWM
void redraw(void);
/**
+ * Report of this is a "normal" window or a full screen window. The
+ * primary purpose of this method is so that window manager will know
+ * whether or not it show draw the task bar.
+ *
+ * @return True if this is a full screen window.
+ */
+
+ bool isFullScreen(void) const;
+
+ /**
* Add the application to the start window. The general sequence for
* setting up the start window is:
*
diff --git a/NxWidgets/nxwm/include/ctouchscreen.hxx b/NxWidgets/nxwm/include/ctouchscreen.hxx
index 52433c1de..396400204 100644
--- a/NxWidgets/nxwm/include/ctouchscreen.hxx
+++ b/NxWidgets/nxwm/include/ctouchscreen.hxx
@@ -167,6 +167,17 @@ namespace NxWM
}
/**
+ * Is the touchscreen calibrated?
+ *
+ * @return True if the touchscreen has been calibrated.
+ */
+
+ inline bool isCalibrated(void) const
+ {
+ return m_calibrated;
+ }
+
+ /**
* Provide touchscreen calibration data. If calibration data is received (and
* the touchscreen is enabled), then received touchscreen data will be scaled
* using the calibration data and forward to the NX layer which dispatches the
@@ -175,7 +186,23 @@ namespace NxWM
* @param data. A reference to the touchscreen data.
*/
- void setCalibrationData(struct SCalibrationData &caldata);
+ void setCalibrationData(const struct SCalibrationData &caldata);
+
+ /**
+ * Recover the calibration data so that it can be saved to non-volatile storage.
+ *
+ * @param data. A reference to the touchscreen data.
+ * @return True if calibration data was successfully returned.
+ */
+
+ inline bool getCalibrationData(struct SCalibrationData &caldata) const
+ {
+ if (m_calibrated)
+ {
+ caldata = m_calibData;
+ }
+ return m_calibrated;
+ }
/**
* Capture raw driver data. This method will capture mode one raw touchscreen
diff --git a/NxWidgets/nxwm/include/iapplication.hxx b/NxWidgets/nxwm/include/iapplication.hxx
index e92e1908e..0d33db7bc 100644
--- a/NxWidgets/nxwm/include/iapplication.hxx
+++ b/NxWidgets/nxwm/include/iapplication.hxx
@@ -170,6 +170,16 @@ namespace NxWM
{
return m_topapp;
}
+
+ /**
+ * Report of this is a "normal" window or a full screen window. The
+ * primary purpose of this method is so that window manager will know
+ * whether or not it show draw the task bar.
+ *
+ * @return True if this is a full screen window.
+ */
+
+ virtual bool isFullScreen(void) const = 0;
};
}
diff --git a/NxWidgets/nxwm/include/iapplicationwindow.hxx b/NxWidgets/nxwm/include/iapplicationwindow.hxx
index 115998775..b00a03fa2 100644
--- a/NxWidgets/nxwm/include/iapplicationwindow.hxx
+++ b/NxWidgets/nxwm/include/iapplicationwindow.hxx
@@ -130,6 +130,16 @@ namespace NxWM
virtual void setWindowLabel(NXWidgets::CNxString &appname) = 0;
/**
+ * Report of this is a "normal" window or a full screen window. The
+ * primary purpose of this method is so that window manager will know
+ * whether or not it show draw the task bar.
+ *
+ * @return True if this is a full screen window.
+ */
+
+ virtual bool isFullScreen(void) const = 0;
+
+ /**
* Register to receive callbacks when toolbar icons are selected
*/
diff --git a/NxWidgets/nxwm/include/nxwmconfig.hxx b/NxWidgets/nxwm/include/nxwmconfig.hxx
index 359f7d095..88c2ea8db 100644
--- a/NxWidgets/nxwm/include/nxwmconfig.hxx
+++ b/NxWidgets/nxwm/include/nxwmconfig.hxx
@@ -333,6 +333,10 @@
* Default: "/dev/input0"
* CONFIG_NXWM_TOUCHSCREEN_SIGNO - The realtime signal used to wake up the
* touchscreen listener thread. Default: 5
+ * 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
*/
#ifndef CONFIG_NXWM_TOUCHSCREEN_DEVNO
@@ -347,6 +351,14 @@
# define CONFIG_NXWM_TOUCHSCREEN_SIGNO 5
#endif
+#ifndef CONFIG_NXWM_TOUCHSCREEN_LISTENERPRIO
+# define CONFIG_NXWM_TOUCHSCREEN_LISTENERPRIO SCHED_PRIORITY_DEFAULT
+#endif
+
+#ifndef CONFIG_NXWM_TOUCHSCREEN_LISTENERSTACK
+# define CONFIG_NXWM_TOUCHSCREEN_LISTENERSTACK 2048
+#endif
+
/* Calibration display ******************************************************/
/**
* Calibration display settings:
@@ -363,6 +375,12 @@
* MKRGB(255, 255, 96) (very light yellow)
* CONFIG_NXWM_CALIBRATION_ICON - The ICON to use for the touchscreen
* calibration application. Default: NxWM::g_calibrationBitmap
+ * CONFIG_NXWM_CALIBRATION_SIGNO - The realtime signal used to wake up the
+ * touchscreen calibration thread. Default: 5
+ * CONFIG_NXWM_CALIBRATION_LISTENERPRIO - Priority of the touchscreen listener
+ * thread. Default: SCHED_PRIORITY_DEFAULT
+ * CONFIG_NXWM_CALIBRATION_LISTENERSTACK - Touchscreen listener thread stack
+ * size. Default 2048
*/
#ifndef CONFIG_NXWM_CALIBRATION_BACKGROUNDCOLOR
@@ -385,6 +403,18 @@
# define CONFIG_NXWM_CALIBRATION_ICON NxWM::g_calibrationBitmap
#endif
+#ifndef CONFIG_NXWM_CALIBRATION_SIGNO
+# define CONFIG_NXWM_CALIBRATION_SIGNO 5
+#endif
+
+#ifndef CONFIG_NXWM_CALIBRATION_LISTENERPRIO
+# define CONFIG_NXWM_CALIBRATION_LISTENERPRIO SCHED_PRIORITY_DEFAULT
+#endif
+
+#ifndef CONFIG_NXWM_CALIBRATION_LISTENERSTACK
+# define CONFIG_NXWM_CALIBRATION_LISTENERSTACK 2048
+#endif
+
/****************************************************************************
* Global Function Prototypes
****************************************************************************/
diff --git a/NxWidgets/nxwm/src/capplicationwindow.cxx b/NxWidgets/nxwm/src/capplicationwindow.cxx
index d2190cd24..60ab5a3d3 100644
--- a/NxWidgets/nxwm/src/capplicationwindow.cxx
+++ b/NxWidgets/nxwm/src/capplicationwindow.cxx
@@ -425,6 +425,19 @@ void CApplicationWindow::setWindowLabel(NXWidgets::CNxString &appname)
}
/**
+ * Report of this is a "normal" window or a full screen window. The
+ * primary purpose of this method is so that window manager will know
+ * whether or not it show draw the task bar.
+ *
+ * @return True if this is a full screen window.
+ */
+
+bool CApplicationWindow::isFullScreen(void) const
+{
+ return false;
+}
+
+/**
* Register to receive callbacks when toolbar icons are selected
*/
diff --git a/NxWidgets/nxwm/src/ccalibration.cxx b/NxWidgets/nxwm/src/ccalibration.cxx
index 1fc9f3466..2f9adb2e0 100644
--- a/NxWidgets/nxwm/src/ccalibration.cxx
+++ b/NxWidgets/nxwm/src/ccalibration.cxx
@@ -37,8 +37,11 @@
* Included Files
****************************************************************************/
+#include <cunistd>
+#include <cerrno>
+
+#include <sched.h>
#include <assert.h>
-#include <errno.h>
#include <debug.h>
#include "nxwmconfig.hxx"
@@ -78,18 +81,23 @@ using namespace NxWM;
/**
* CCalibration Constructor
*
+ * @param taskbar. The taskbar instance used to terminate calibration
* @param window. The window to use for the calibration display
- * @param touchscreen. An instance of the class that wraps the touchscreen device.
+ * @param touchscreen. An instance of the class that wraps the touchscreen
+ * device.
*/
-CCalibration::CCalibration(CFullScreenWindow *window, CTouchscreen *touchscreen)
+CCalibration::CCalibration(CTaskbar *taskbar, CFullScreenWindow *window,
+ CTouchscreen *touchscreen)
{
// Initialize state data
+ m_taskbar = taskbar;
m_window = window;
m_touchscreen = touchscreen;
- m_state = CALIB_NOT_STARTED;
- m_stop = false;
+ m_thread = 0;
+ m_calthread = CALTHREAD_NOTRUNNING;
+ m_calphase = CALPHASE_NOT_STARTED;
m_touched = false;
}
@@ -150,27 +158,9 @@ NXWidgets::CNxString CCalibration::getName(void)
bool CCalibration::run(void)
{
- // Provide the initial display
-
- m_state = CALIB_NOT_STARTED;
- stateMachine();
-
- // Loop until calibration completes
-
- while (!m_stop && m_state != CALIB_COMPLETE)
- {
- // Wait for the next raw touchscreen input
-
- struct touch_sample_s sample;
- while (!m_touchscreen->waitRawTouchData(&sample));
+ gvdbg("Starting calibration: m_calthread=%d\n", (int)m_calthread);
- // Then process the raw touchscreen input
-
- touchscreenInput(sample);
- }
-
- m_stop = false;
- return true;
+ return startCalibration(CALTHREAD_STARTED);
}
/**
@@ -179,10 +169,29 @@ bool CCalibration::run(void)
void CCalibration::stop(void)
{
- // The main thread is stuck waiting for the next touchscreen input...
- // So this is probably just a waste of good FLASH space.
+ gvdbg("Stopping calibration: m_calthread=%d\n", (int)m_calthread);
+
+ // Was the calibration thread created?
+
+ if (m_thread != 0)
+ {
+ // Is the calibration thread running?
+
+ if (isRunning())
+ {
+ // The main thread is stuck waiting for the next touchscreen input...
+ // We can signal that we would like the thread to stop, but we will be
+ // stuck here until the next touch
- m_stop = true;
+ m_calthread = CALTHREAD_STOPREQUESTED;
+
+ // Try to wake up the calibration thread so that it will see our
+ // terminatin request
+
+ gvdbg("Stopping calibration: m_calthread=%d\n", (int)m_calthread);
+ (void)pthread_kill(m_thread, CONFIG_NXWM_CALIBRATION_SIGNO);
+ }
+ }
}
/**
@@ -192,7 +201,17 @@ void CCalibration::stop(void)
void CCalibration::hide(void)
{
- // REVISIT
+ gvdbg("Entry\n");
+
+ // Is the calibration thread running?
+
+ if (m_calthread == CALTHREAD_RUNNING || m_calthread == CALTHREAD_SHOW)
+ {
+ // Ask the calibration thread to hide the display
+
+ m_calthread = CALTHREAD_HIDE;
+ (void)pthread_kill(m_thread, CONFIG_NXWM_CALIBRATION_SIGNO);
+ }
}
/**
@@ -203,89 +222,43 @@ void CCalibration::hide(void)
void CCalibration::redraw(void)
{
- // Reset the state machine and start over
+ gvdbg("Entry\n");
- if (m_state != CALIB_COMPLETE)
- {
- m_state = CALIB_NOT_STARTED;
- stateMachine();
- }
-}
-
-/**
- * Wait for calibration data to be received.
- *
- * @return True if the calibration data was successfully obtained.
- */
+ // Is the calibration thread running? We might have to restart it if
+ // we have completed the calibration early but are being brought to
+ // top of the display again
-bool CCalibration::waitCalibrationData(struct SCalibrationData &data)
-{
- // Wait until calibration is finished
+ // Is the calibration thread running?
- while (m_state != CALIB_COMPLETE)
+ if (!isRunning())
{
-#ifdef CONFIG_DEBUG
- int ret = sem_wait(&m_waitSem);
- DEBUGASSERT(ret == 0 || errno == EINTR);
-#else
- (void)sem_wait(&m_waitSem);
-#endif
+ gvdbg("Starting calibration: m_calthread=%d\n", (int)m_calthread);
+ (void)startCalibration(CALTHREAD_SHOW);
}
- // Recover the window instance contained in the full screen window
-
- NXWidgets::INxWindow *window = m_window->getWindow();
-
- // Get the size of the fullscreen window
+ // The calibration thread is running. Make sure that is is not
+ // already processing a redraw
- struct nxgl_size_s windowSize;
- if (!window->getSize(&windowSize))
+ else if (m_calthread != CALTHREAD_SHOW)
{
- return false;
- }
-
- // Calculate the calibration parameters
- //
- // (scaledX - LEFTX) / (rawX - leftX) = (RIGHTX - LEFTX) / (rightX - leftX)
- // scaledX = (rawX - leftX) * (RIGHTX - LEFTX) / (rightX - leftX) + LEFTX
- // = rawX * xSlope + (LEFTX - leftX * xSlope)
- // = rawX * xSlope + xOffset
- //
- // where:
- // xSlope = (RIGHTX - LEFTX) / (rightX - leftX)
- // xOffset = (LEFTX - leftX * xSlope)
+ // Ask the calibration thread to restart the calibration and redraw the display
- b16_t leftX = (m_calibData[CALIB_UPPER_LEFT_INDEX].x +
- m_calibData[CALIB_LOWER_LEFT_INDEX].x) << 15;
- b16_t rightX = (m_calibData[CALIB_UPPER_RIGHT_INDEX].x +
- m_calibData[CALIB_LOWER_RIGHT_INDEX].x) << 15;
-
- data.xSlope = b16divb16(itob16(CALIBRATION_RIGHTX - CALIBRATION_LEFTX), (rightX - leftX));
- data.xOffset = itob16(CALIBRATION_LEFTX) - b16mulb16(leftX, data.xSlope);
-
- gdbg("New xSlope: %08x xOffset: %08x\n", data.xSlope, data.xOffset);
-
- // Similarly for Y
- //
- // (scaledY - TOPY) / (rawY - topY) = (BOTTOMY - TOPY) / (bottomY - topY)
- // scaledY = (rawY - topY) * (BOTTOMY - TOPY) / (bottomY - topY) + TOPY
- // = rawY * ySlope + (TOPY - topY * ySlope)
- // = rawY * ySlope + yOffset
- //
- // where:
- // ySlope = (BOTTOMY - TOPY) / (bottomY - topY)
- // yOffset = (TOPY - topY * ySlope)
-
- b16_t topY = (m_calibData[CALIB_UPPER_LEFT_INDEX].y +
- m_calibData[CALIB_UPPER_RIGHT_INDEX].y) << 15;
- b16_t bottomY = (m_calibData[CALIB_LOWER_LEFT_INDEX].y +
- m_calibData[CALIB_LOWER_RIGHT_INDEX].y) << 15;
+ m_calthread = CALTHREAD_SHOW;
+ (void)pthread_kill(m_thread, CONFIG_NXWM_CALIBRATION_SIGNO);
+ }
+}
- data.ySlope = b16divb16(itob16(CALIBRATION_BOTTOMY - CALIBRATION_TOPY), (bottomY - topY));
- data.yOffset = itob16(CALIBRATION_TOPY) - b16mulb16(topY, data.ySlope);
+/**
+ * Report of this is a "normal" window or a full screen window. The
+ * primary purpose of this method is so that window manager will know
+ * whether or not it show draw the task bar.
+ *
+ * @return True if this is a full screen window.
+ */
- gdbg("New ySlope: %08x yOffset: %08x\n", data.ySlope, data.yOffset);
- return true;
+bool CCalibration::isFullScreen(void) const
+{
+ return m_window->isFullScreen();
}
/**
@@ -347,7 +320,7 @@ void CCalibration::touchscreenInput(struct touch_sample_s &sample)
// Yes.. invoke the state machine.
gvdbg("State: %d Screen x: %d y: %d Touch x: %d y: %d\n",
- m_state, m_screenInfo.pos.x, m_screenInfo.pos.y,
+ m_calphase, m_screenInfo.pos.x, m_screenInfo.pos.y,
m_touchPos.x, m_touchPos.y);
stateMachine();
@@ -368,12 +341,147 @@ void CCalibration::touchscreenInput(struct touch_sample_s &sample)
}
/**
+ * Start the calibration thread.
+ *
+ * @param initialState. The initial state of the calibration thread
+ * @return True if the thread was successfully started.
+ */
+
+bool CCalibration::startCalibration(enum ECalThreadState initialState)
+{
+
+ // Verify that the thread is not already running
+
+ if (isRunning())
+ {
+ gdbg("The calibration thread is already running\n");
+ return false;
+ }
+
+ // Configure the calibration thread
+
+ pthread_attr_t attr;
+ (void)pthread_attr_init(&attr);
+
+ struct sched_param param;
+ param.sched_priority = CONFIG_NXWM_CALIBRATION_LISTENERPRIO;
+ (void)pthread_attr_setschedparam(&attr, &param);
+
+ (void)pthread_attr_setstacksize(&attr, CONFIG_NXWM_CALIBRATION_LISTENERSTACK);
+
+ // Set the initial state of the thread
+
+ m_calthread = initialState;
+
+ // Start the thread that will perform the calibration process
+
+ int ret = pthread_create(&m_thread, &attr, calibration, (FAR void *)this);
+ if (ret != 0)
+ {
+ gdbg("pthread_create failed: %d\n", ret);
+ return false;
+ }
+
+ // Detach from the pthread so that we do not have any memory leaks
+
+ (void)pthread_detach(m_thread);
+
+ gvdbg("Calibration thread m_calthread=%d\n", (int)m_calthread);
+ return true;
+}
+
+/**
+ * The calibration thread. This is the entry point of a thread that provides the
+ * calibration displays, waits for input, and collects calibration data.
+ *
+ * @param arg. The CCalibration 'this' pointer cast to a void*.
+ * @return This function always returns NULL when the thread exits
+ */
+
+FAR void *CCalibration::calibration(FAR void *arg)
+{
+ CCalibration *This = (CCalibration *)arg;
+ bool stalled = true;
+
+ // The calibration thread is now running
+
+ This->m_calthread = CALTHREAD_RUNNING;
+ This->m_calphase = CALPHASE_NOT_STARTED;
+ gvdbg("Started: m_calthread=%d\n", (int)This->m_calthread);
+
+ // Loop until calibration completes or we have been requested to terminate
+
+ while (This->m_calthread != CALTHREAD_STOPREQUESTED &&
+ This->m_calphase != CALPHASE_COMPLETE)
+ {
+ // Check for state changes due to display order changes
+
+ if (This->m_calthread == CALTHREAD_HIDE)
+ {
+ // This state is set by hide() when our display is no longer visible
+
+ This->m_calthread = CALTHREAD_RUNNING;
+ This->m_calphase = CALPHASE_NOT_STARTED;
+ stalled = true;
+ }
+ else if (This->m_calthread == CALTHREAD_SHOW)
+ {
+ // This state is set by redraw() when our display has become visible
+
+ This->m_calthread = CALTHREAD_RUNNING;
+ This->m_calphase = CALPHASE_NOT_STARTED;
+ stalled = false;
+ This->stateMachine();
+ }
+
+ // The calibration thread will stall if has been asked to hide the
+ // display. While stalled, we will just sleep for a bit abd test
+ // the state again. If we are re-awakened by a redraw(), then we
+ // will be given a signal which will wake us up immediately.
+ //
+ // Note that stalled is also initially true so we have to receive
+ // redraw() before we attempt to draw anything
+
+ if (stalled)
+ {
+ // Sleep for a while (or until we receive a signal)
+
+ std::usleep(500*1000);
+ }
+ else
+ {
+ // Wait for the next raw touchscreen input (or possibly a signal)
+
+ struct touch_sample_s sample;
+ while (!This->m_touchscreen->waitRawTouchData(&sample) &&
+ This->m_calthread == CALTHREAD_RUNNING);
+
+ // Then process the raw touchscreen input
+
+ if (This->m_calthread == CALTHREAD_RUNNING)
+ {
+ This->touchscreenInput(sample);
+ }
+ }
+ }
+
+ // Perform the final steps of calibration
+
+ This->finishCalibration();
+
+ gvdbg("Terminated: m_calthread=%d\n", (int)This->m_calthread);
+ return (FAR void *)0;
+}
+
+/**
* This is the calibration state machine. It is called initially and then
* as new touchscreen data is received.
*/
void CCalibration::stateMachine(void)
{
+ gvdbg("Old m_calphase=%d\n", m_calphase);
+
// Recover the window instance contained in the full screen window
NXWidgets::INxWindow *window = m_window->getWindow();
@@ -386,10 +494,10 @@ void CCalibration::stateMachine(void)
return;
}
- switch (m_state)
+ switch (m_calphase)
{
default:
- case CALIB_NOT_STARTED:
+ case CALPHASE_NOT_STARTED:
{
// Clear the entire screen
// Get the widget control associated with the full screen window
@@ -415,13 +523,13 @@ void CCalibration::stateMachine(void)
// Then set up the current state
- m_state = CALIB_UPPER_LEFT;
+ m_calphase = CALPHASE_UPPER_LEFT;
}
break;
- case CALIB_UPPER_LEFT:
+ case CALPHASE_UPPER_LEFT:
{
- // A touch has been received while in the CALIB_UPPER_LEFT state.
+ // A touch has been received while in the CALPHASE_UPPER_LEFT state.
// Save the touch data and set up the next calibration display
m_calibData[CALIB_UPPER_LEFT_INDEX].x = m_touchPos.x;
@@ -444,13 +552,13 @@ void CCalibration::stateMachine(void)
// Then set up the current state
- m_state = CALIB_UPPER_RIGHT;
+ m_calphase = CALPHASE_UPPER_RIGHT;
}
break;
- case CALIB_UPPER_RIGHT:
+ case CALPHASE_UPPER_RIGHT:
{
- // A touch has been received while in the CALIB_UPPER_RIGHT state.
+ // A touch has been received while in the CALPHASE_UPPER_RIGHT state.
// Save the touch data and set up the next calibration display
m_calibData[CALIB_UPPER_RIGHT_INDEX].x = m_touchPos.x;
@@ -473,13 +581,13 @@ void CCalibration::stateMachine(void)
// Then set up the current state
- m_state = CALIB_LOWER_RIGHT;
+ m_calphase = CALPHASE_LOWER_RIGHT;
}
break;
- case CALIB_LOWER_RIGHT:
+ case CALPHASE_LOWER_RIGHT:
{
- // A touch has been received while in the CALIB_LOWER_RIGHT state.
+ // A touch has been received while in the CALPHASE_LOWER_RIGHT state.
// Save the touch data and set up the next calibration display
m_calibData[CALIB_LOWER_RIGHT_INDEX].x = m_touchPos.x;
@@ -502,32 +610,38 @@ void CCalibration::stateMachine(void)
// Then set up the current state
- m_state = CALIB_LOWER_LEFT;
+ m_calphase = CALPHASE_LOWER_LEFT;
}
break;
- case CALIB_LOWER_LEFT:
+ case CALPHASE_LOWER_LEFT:
{
- // A touch has been received while in the CALIB_LOWER_LEFT state.
+ // A touch has been received while in the CALPHASE_LOWER_LEFT state.
// Save the touch data and set up the next calibration display
m_calibData[CALIB_LOWER_LEFT_INDEX].x = m_touchPos.x;
m_calibData[CALIB_LOWER_LEFT_INDEX].y = m_touchPos.y;
+ // Clear the previous screen by re-drawing it using the backgro9und
+ // color. That is much faster than clearing the whole display
+
+ m_screenInfo.lineColor = CONFIG_NXWM_CALIBRATION_BACKGROUNDCOLOR;
+ m_screenInfo.circleFillColor = CONFIG_NXWM_CALIBRATION_BACKGROUNDCOLOR;
+ showCalibration();
+
// Inform any waiter that calibration is complete
- m_state = CALIB_COMPLETE;
- sem_post(&m_waitSem);
+ m_calphase = CALPHASE_COMPLETE;
}
break;
- case CALIB_COMPLETE:
+ case CALPHASE_COMPLETE:
// Might happen... do nothing if it does
break;
}
- gvdbg("State: %d Screen x: %d y: %d\n",
- m_state, m_screenInfo.pos.x, m_screenInfo.pos.y);
+ gvdbg("New m_calphase=%d Screen x: %d y: %d\n",
+ m_calphase, m_screenInfo.pos.x, m_screenInfo.pos.y);
}
/**
@@ -573,3 +687,105 @@ void CCalibration::showCalibration(void)
port->drawFilledRect(m_screenInfo.pos.x, 0, CALIBRATION_LINE_THICKNESS, windowSize.h,
m_screenInfo.lineColor);
}
+
+/**
+ * Finish calibration steps and provide the calibration data to the
+ * touchscreen driver.
+ */
+
+void CCalibration::finishCalibration(void)
+{
+ // Did we finish calibration successfully?
+
+ if (m_calphase == CALPHASE_COMPLETE)
+ {
+ // Yes... Get the final Calibration data
+
+ struct SCalibrationData caldata;
+ if (createCalibrationData(caldata))
+ {
+ // And provide this to the touchscreen, enabling touchscreen processing
+
+ m_touchscreen->setEnabled(false);
+ m_touchscreen->setCalibrationData(caldata);
+ m_touchscreen->setEnabled(true);
+ }
+ }
+
+ // Remove the touchscreen application from the taskbar
+
+ m_taskbar->stopApplication(this);
+
+ // And set the terminated stated
+
+ m_calthread = CALTHREAD_TERMINATED;
+}
+
+/**
+ * Given the raw touch data collected by the calibration thread, create the
+ * massaged calibration data needed by CTouchscreen.
+ *
+ * @param data. A reference to the location to save the calibration data
+ * @return True if the calibration data was successfully created.
+ */
+
+bool CCalibration::createCalibrationData(struct SCalibrationData &data)
+{
+ // Recover the window instance contained in the full screen window
+
+ NXWidgets::INxWindow *window = m_window->getWindow();
+
+ // Get the size of the fullscreen window
+
+ struct nxgl_size_s windowSize;
+ if (!window->getSize(&windowSize))
+ {
+ gdbg("NXWidgets::INxWindow::getSize failed\n");
+ return false;
+ }
+
+ // Calculate the calibration parameters
+ //
+ // (scaledX - LEFTX) / (rawX - leftX) = (RIGHTX - LEFTX) / (rightX - leftX)
+ // scaledX = (rawX - leftX) * (RIGHTX - LEFTX) / (rightX - leftX) + LEFTX
+ // = rawX * xSlope + (LEFTX - leftX * xSlope)
+ // = rawX * xSlope + xOffset
+ //
+ // where:
+ // xSlope = (RIGHTX - LEFTX) / (rightX - leftX)
+ // xOffset = (LEFTX - leftX * xSlope)
+
+ b16_t leftX = (m_calibData[CALIB_UPPER_LEFT_INDEX].x +
+ m_calibData[CALIB_LOWER_LEFT_INDEX].x) << 15;
+ b16_t rightX = (m_calibData[CALIB_UPPER_RIGHT_INDEX].x +
+ m_calibData[CALIB_LOWER_RIGHT_INDEX].x) << 15;
+
+ data.xSlope = b16divb16(itob16(CALIBRATION_RIGHTX - CALIBRATION_LEFTX), (rightX - leftX));
+ data.xOffset = itob16(CALIBRATION_LEFTX) - b16mulb16(leftX, data.xSlope);
+
+ gdbg("New xSlope: %08x xOffset: %08x\n", data.xSlope, data.xOffset);
+
+ // Similarly for Y
+ //
+ // (scaledY - TOPY) / (rawY - topY) = (BOTTOMY - TOPY) / (bottomY - topY)
+ // scaledY = (rawY - topY) * (BOTTOMY - TOPY) / (bottomY - topY) + TOPY
+ // = rawY * ySlope + (TOPY - topY * ySlope)
+ // = rawY * ySlope + yOffset
+ //
+ // where:
+ // ySlope = (BOTTOMY - TOPY) / (bottomY - topY)
+ // yOffset = (TOPY - topY * ySlope)
+
+ b16_t topY = (m_calibData[CALIB_UPPER_LEFT_INDEX].y +
+ m_calibData[CALIB_UPPER_RIGHT_INDEX].y) << 15;
+ b16_t bottomY = (m_calibData[CALIB_LOWER_LEFT_INDEX].y +
+ m_calibData[CALIB_LOWER_RIGHT_INDEX].y) << 15;
+
+ data.ySlope = b16divb16(itob16(CALIBRATION_BOTTOMY - CALIBRATION_TOPY), (bottomY - topY));
+ data.yOffset = itob16(CALIBRATION_TOPY) - b16mulb16(topY, data.ySlope);
+
+ gdbg("New ySlope: %08x yOffset: %08x\n", data.ySlope, data.yOffset);
+ return true;
+}
+
+
diff --git a/NxWidgets/nxwm/src/cfullscreenwindow.cxx b/NxWidgets/nxwm/src/cfullscreenwindow.cxx
index 2087543cd..7d63b02d7 100644
--- a/NxWidgets/nxwm/src/cfullscreenwindow.cxx
+++ b/NxWidgets/nxwm/src/cfullscreenwindow.cxx
@@ -138,6 +138,19 @@ void CFullScreenWindow::setWindowLabel(NXWidgets::CNxString &appname)
}
/**
+ * Report of this is a "normal" window or a full screen window. The
+ * primary purpose of this method is so that window manager will know
+ * whether or not it show draw the task bar.
+ *
+ * @return True if this is a full screen window.
+ */
+
+bool CFullScreenWindow::isFullScreen(void) const
+{
+ return true;
+}
+
+/**
* Register to receive callbacks when toolbar icons are selected
*/
diff --git a/NxWidgets/nxwm/src/cnxconsole.cxx b/NxWidgets/nxwm/src/cnxconsole.cxx
index 5ee12d36f..264845a03 100644
--- a/NxWidgets/nxwm/src/cnxconsole.cxx
+++ b/NxWidgets/nxwm/src/cnxconsole.cxx
@@ -327,6 +327,19 @@ void CNxConsole::redraw(void)
}
/**
+ * Report of this is a "normal" window or a full screen window. The
+ * primary purpose of this method is so that window manager will know
+ * whether or not it show draw the task bar.
+ *
+ * @return True if this is a full screen window.
+ */
+
+bool CNxConsole::isFullScreen(void) const
+{
+ return m_window->isFullScreen();
+}
+
+/**
* This is the NxConsole task. This function first redirects output to the
* console window.
*/
diff --git a/NxWidgets/nxwm/src/cstartwindow.cxx b/NxWidgets/nxwm/src/cstartwindow.cxx
index f907f6718..ceeff0d7b 100644
--- a/NxWidgets/nxwm/src/cstartwindow.cxx
+++ b/NxWidgets/nxwm/src/cstartwindow.cxx
@@ -280,6 +280,19 @@ void CStartWindow::redraw(void)
}
/**
+ * Report of this is a "normal" window or a full screen window. The
+ * primary purpose of this method is so that window manager will know
+ * whether or not it show draw the task bar.
+ *
+ * @return True if this is a full screen window.
+ */
+
+bool CStartWindow::isFullScreen(void) const
+{
+ return m_window->isFullScreen();
+}
+
+/**
* Add the application to the start window. The general sequence for
* setting up the start window is:
*
diff --git a/NxWidgets/nxwm/src/ctaskbar.cxx b/NxWidgets/nxwm/src/ctaskbar.cxx
index f5a5c08f5..3305b945b 100644
--- a/NxWidgets/nxwm/src/ctaskbar.cxx
+++ b/NxWidgets/nxwm/src/ctaskbar.cxx
@@ -39,6 +39,8 @@
#include <nuttx/config.h>
+#include <debug.h>
+
#include <nuttx/nx/nxglib.h>
#include "crect.hxx"
@@ -235,16 +237,75 @@ bool CTaskbar::startWindowManager(void)
m_started = true;
- // Draw the taskbar
+ // Decide which application will be the initial 'top' application
+
+ m_topApp = (IApplication *)0;
+ int topIndex = -1;
+
+ // No.. Search for that last, non-minimized application (there might not be one)
- if (!redrawTaskbarWindow())
+ for (int i = m_slots.size() - 1; i >= 0; i--)
{
- return false;
+ IApplication *candidate = m_slots.at(i).app;
+ if (!candidate->isMinimized())
+ {
+ m_topApp = candidate;
+ topIndex = i;
+ break;
+ }
}
+ gvdbg("m_topApp=%p topIndex=%d\n", m_topApp, topIndex);
- // Draw the top application window
+ // Now start each application (whatever that means to the application)
- return redrawTopWindow();
+ for (int i = 0; i < m_slots.size(); )
+ {
+ IApplication *app = m_slots.at(i).app;
+
+ gvdbg("Starting app[%d]\n", i);
+ if (!app->run())
+ {
+ // Call stopApplication on a failure to start. This will call
+ // app->stop() (which is probably not necesary for the application
+ // but it should be prepared/ to handle it). stopApplication()
+ // will also removed the icon image from the list and delete it.
+
+ stopApplication(app);
+
+ // Then continue with the next application. Notice that i is
+ // not incremented in this case and we will continue with the
+ // next application which will not be at this same index
+
+ continue;
+ }
+
+ // Hide all appliations except for the top application
+
+ if (i != topIndex)
+ {
+ // Bring the application up in the non-visible state (the
+ // application may or may not be minimized, but it is not
+ // visible now).
+
+ gvdbg("Hiding app[%d]\n", i);
+ hideApplicationWindow(app);
+ }
+ else
+ {
+ // Bring up the application as the new top application
+
+ gvdbg("Showing app[%d]\n", i);
+ topApplication(app);
+ }
+
+ // The application was successfully initialized.. index to the next application
+
+ i++;
+ }
+
+ // Draw the taskbar. It will be draw at a higher level than the application.
+
+ return redrawTaskbarWindow();
}
return false;
@@ -391,41 +452,48 @@ bool CTaskbar::startApplication(IApplication *app, bool minimized)
slot.image = image;
m_slots.push_back(slot);
- // Start the application (whatever that means).
+ // Initialize the application states
+
+ app->setTopApplication(false);
+ app->setMinimized(minimized);
- if (!app->run())
+ // Has the window manager been started?
+
+ if (m_started)
{
- // Call stopApplication on a failure to start. This will call
- // app->stop() (which is probably not necesary for the application
- // but it should be prepared/ to handle it). stopApplication()
- // will also removed the icon image from the list and delete it.
+ // Yes.. Start the application (whatever that means).
- stopApplication(app);
- return false;
- }
+ if (!app->run())
+ {
+ // Call stopApplication on a failure to start. This will call
+ // app->stop() (which is probably not necesary for the application
+ // but it should be prepared/ to handle it). stopApplication()
+ // will also removed the icon image from the list and delete it.
- // Has the window manager been started? Or were we ask to start
- // the application minimized?
+ stopApplication(app);
+ return false;
+ }
- if (minimized || !m_started)
- {
- // Bring the application up in the minimized state
+ // Has the window manager been started? Or were we ask to start
+ // the application minimized?
- hideApplicationWindow(app);
- }
- else
- {
- // Bring up the application as the new top application
+ if (minimized)
+ {
+ // Bring the minimized application up in non-visible state
- app->setTopApplication(false);
- app->setMinimized(false);
- topApplication(app);
- }
+ hideApplicationWindow(app);
+ }
+ else
+ {
+ // Bring up the application as the new top application if we are running
+ // If not, we will select and bring up the top application when the
+ // window manager is started
- // Redraw the task bar with the new icon (if we have been started)
+ topApplication(app);
+ }
+
+ // Redraw the task bar with the new icon (if we have been started)
- if (m_started)
- {
redrawTaskbarWindow();
}
@@ -451,7 +519,11 @@ bool CTaskbar::topApplication(IApplication *app)
if (m_topApp)
{
- // Yes.. then disable it
+ // Yes.. then minimize the application
+
+ app->setMinimized(true);
+
+ // And make the application non-visible
hideApplicationWindow(m_topApp);
}
@@ -501,6 +573,7 @@ bool CTaskbar::minimizeApplication(IApplication *app)
// No, then we are going to minimize it but disabling its components,
// marking it as minimized, then raising a new window to the top window.
+ app->setMinimized(true);
hideApplicationWindow(app);
// Re-draw the new top, non-minimized application
@@ -521,13 +594,22 @@ bool CTaskbar::minimizeApplication(IApplication *app)
bool CTaskbar::stopApplication(IApplication *app)
{
- // First, minimize the application. That will move the application
- // to the bottom of the hiearachy and redraw the next application
- // (If the application is already minimized, it does nothing)
+ // Make the application minimized and make sure that it is not the top
+ // application.
- minimizeApplication(app);
+ app->setMinimized(true);
+ if (app->isTopApplication())
+ {
+ app->setTopApplication(false);
+ m_topApp = (IApplication *)0;
+ }
+
+ // Hide the application window. That will move the application to the
+ // bottom of the hiearachy.
+
+ hideApplicationWindow(app);
- // Stop the application
+ // Stop the application (whatever this means to the application)
app->stop();
@@ -540,7 +622,7 @@ bool CTaskbar::stopApplication(IApplication *app)
IApplication *candidate = m_slots.at(i).app;
if (candidate == app)
{
- // Yes.. found it. Delete the icon image and remove it
+ // Yes.. found it. Delete the icon image and remove the entry
// from the list of applications
delete m_slots.at(i).image;
@@ -549,9 +631,16 @@ bool CTaskbar::stopApplication(IApplication *app)
}
}
- // And redraw the task bar (without the icon for this task)
+ // Re-draw the new top, non-minimized application
- return redrawTaskbarWindow();
+ bool ret = redrawTopWindow();
+ if (ret)
+ {
+ // And redraw the task bar (without the icon for this task)
+
+ ret = redrawTaskbarWindow();
+ }
+ return ret;
}
/**
@@ -895,116 +984,126 @@ bool CTaskbar::createBackgroundImage(void)
bool CTaskbar::redrawTaskbarWindow(void)
{
- // Get the widget control from the task bar
+ // Only redraw the task bar if (1) the window manager has been started, AND
+ // (2) there is no top window (i.e., we are showing the background image), OR
+ // (3) there is a top window, but it is not full screen
- NXWidgets::CWidgetControl *control = m_taskbar->getWidgetControl();
+ if (m_started && (!m_topApp || !m_topApp->isFullScreen()))
+ {
+ // Get the widget control from the task bar
- // Get the graphics port for drawing on the background window
+ NXWidgets::CWidgetControl *control = m_taskbar->getWidgetControl();
- NXWidgets::CGraphicsPort *port = control->getGraphicsPort();
+ // Get the graphics port for drawing on the background window
- // Get the size of the window
+ NXWidgets::CGraphicsPort *port = control->getGraphicsPort();
- struct nxgl_size_s windowSize;
- if (!m_taskbar->getSize(&windowSize))
- {
- return false;
- }
+ // Get the size of the window
- // Raise the task bar to the top of the display. This is only necessary
- // after stopping a full screen application. Other applications do not
- // overlap the task bar and, hence, do not interfere.
+ struct nxgl_size_s windowSize;
+ if (!m_taskbar->getSize(&windowSize))
+ {
+ return false;
+ }
- m_taskbar->raise();
+ // Raise the task bar to the top of the display. This is only necessary
+ // after stopping a full screen application. Other applications do not
+ // overlap the task bar and, hence, do not interfere.
- // Fill the entire window with the background color
+ m_taskbar->raise();
- port->drawFilledRect(0, 0, windowSize.w, windowSize.h,
- CONFIG_NXWM_DEFAULT_BACKGROUNDCOLOR);
+ // Fill the entire window with the background color
- // Add a border to the task bar to delineate it from the background window
+ port->drawFilledRect(0, 0, windowSize.w, windowSize.h,
+ CONFIG_NXWM_DEFAULT_BACKGROUNDCOLOR);
- port->drawBevelledRect(0, 0, windowSize.w, windowSize.h,
- CONFIG_NXWM_DEFAULT_SHINEEDGECOLOR,
- CONFIG_NXWM_DEFAULT_SHADOWEDGECOLOR);
+ // Add a border to the task bar to delineate it from the background window
+
+ port->drawBevelledRect(0, 0, windowSize.w, windowSize.h,
+ CONFIG_NXWM_DEFAULT_SHINEEDGECOLOR,
+ CONFIG_NXWM_DEFAULT_SHADOWEDGECOLOR);
- // Begin adding icons in the upper left corner
+ // Begin adding icons in the upper left corner
- struct nxgl_point_s taskbarPos;
+ struct nxgl_point_s taskbarPos;
#if defined(CONFIG_NXWM_TASKBAR_TOP) || defined(CONFIG_NXWM_TASKBAR_BOTTOM)
- taskbarPos.x = CONFIG_NXWM_TASKBAR_HSPACING;
- taskbarPos.y = 0;
+ taskbarPos.x = CONFIG_NXWM_TASKBAR_HSPACING;
+ taskbarPos.y = 0;
#else
- taskbarPos.x = 0;
- taskbarPos.y = CONFIG_NXWM_TASKBAR_VSPACING;
+ taskbarPos.x = 0;
+ taskbarPos.y = CONFIG_NXWM_TASKBAR_VSPACING;
#endif
- // Add each icon in the list of applications
+ // Add each icon in the list of applications
- for (int i = 0; i < m_slots.size(); i++)
- {
- // Get the icon associated with this application
+ for (int i = 0; i < m_slots.size(); i++)
+ {
+ // Get the icon associated with this application
- NXWidgets::CImage *image = m_slots.at(i).image;
+ NXWidgets::CImage *image = m_slots.at(i).image;
- // Disable drawing of the icon image; disable events from the icon
+ // Disable drawing of the icon image; disable events from the icon
- image->disableDrawing();
- image->setRaisesEvents(false);
+ image->disableDrawing();
+ image->setRaisesEvents(false);
- // Get the size of the icon image
+ // Get the size of the icon image
- NXWidgets::CRect rect;
- image->getPreferredDimensions(rect);
+ NXWidgets::CRect rect;
+ image->getPreferredDimensions(rect);
- // Position the icon
+ // Position the icon
- struct nxgl_point_s iconPos;
+ struct nxgl_point_s iconPos;
#if defined(CONFIG_NXWM_TASKBAR_TOP) || defined(CONFIG_NXWM_TASKBAR_BOTTOM)
- // For horizontal task bars, the icons will be aligned along the top of
- // the task bar
+ // For horizontal task bars, the icons will be aligned along the top of
+ // the task bar
- iconPos.x = taskbarPos.x;
- iconPos.y = taskbarPos.y + CONFIG_NXWM_TASKBAR_VSPACING;
+ iconPos.x = taskbarPos.x;
+ iconPos.y = taskbarPos.y + CONFIG_NXWM_TASKBAR_VSPACING;
#else
- // For vertical task bars, the icons will be centered horizontally
+ // For vertical task bars, the icons will be centered horizontally
- iconPos.x = (windowSize.w - rect.getWidth()) >> 1;
- iconPos.y = taskbarPos.y;
+ iconPos.x = (windowSize.w - rect.getWidth()) >> 1;
+ iconPos.y = taskbarPos.y;
#endif
- // Set the position of the icon bitmap
+ // Set the position of the icon bitmap
- (void)image->moveTo(iconPos.x, iconPos.y);
+ (void)image->moveTo(iconPos.x, iconPos.y);
- // Then re-draw the icon at the new position
+ // Then re-draw the icon at the new position
- image->enableDrawing();
- image->redraw();
- image->setRaisesEvents(true);
+ image->enableDrawing();
+ image->redraw();
+ image->setRaisesEvents(true);
- // Do we add icons left-to-right? Or top-to-bottom?
+ // Do we add icons left-to-right? Or top-to-bottom?
#if defined(CONFIG_NXWM_TASKBAR_TOP) || defined(CONFIG_NXWM_TASKBAR_BOTTOM)
- // left-to-right ... increment the X display position
+ // left-to-right ... increment the X display position
- taskbarPos.x += rect.getWidth() + CONFIG_NXWM_TASKBAR_HSPACING;
- if (taskbarPos.x > windowSize.w)
- {
- break;
- }
+ taskbarPos.x += rect.getWidth() + CONFIG_NXWM_TASKBAR_HSPACING;
+ if (taskbarPos.x > windowSize.w)
+ {
+ break;
+ }
#else
- // top-to-bottom ... increment the Y display position
+ // top-to-bottom ... increment the Y display position
- taskbarPos.y += rect.getHeight() + CONFIG_NXWM_TASKBAR_VSPACING;
- if (taskbarPos.y > windowSize.h)
- {
- break;
- }
+ taskbarPos.y += rect.getHeight() + CONFIG_NXWM_TASKBAR_VSPACING;
+ if (taskbarPos.y > windowSize.h)
+ {
+ break;
+ }
#endif
+ }
}
+ // Return success (it is not a failure if the window manager is not started
+ // or the task bar is occluded by a full screen window.
+
return true;
}
@@ -1158,10 +1257,6 @@ void CTaskbar::hideApplicationWindow(IApplication *app)
app->setTopApplication(false);
}
- // Make sure that the application is marked as minimized.
-
- app->setMinimized(true);
-
// We do not need to lower the application to the back.. the new top
// window will be raised instead.
//
diff --git a/NxWidgets/nxwm/src/ctouchscreen.cxx b/NxWidgets/nxwm/src/ctouchscreen.cxx
index 21ccc91e3..1a8a5e967 100644
--- a/NxWidgets/nxwm/src/ctouchscreen.cxx
+++ b/NxWidgets/nxwm/src/ctouchscreen.cxx
@@ -159,17 +159,17 @@ bool CTouchscreen::start(void)
(void)pthread_attr_init(&attr);
struct sched_param param;
- param.sched_priority = CONFIG_NXWIDGETS_LISTENERPRIO;
+ param.sched_priority = CONFIG_NXWM_TOUCHSCREEN_LISTENERPRIO;
(void)pthread_attr_setschedparam(&attr, &param);
- (void)pthread_attr_setstacksize(&attr, CONFIG_NXWIDGETS_LISTENERSTACK);
+ (void)pthread_attr_setstacksize(&attr, CONFIG_NXWM_TOUCHSCREEN_LISTENERSTACK);
m_state = LISTENER_STARTED; // The listener thread has been started, but is not yet running
int ret = pthread_create(&m_thread, &attr, listener, (FAR void *)this);
if (ret != 0)
{
- dbg("NxServer::connect: pthread_create failed: %d\n", ret);
+ dbg("CTouchscreen::start: pthread_create failed: %d\n", ret);
return false;
}
@@ -204,7 +204,7 @@ bool CTouchscreen::start(void)
* @param data. A reference to the touchscreen data.
*/
-void CTouchscreen::setCalibrationData(struct SCalibrationData &caldata)
+void CTouchscreen::setCalibrationData(const struct SCalibrationData &caldata)
{
// Save a copy of the calibration data