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
This commit is contained in:
patacongo 2012-05-14 20:46:47 +00:00
parent 92d74816c0
commit fc935338e8
18 changed files with 912 additions and 390 deletions

View File

@ -71,3 +71,15 @@
and create a new CImageButton.
* NxWM::CStartWindow: Now ignores any close application button presses
(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.

View File

@ -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,50 +585,17 @@ 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);
}
// Run the touchscreen calibration application
if (!runCalibration())
{
printf(MAIN_STRING "ERROR: Touchscreen Calibration failed\n");
testCleanUpAndExit(EXIT_FAILURE);
}
#endif
// Create the start window.
if (!createStartWindow())
{
printf(MAIN_STRING "ERROR: Failed to create the start window\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
// Add the NxConsole application to the start window
// Create the NxConsole application and add it to the start window
if (!createNxConsole())
{
@ -682,6 +611,30 @@ int MAIN_NAME(int argc, char *argv[])
testCleanUpAndExit(EXIT_FAILURE);
}
#ifdef CONFIG_NXWM_TOUCHSCREEN
// 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
printf(MAIN_STRING "Waiting for touchscreen calibration\n");
while (!g_nxwmtest.touchscreen->isCalibrated())
{
std::sleep(2);
}
// 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.
printf(MAIN_STRING "Getting calibration data from the touchscreen\n");
if (!g_nxwmtest.touchscreen->getCalibrationData(g_nxwmtest.calibData))
{
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

View File

@ -158,6 +158,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
*/

View File

@ -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"
@ -97,18 +99,33 @@ namespace NxWM
class CCalibration : public IApplication
{
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];
/**
@ -145,6 +164,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;
};
}

View File

@ -122,6 +122,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
*/

View File

@ -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

View File

@ -188,6 +188,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:

View File

@ -166,6 +166,17 @@ namespace NxWM
m_enabled = enable;
}
/**
* 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
@ -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

View File

@ -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;
};
}

View File

@ -129,6 +129,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
*/

View File

@ -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
****************************************************************************/

View File

@ -424,6 +424,19 @@ void CApplicationWindow::setWindowLabel(NXWidgets::CNxString &appname)
m_windowLabel->setText(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
*/

View File

@ -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
gvdbg("Starting calibration: m_calthread=%d\n", (int)m_calthread);
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));
// 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);
m_stop = true;
// 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_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)
// 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
// Is the calibration thread running?
if (!isRunning())
{
m_state = CALIB_NOT_STARTED;
stateMachine();
gvdbg("Starting calibration: m_calthread=%d\n", (int)m_calthread);
(void)startCalibration(CALTHREAD_SHOW);
}
// The calibration thread is running. Make sure that is is not
// already processing a redraw
else if (m_calthread != CALTHREAD_SHOW)
{
// Ask the calibration thread to restart the calibration and redraw the display
m_calthread = CALTHREAD_SHOW;
(void)pthread_kill(m_thread, CONFIG_NXWM_CALIBRATION_SIGNO);
}
}
/**
* 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 CCalibration::waitCalibrationData(struct SCalibrationData &data)
bool CCalibration::isFullScreen(void) const
{
// Wait until calibration is finished
while (m_state != CALIB_COMPLETE)
{
#ifdef CONFIG_DEBUG
int ret = sem_wait(&m_waitSem);
DEBUGASSERT(ret == 0 || errno == EINTR);
#else
(void)sem_wait(&m_waitSem);
#endif
}
// 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))
{
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;
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();
@ -367,6 +340,139 @@ 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.
@ -374,6 +480,8 @@ void CCalibration::touchscreenInput(struct touch_sample_s &sample)
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;
}

View File

@ -137,6 +137,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
*/

View File

@ -326,6 +326,19 @@ void CNxConsole::redraw(void)
nxcon_redraw(m_nxcon, &rect, false);
}
/**
* 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.

View File

@ -279,6 +279,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:

View File

@ -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
if (!redrawTaskbarWindow())
m_topApp = (IApplication *)0;
int topIndex = -1;
// No.. Search for that last, non-minimized application (there might not be one)
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);
// Now start each application (whatever that means to the application)
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 top application window
// Draw the taskbar. It will be draw at a higher level than the application.
return redrawTopWindow();
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
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.
app->setTopApplication(false);
app->setMinimized(minimized);
stopApplication(app);
return false;
}
// Has the window manager been started? Or were we ask to start
// the application minimized?
if (minimized || !m_started)
{
// Bring the application up in the minimized state
hideApplicationWindow(app);
}
else
{
// Bring up the application as the new top application
app->setTopApplication(false);
app->setMinimized(false);
topApplication(app);
}
// Redraw the task bar with the new icon (if we have been started)
// Has the window manager been started?
if (m_started)
{
// Yes.. Start the application (whatever that means).
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);
return false;
}
// Has the window manager been started? Or were we ask to start
// the application minimized?
if (minimized)
{
// Bring the minimized application up in non-visible state
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
topApplication(app);
}
// Redraw the task bar with the new icon (if we have been 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;
}
// Stop the application
// Hide the application window. That will move the application to the
// bottom of the hiearachy.
hideApplicationWindow(app);
// 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,115 +984,125 @@ 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();
// Get the graphics port for drawing on the background window
NXWidgets::CGraphicsPort *port = control->getGraphicsPort();
// Get the size of the window
struct nxgl_size_s windowSize;
if (!m_taskbar->getSize(&windowSize))
if (m_started && (!m_topApp || !m_topApp->isFullScreen()))
{
return false;
// Get the widget control from the task bar
NXWidgets::CWidgetControl *control = m_taskbar->getWidgetControl();
// Get the graphics port for drawing on the background window
NXWidgets::CGraphicsPort *port = control->getGraphicsPort();
// Get the size of the window
struct nxgl_size_s windowSize;
if (!m_taskbar->getSize(&windowSize))
{
return false;
}
// 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.
m_taskbar->raise();
// Fill the entire window with the background color
port->drawFilledRect(0, 0, windowSize.w, windowSize.h,
CONFIG_NXWM_DEFAULT_BACKGROUNDCOLOR);
// 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
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;
#else
taskbarPos.x = 0;
taskbarPos.y = CONFIG_NXWM_TASKBAR_VSPACING;
#endif
// Add each icon in the list of applications
for (int i = 0; i < m_slots.size(); i++)
{
// Get the icon associated with this application
NXWidgets::CImage *image = m_slots.at(i).image;
// Disable drawing of the icon image; disable events from the icon
image->disableDrawing();
image->setRaisesEvents(false);
// Get the size of the icon image
NXWidgets::CRect rect;
image->getPreferredDimensions(rect);
// Position the icon
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
iconPos.x = taskbarPos.x;
iconPos.y = taskbarPos.y + CONFIG_NXWM_TASKBAR_VSPACING;
#else
// For vertical task bars, the icons will be centered horizontally
iconPos.x = (windowSize.w - rect.getWidth()) >> 1;
iconPos.y = taskbarPos.y;
#endif
// Set the position of the icon bitmap
(void)image->moveTo(iconPos.x, iconPos.y);
// Then re-draw the icon at the new position
image->enableDrawing();
image->redraw();
image->setRaisesEvents(true);
// 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
taskbarPos.x += rect.getWidth() + CONFIG_NXWM_TASKBAR_HSPACING;
if (taskbarPos.x > windowSize.w)
{
break;
}
#else
// top-to-bottom ... increment the Y display position
taskbarPos.y += rect.getHeight() + CONFIG_NXWM_TASKBAR_VSPACING;
if (taskbarPos.y > windowSize.h)
{
break;
}
#endif
}
}
// 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.
m_taskbar->raise();
// Fill the entire window with the background color
port->drawFilledRect(0, 0, windowSize.w, windowSize.h,
CONFIG_NXWM_DEFAULT_BACKGROUNDCOLOR);
// 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
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;
#else
taskbarPos.x = 0;
taskbarPos.y = CONFIG_NXWM_TASKBAR_VSPACING;
#endif
// Add each icon in the list of applications
for (int i = 0; i < m_slots.size(); i++)
{
// Get the icon associated with this application
NXWidgets::CImage *image = m_slots.at(i).image;
// Disable drawing of the icon image; disable events from the icon
image->disableDrawing();
image->setRaisesEvents(false);
// Get the size of the icon image
NXWidgets::CRect rect;
image->getPreferredDimensions(rect);
// Position the icon
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
iconPos.x = taskbarPos.x;
iconPos.y = taskbarPos.y + CONFIG_NXWM_TASKBAR_VSPACING;
#else
// For vertical task bars, the icons will be centered horizontally
iconPos.x = (windowSize.w - rect.getWidth()) >> 1;
iconPos.y = taskbarPos.y;
#endif
// Set the position of the icon bitmap
(void)image->moveTo(iconPos.x, iconPos.y);
// Then re-draw the icon at the new position
image->enableDrawing();
image->redraw();
image->setRaisesEvents(true);
// 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
taskbarPos.x += rect.getWidth() + CONFIG_NXWM_TASKBAR_HSPACING;
if (taskbarPos.x > windowSize.w)
{
break;
}
#else
// top-to-bottom ... increment the Y display position
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.
//

View File

@ -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