diff --git a/graphics/twm4nx/src/cbackground.cxx b/graphics/twm4nx/src/cbackground.cxx index 99993618e..f8f831059 100644 --- a/graphics/twm4nx/src/cbackground.cxx +++ b/graphics/twm4nx/src/cbackground.cxx @@ -186,7 +186,13 @@ bool CBackground::event(FAR struct SEventMsg *eventmsg) { case EVENT_BACKGROUND_POLL: // Poll for icon events { -#warning Missing logic + NXWidgets::CWidgetControl *control = + m_backWindow->getWidgetControl(); + + // pollEvents() returns true if any interesting event occurred. + // false is not a failure. + + (void)control->pollEvents(); } break; diff --git a/graphics/twm4nx/src/cicon.cxx b/graphics/twm4nx/src/cicon.cxx index 4c1d24e0f..2c98e9712 100644 --- a/graphics/twm4nx/src/cicon.cxx +++ b/graphics/twm4nx/src/cicon.cxx @@ -295,7 +295,7 @@ void CIcon::up(FAR CWindow *cwin) /** * Take the window down. * - * @param vwin The window to be taken down. + * @param cwin The window to be taken down. */ void CIcon::down(FAR CWindow *cwin) diff --git a/graphics/twm4nx/src/ciconmgr.cxx b/graphics/twm4nx/src/ciconmgr.cxx index 8fb9822dc..d1cd7e038 100644 --- a/graphics/twm4nx/src/ciconmgr.cxx +++ b/graphics/twm4nx/src/ciconmgr.cxx @@ -147,7 +147,7 @@ bool CIconMgr::initialize(FAR const char *prefix) // Create the icon manager window - if (!createWindow(prefix)) + if (!createIconManagerWindow(prefix)) { twmerr("ERROR: Failed to create window\n"); return false; @@ -205,11 +205,12 @@ bool CIconMgr::add(FAR CWindow *cwin) insertEntry(wentry, cwin); - // The height of one row is determined (mostly) by the font height + // The height of one row of the Icon Manager Window is determined (mostly) + // by the font height nxgl_coord_t rowHeight = getRowHeight(); - // Increase the icon window size + // Increase the Icon Manager window size, if necessary struct nxgl_size_s windowSize; if (!m_window->getWindowSize(&windowSize)) @@ -218,8 +219,12 @@ bool CIconMgr::add(FAR CWindow *cwin) } else { - windowSize.h = rowHeight * m_nWindows; - m_window->setWindowSize(&windowSize); // REVISIT: use resizeFrame() + nxgl_coord_t newHeight = rowHeight * m_nWindows; + if (newHeight != windowSize.h) + { + windowSize.h = rowHeight * m_nWindows; + m_window->setWindowSize(&windowSize); // REVISIT: use resizeFrame() + } } // Increment the window count @@ -499,7 +504,7 @@ nxgl_coord_t CIconMgr::getRowHeight(void) * @param name The prefix for this icon manager name */ -bool CIconMgr::createWindow(FAR const char *prefix) +bool CIconMgr::createIconManagerWindow(FAR const char *prefix) { static FAR const char *rootName = "Icon Manager"; @@ -514,12 +519,22 @@ bool CIconMgr::createWindow(FAR const char *prefix) FAR const char *name = (allocName == (FAR char *)0) ? rootName : allocName; - // Create the icon manager window + // Create the icon manager window. Customizations: + // + // WFLAGS_NO_MENU_BUTTON: There is no menu associated with the Icon + // Manager + // WFLAGS_NO_DELETE_BUTTON: The user cannot delete the Icon Manager window + // WFLAGS_NO_RESIZE_BUTTON: The user cannot control the Icon Manager + // window size + // WFLAGS_IS_ICONMGR: Yes, this is the Icon Manager window CWindowFactory *factory = m_twm4nx->getWindowFactory(); + uint8_t wflags = (WFLAGS_NO_MENU_BUTTON | WFLAGS_NO_DELETE_BUTTON | + WFLAGS_NO_RESIZE_BUTTON | WFLAGS_IS_ICONMGR); + m_window = factory->createWindow(name, &CONFIG_TWM4NX_ICONMGR_IMAGE, - true, this, false); + this, wflags); if (m_window == (FAR CWindow *)0) { diff --git a/graphics/twm4nx/src/cinput.cxx b/graphics/twm4nx/src/cinput.cxx index 7e5125ccf..c2d34e917 100644 --- a/graphics/twm4nx/src/cinput.cxx +++ b/graphics/twm4nx/src/cinput.cxx @@ -103,6 +103,9 @@ CInput::CInput(CTwm4Nx *twm4nx) m_mouseFd = -1; // Mouse/touchscreen driver is not opened #endif m_state = LISTENER_NOTRUNNING; // The listener thread is not running yet +#ifdef CONFIG_TWM4NX_TOUCHSCREEN + m_calib = false; // Use raw touches until calibrated +#endif // Initialize the semaphore used to synchronize with the listener thread @@ -144,6 +147,29 @@ CInput::~CInput(void) #endif } +#ifdef CONFIG_TWM4NX_TOUCHSCREEN +/** + * 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 + * touchscreen events in window-relative positions to the correct NX window. + * + * @param caldata. A reference to the touchscreen data. + */ + +void CInput::setCalibrationData(const struct SCalibrationData &caldata) +{ + // Save a copy of the calibration data + + m_calData = caldata; + + // Note that we have calibration data. Data will now be scaled before being + // forwarded to NX + + m_calib = true; +} +#endif + /** * Start the keyboard listener thread. * @@ -416,6 +442,127 @@ int CInput::keyboardInput(void) } #endif +/** + * Calibrate raw touchscreen input. + * + * @param raw The raw touch sample + * @param scaled The location to return the scaled touch position + * @return On success, this method returns zero (OK). A negated errno + * value is returned if an irrecoverable error occurs. + */ + +#ifdef CONFIG_TWM4NX_TOUCHSCREEN +int CInput::scaleTouchData(FAR const struct touch_point_s &raw, + FAR struct nxgl_point_s &scaled) +{ +#ifdef CONFIG_NXWM_CALIBRATION_ANISOTROPIC + // Create a line (varying in X) that have the same matching Y values + // X lines: + // + // x2 = slope*y1 + offset + // + // X value calculated on the left side for the given value of y + + float leftX = raw.y * m_calData.left.slope + m_calData.left.offset; + + // X value calculated on the right side for the given value of y + + float rightX = raw.y * m_calData.right.slope + m_calData.right.offset; + + // Line of X values between (m_calData.leftX,leftX) and + // (m_calData.rightX,rightX) the are possible solutions: + // + // x2 = slope * x1 - offset + + struct SCalibrationLine xLine; + xLine.slope = (float)((int)m_calData.rightX - + (int)m_calData.leftX) / (rightX - leftX); + xLine.offset = (float)m_calData.leftX - leftX * xLine.slope; + + // Create a line (varying in Y) that have the same matching X value + // X lines: + // + // y2 = slope*x1 + offset + // + // Y value calculated on the top side for a given value of X + + float topY = raw.x * m_calData.top.slope + m_calData.top.offset; + + // Y value calculated on the bottom side for a give value of X + + float bottomY = raw.x * m_calData.bottom.slope + + m_calData.bottom.offset; + + // Line of Y values between (topy,m_calData.topY) and + // (bottomy,m_calData.bottomY) that are possible solutions: + // + // y2 = slope * y1 - offset + + struct SCalibrationLine yLine; + yLine.slope = (float)((int)m_calData.bottomY - + (int)m_calData.topY) / (bottomY - topY); + yLine.offset = (float)m_calData.topY - topY * yLine.slope; + + // Then scale the raw x and y positions + + float scaledX = raw.x * xLine.slope + xLine.offset; + float scaledY = raw.y * yLine.slope + yLine.offset; + + scaled.x = (nxgl_coord_t)scaledX; + scaled.y = (nxgl_coord_t)scaledY; + + twminfo("raw: (%6.2f, %6.2f) scaled: (%6.2f, %6.2f) (%d, %d)\n", + raw.x, raw.y, scaledX, scaledY, scaled.x, scaled.y); +#else + // Get the fixed precision, scaled X and Y values + + b16_t scaledX = raw.x * m_calData.xSlope + m_calData.xOffset; + b16_t scaledY = raw.y * m_calData.ySlope + m_calData.yOffset; + + // Get integer scaled X and Y positions and clip + // to fix in the window + + int32_t bigX = b16toi(scaledX + b16HALF); + int32_t bigY = b16toi(scaledY + b16HALF); + + // Clip to the display + + struct nxgl_size_s displaySize; + m_twm4nx->getDisplaySize(&displaySize); + + + if (bigX < 0) + { + scaled.x = 0; + } + else if (bigX >= displaySize.w) + { + scaled.x = displaySize.w - 1; + } + else + { + scaled.x = (nxgl_coord_t)bigX; + } + + if (bigY < 0) + { + scaled.y = 0; + } + else if (bigY >= displaySize.h) + { + scaled.y = displaySize.h - 1; + } + else + { + scaled.y = (nxgl_coord_t)bigY; + } + + twminfo("raw: (%d, %d) scaled: (%d, %d)\n", + raw.x, raw.y, scaled.x, scaled.y); +#endif +} +#endif + /** * Read data from the mouse/touchscreen device. If the input device is a * mouse, then update the cursor position. And, in either case, inject @@ -430,7 +577,7 @@ int CInput::mouseInput(void) { // Read one mouse sample - twminfo("Reading mouse input\n"); + twminfo("Reading XY input\n"); uint8_t rxbuffer[CONFIG_TWM4NX_MOUSE_BUFSIZE]; ssize_t nbytes = read(m_mouseFd, rxbuffer, @@ -481,6 +628,9 @@ int CInput::mouseInput(void) FAR struct mouse_report_s *rpt = (FAR struct mouse_report_s *)rxbuffer; + twminfo("Mouse pos: (%d,%d) Buttons: %02x\n", + rtp->x, rpt->y, rpt->buttons); + struct nxgl_point_s pos = { .x = rpt->x, @@ -527,12 +677,64 @@ int CInput::mouseInput(void) // Inject the touchscreen as mouse input into NX (with the left // button pressed) - FAR struct touch_sample_s *rpt = + FAR struct touch_sample_s *sample = (FAR struct touch_sample_s *)rxbuffer; + // Have we received calibration data yet? + + struct nxgl_point_s touchPos; + int ret; + + if (m_calib) + { + // Yes.. scale the raw mouse input to fit the display + + ret = scaleTouchData(sample->point[0], touchPos); + if (ret < 0) + { + twmerr("ERROR: scaleTouchData failed: %d\n", ret); + return ret; + } + } + else + { + // Hmm.. It is probably an error if no calibration data is + // provided. However, it is also possible that the touch data as + // received does not require calibration. We will just have to + // trust that the user knows what they are doing. + + touchPos.x = sample->point[0].x; + touchPos.y = sample->point[0].y; + } + + // Now we will inject the touchscreen into NX as mouse input. First + // massage the data a little so that it behaves a little more like a + // mouse with only a left button + // + // Was the touch up or down? + + uint8_t buttons; + if ((sample->point[0].flags & (TOUCH_DOWN | TOUCH_MOVE)) != 0) + { + buttons = MOUSE_BUTTON_1; + } + else if ((sample->point[0].flags & TOUCH_UP) != 0) + { + buttons = 0; + } + else + { + // The touch is neither up nor down. This should not happen + + return -EIO; + } + + twminfo("Touch pos: (%d,%d)->(%d,%d) Buttons: %02x\n", + sample->point[0].x, sample->point[0].y, + touchPos.x, touchPos.y, buttons); + NXHANDLE server = m_twm4nx->getServer(); - int ret = nx_mousein(server, rpt->point[0].x, rpt->point[0].y, - MOUSE_BUTTON_1); + ret = nx_mousein(server, touchPos.x, touchPos.y, buttons); if (ret < 0) { twmerr("ERROR: nx_mousein failed: %d\n", ret); diff --git a/graphics/twm4nx/src/cwindow.cxx b/graphics/twm4nx/src/cwindow.cxx index 25bd3c66e..10561f683 100644 --- a/graphics/twm4nx/src/cwindow.cxx +++ b/graphics/twm4nx/src/cwindow.cxx @@ -148,13 +148,13 @@ CWindow::CWindow(CTwm4Nx *twm4nx) m_tbHeight = 0; // Height of the toolbar m_tbLeftX = 0; // Temporaries m_tbRightX = 0; + m_tbFlags = 0; // No customizations // Icons/Icon Manager m_iconBitMap = (FAR NXWidgets::CRlePaletteBitmap *)0; m_iconWidget = (FAR CIconWidget *)0; m_iconMgr = (FAR CIconMgr *)0; - m_isIconMgr = false; m_iconOn = false; m_iconified = false; @@ -187,9 +187,8 @@ CWindow::~CWindow(void) * @param pos The initialize position of the window * @param size The initial size of the window * @param sbitmap The Icon bitmap image - * @param isIconMgr Flag to tell if this is an icon manager window * @param iconMgr Pointer to icon manager instance - * @param noToolbar True: Don't add Title Bar + * @param flags Toolbar customizations see WFLAGS_NO_* definition * @return True if the window was successfully initialize; false on * any failure, */ @@ -198,8 +197,7 @@ bool CWindow::initialize(FAR const char *name, FAR const struct nxgl_point_s *pos, FAR const struct nxgl_size_s *size, FAR const struct NXWidgets::SRlePaletteBitmap *sbitmap, - bool isIconMgr, FAR CIconMgr *iconMgr, - bool noToolbar) + FAR CIconMgr *iconMgr, uint8_t flags) { // Open a message queue to send fully digested NxWidget events. @@ -213,8 +211,7 @@ bool CWindow::initialize(FAR const char *name, return false; } - m_isIconMgr = isIconMgr; - m_iconMgr = iconMgr; + m_iconMgr = iconMgr; if (name == (FAR const char *)0) { @@ -260,9 +257,10 @@ bool CWindow::initialize(FAR const char *name, } m_tbHeight = 0; + m_tbFlags = flags; m_toolbar = (FAR NXWidgets::CNxToolbar *)0; - if (!noToolbar) + if (WFLAGS_HAVE_TOOLBAR(flags)) { // Toolbar height should be based on size of images and fonts. @@ -284,7 +282,7 @@ bool CWindow::initialize(FAR const char *name, // Add buttons to the toolbar - if (!createToolbarButtons()) + if (!createToolbarButtons(flags)) { twmerr("ERROR: createToolbarButtons() failed\n"); cleanup(); @@ -421,7 +419,7 @@ bool CWindow::resizeFrame(FAR const struct nxgl_size_s *size, m_nxWin->synchronize(); - // Then update the toolbar layout + // Then update the toolbar layout (if there is one) return updateToolbarLayout(); } @@ -536,6 +534,26 @@ bool CWindow::event(FAR struct SEventMsg *eventmsg) break; + case EVENT_TOOLBAR_MENU: // Toolbar menu button released + { + // REVISIT: Not yet implemented (but don't raise an error) + } + break; + + case EVENT_TOOLBAR_MINIMIZE: // Toolbar minimize button released + { + // Minimize (iconify) the window + + iconify(); + } + break; + + case EVENT_TOOLBAR_RESIZE: // Toolbar resize button released + { + // REVISIT: Not yet implemented (but don't raise an error) + } + break; + case EVENT_TOOLBAR_TERMINATE: // Toolbar terminate button pressed if (isIconMgr()) { @@ -761,7 +779,8 @@ bool CWindow::updateToolbarLayout(void) m_tbRightX = 0; for (int btindex = 0; btindex < NTOOLBAR_BUTTONS; btindex++) { - if (GToolBarInfo[btindex].rightSide) + if (m_tbButtons[btindex] != (FAR NXWidgets::CImage *)0 && + GToolBarInfo[btindex].rightSide) { FAR NXWidgets::CImage *cimage = m_tbButtons[btindex]; @@ -813,8 +832,11 @@ bool CWindow::disableWidgets(void) for (int btindex = 0; btindex < NTOOLBAR_BUTTONS; btindex++) { FAR NXWidgets::CImage *cimage = m_tbButtons[btindex]; - cimage->disableDrawing(); - cimage->setRaisesEvents(false); + if (cimage != (FAR NXWidgets::CImage *)0) + { + cimage->disableDrawing(); + cimage->setRaisesEvents(false); + } } m_tbTitle->disableDrawing(); @@ -831,9 +853,12 @@ bool CWindow::enableWidgets(void) for (int btindex = 0; btindex < NTOOLBAR_BUTTONS; btindex++) { FAR NXWidgets::CImage *cimage = m_tbButtons[btindex]; - cimage->enableDrawing(); - cimage->setRaisesEvents(true); - cimage->redraw(); + if (cimage != (FAR NXWidgets::CImage *)0) + { + cimage->enableDrawing(); + cimage->setRaisesEvents(true); + cimage->redraw(); + } } m_tbTitle->enableDrawing(); @@ -844,9 +869,13 @@ bool CWindow::enableWidgets(void) /** * Create all toolbar buttons + * + * @param flags Toolbar customizations see WFLAGS_NO_* definitions + * @return True if the window was successfully initialize; false on + * any failure, */ -bool CWindow::createToolbarButtons(void) +bool CWindow::createToolbarButtons(uint8_t flags) { struct nxgl_size_s winsize; if (!getWindowSize(&winsize)) @@ -862,6 +891,17 @@ bool CWindow::createToolbarButtons(void) for (int btindex = 0; btindex < NTOOLBAR_BUTTONS; btindex++) { + // Check if this button is omitted by toolbar customizations + + if ((m_tbFlags & (1 << btindex)) != 0) + { + // Omitted.. skip to the next button + + continue; + } + + // Create the bitmap instance + FAR const NXWidgets::SRlePaletteBitmap *sbitmap = GToolBarInfo[btindex].bitmap; @@ -1240,7 +1280,8 @@ void CWindow::handleActionEvent(const NXWidgets::CWidgetEventArgs &e) { // Check if the widget is clicked - if (m_tbButtons[btindex]->isClicked()) + if (m_tbButtons[btindex] != (FAR NXWidgets::CImage *)0 && + m_tbButtons[btindex]->isClicked()) { // Yes.. generate the event diff --git a/graphics/twm4nx/src/cwindowfactory.cxx b/graphics/twm4nx/src/cwindowfactory.cxx index f10227277..d5fa9a463 100644 --- a/graphics/twm4nx/src/cwindowfactory.cxx +++ b/graphics/twm4nx/src/cwindowfactory.cxx @@ -100,17 +100,15 @@ CWindowFactory::~CWindowFactory(void) * * @param name The window name * @param sbitmap The Icon bitmap - * @param isIconMgr Flag to tell if this is an icon manager window * @param iconMgr Pointer to icon manager instance - * @param noToolbar True: Don't add Title Bar + * @param flags Toolbar customizations see WFLAGS_NO_* definitions * @return Reference to the allocated CWindow instance */ FAR CWindow * CWindowFactory::createWindow(FAR const char *name, FAR const struct NXWidgets::SRlePaletteBitmap *sbitmap, - bool isIconMgr, FAR CIconMgr *iconMgr, - bool noToolbar) + FAR CIconMgr *iconMgr, uint8_t flags) { twminfo("name=%p\n", name); @@ -169,7 +167,7 @@ FAR CWindow * m_winpos.x, m_winpos.y, winsize.w, winsize.h); if (!win->cwin->initialize(name, &m_winpos, &winsize, sbitmap, - isIconMgr, iconMgr, noToolbar)) + iconMgr, flags)) { twmerr("ERROR: Failed to initialize CWindow\n"); delete win->cwin; diff --git a/include/graphics/nxwm/ccalibration.hxx b/include/graphics/nxwm/ccalibration.hxx index cb907ada3..87cc22d36 100644 --- a/include/graphics/nxwm/ccalibration.hxx +++ b/include/graphics/nxwm/ccalibration.hxx @@ -271,6 +271,7 @@ namespace NxWM static FAR void *calibration(FAR void *arg); +#ifdef CONFIG_NXWM_CALIBRATION_AVERAGE /** * Accumulate and average touch sample data * @@ -278,7 +279,6 @@ namespace NxWM * @return True: Average data is available; False: Need to collect more samples */ -#ifdef CONFIG_NXWM_CALIBRATION_AVERAGE bool averageSamples(struct nxgl_point_s &average); #endif diff --git a/include/graphics/nxwm/ctouchscreen.hxx b/include/graphics/nxwm/ctouchscreen.hxx index 2e1c04b74..8434be534 100644 --- a/include/graphics/nxwm/ctouchscreen.hxx +++ b/include/graphics/nxwm/ctouchscreen.hxx @@ -111,7 +111,7 @@ namespace NxWM static FAR void *listener(FAR void *arg); /** - * Inject touchscreen data into NX as mouse intput + * Inject touchscreen data into NX as mouse input * * @param sample. The buffer where data was collected. */ @@ -183,7 +183,7 @@ namespace NxWM * using the calibration data and forward to the NX layer which dispatches the * touchscreen events in window-relative positions to the correct NX window. * - * @param data. A reference to the touchscreen data. + * @param caldata. A reference to the touchscreen data. */ void setCalibrationData(const struct SCalibrationData &caldata); @@ -201,6 +201,7 @@ namespace NxWM { caldata = m_calibData; } + return m_calibrated; } diff --git a/include/graphics/twm4nx/ciconmgr.hxx b/include/graphics/twm4nx/ciconmgr.hxx index 1385b364b..5bb8d6a59 100644 --- a/include/graphics/twm4nx/ciconmgr.hxx +++ b/include/graphics/twm4nx/ciconmgr.hxx @@ -113,7 +113,7 @@ namespace Twm4Nx * @param name The prefix for this icon manager name */ - bool createWindow(FAR const char *prefix); + bool createIconManagerWindow(FAR const char *prefix); /** * Create the button array widget diff --git a/include/graphics/twm4nx/cinput.hxx b/include/graphics/twm4nx/cinput.hxx index 7b3d36c9f..cf9648a35 100644 --- a/include/graphics/twm4nx/cinput.hxx +++ b/include/graphics/twm4nx/cinput.hxx @@ -45,7 +45,9 @@ #include #include +#include +#include #include #include "graphics/nxwidgets/cnxserver.hxx" @@ -58,6 +60,40 @@ namespace Twm4Nx { class CTwm4Nx; // Forward reference +#ifdef CONFIG_TWM4NX_TOUCHSCREEN + /** + * Touchscreen calibration data + */ + +#ifdef CONFIG_TWM4NX_TOUCHSCREEN_ANISOTROPIC + struct SCalibrationLine + { + float slope; /**< The slope of a line */ + float offset; /**< The offset of a line */ + }; + + struct SCalibrationData + { + struct SCalibrationLine left; /**< Describes Y values along left edge */ + struct SCalibrationLine right; /**< Describes Y values along right edge */ + struct SCalibrationLine top; /**< Describes X values along top */ + struct SCalibrationLine bottom; /**< Describes X values along bottom edge */ + nxgl_coord_t leftX; /**< Left X value used in calibration */ + nxgl_coord_t rightX; /**< Right X value used in calibration */ + nxgl_coord_t topY; /**< Top Y value used in calibration */ + nxgl_coord_t bottomY; /**< Bottom Y value used in calibration */ + }; +#else + struct SCalibrationData + { + b16_t xSlope; /**< X conversion: xSlope*(x) + xOffset */ + b16_t xOffset; + b16_t ySlope; /**< Y conversion: ySlope*(y) + yOffset */ + b16_t yOffset; + }; +#endif +#endif // CONFIG_TWM4NX_TOUCHSCREEN + /** * The CInput class provides receives raw keyboard and mouse inputs and * injects that input into NX which it can be properly distributed to the @@ -99,6 +135,11 @@ namespace Twm4Nx volatile enum EListenerState m_state; /**< The state of the listener thread */ sem_t m_waitSem; /**< Used to synchronize with the listener thread */ +#ifdef CONFIG_TWM4NX_TOUCHSCREEN + bool m_calib; /**< False: Use raw, uncalibrated touches */ + struct SCalibrationData m_calData; /**< Touchscreen calibration data */ +#endif + #ifndef CONFIG_TWM4NX_NOKEYBOARD /** * Open the keyboard device. Not very interesting for the case of @@ -148,12 +189,26 @@ namespace Twm4Nx #endif #ifndef CONFIG_TWM4NX_NOMOUSE +#ifdef CONFIG_TWM4NX_TOUCHSCREEN + /** + * Calibrate raw touchscreen input. + * + * @param raw The raw touch sample + * @param scaled The location to return the scaled touch position + * @return On success, this method returns zero (OK). A negated errno + * value is returned if an irrecoverable error occurs. + */ + + int scaleTouchData(FAR const struct touch_point_s &raw, + FAR struct nxgl_point_s &scaled); +#endif + /** * Read data from the mouse/touchscreen device. If the input device * is a mouse, then update the cursor position. And, in either case, * inject the mouse data into NX for proper distribution. * - * @return On success, then method returns zero (OK). A negated errno + * @return On success, this method returns zero (OK). A negated errno * value is returned if an irrecoverable error occurs. */ @@ -209,6 +264,19 @@ namespace Twm4Nx ~CInput(void); +#ifdef CONFIG_TWM4NX_TOUCHSCREEN + /** + * 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 + * touchscreen events in window-relative positions to the correct NX window. + * + * @param caldata. A reference to the touchscreen data. + */ + + void setCalibrationData(const struct SCalibrationData &caldata); +#endif + /** * Start the keyboard listener thread. * diff --git a/include/graphics/twm4nx/cwindow.hxx b/include/graphics/twm4nx/cwindow.hxx index 520b6d280..e2395d11e 100644 --- a/include/graphics/twm4nx/cwindow.hxx +++ b/include/graphics/twm4nx/cwindow.hxx @@ -76,11 +76,31 @@ * There is no focus indicator */ -#define MENU_BUTTON 0 // First on left -#define DELETE_BUTTON 1 // First on right -#define RESIZE_BUTTON 2 -#define MINIMIZE_BUTTON 3 -#define NTOOLBAR_BUTTONS 4 +#define MENU_BUTTON 0 // First on left +#define DELETE_BUTTON 1 // First on right +#define RESIZE_BUTTON 2 +#define MINIMIZE_BUTTON 3 +#define NTOOLBAR_BUTTONS 4 + +// Windows may be customized with the flags parameter to the constructor. +// These are the bits fields that may be OR'ed together in the flags. + +#define NO_TOOLBAR (NTOOLBAR_BUTTONS + 0) +#define ICONMGR_WINDOW (NTOOLBAR_BUTTONS + 1) + +#define WFLAGS_NO_MENU_BUTTON (1 << MENU_BUTTON) +#define WFLAGS_NO_DELETE_BUTTON (1 << DELETE_BUTTON) +#define WFLAGS_NO_RESIZE_BUTTON (1 << RESIZE_BUTTON) +#define WFLAGS_NO_MINIMIZE_BUTTON (1 << MINIMIZE_BUTTON) +#define WFLAGS_NO_TOOLBAR (1 << NO_TOOLBAR) +#define WFLAGS_IS_ICONMGR (1 << ICONMGR_WINDOW) + +#define WFLAGS_HAVE_MENU_BUTTON(f) (((f) & WFLAGS_NO_MENU_BUTTON) == 0) +#define WFLAGS_HAVE_DELETE_BUTTON(f) (((f) & WFLAGS_NO_DELETE_BUTTON) == 0) +#define WFLAGS_HAVE_RESIZE_BUTTON(f) (((f) & WFLAGS_NO_RESIZE_BUTTON) == 0) +#define WFLAGS_HAVE_MINIMIZE_BUTTON(f) (((f) & WFLAGS_NO_MINIMIZE_BUTTON) == 0) +#define WFLAGS_HAVE_TOOLBAR(f) (((f) & WFLAGS_NO_TOOLBAR) == 0) +#define WFLAGS_IS_ICONMGR_WINDOW(f) (((f) & WFLAGS_IS_ICONMGR) != 0) ///////////////////////////////////////////////////////////////////////////// // Implementation Classes @@ -123,7 +143,6 @@ namespace Twm4Nx FAR CIconWidget *m_iconWidget; /**< The icon widget */ FAR CIconMgr *m_iconMgr; /**< Pointer to it if this is an icon manager */ - bool m_isIconMgr; /**< This is an icon manager window */ bool m_iconMoved; /**< User explicitly moved the icon. */ bool m_iconOn; /**< Icon is visible. */ bool m_iconified; /**< Is the window an icon now ? */ @@ -135,6 +154,7 @@ namespace Twm4Nx nxgl_coord_t m_tbHeight; /**< Height of the toolbar */ nxgl_coord_t m_tbLeftX; /**< Rightmost position of left buttons */ nxgl_coord_t m_tbRightX; /**< Leftmost position of right buttons */ + uint8_t m_tbFlags; /**< Toolbar button customizations */ // List of all toolbar button images @@ -164,9 +184,13 @@ namespace Twm4Nx /** * Create all toolbar buttons + * + * @param flags Toolbar customizations see WFLAGS_NO_* definitions + * @return True if the window was successfully initialize; false on + * any failure, */ - bool createToolbarButtons(void); + bool createToolbarButtons(uint8_t flags); /** * Add buttons and title widgets to the tool bar @@ -321,9 +345,8 @@ namespace Twm4Nx * @param pos The initial position of the window * @param size The initial size of the window * @param sbitmap The Icon bitmap image - * @param isIconMgr Flag to tell if this is an icon manager window * @param iconMgr Pointer to icon manager instance - * @param noToolbar True: Don't add Title Bar + * @param flags Toolbar customizations see WFLAGS_NO_* definitions * @return True if the window was successfully initialize; false on * any failure, */ @@ -332,7 +355,7 @@ namespace Twm4Nx FAR const struct nxgl_point_s *pos, FAR const struct nxgl_size_s *size, FAR const struct NXWidgets::SRlePaletteBitmap *sbitmap, - bool isIconMgr, FAR CIconMgr *iconMgr, bool noToolbar); + FAR CIconMgr *iconMgr, uint8_t flags = 0); /** * Synchronize the window with the NX server. This function will delay @@ -371,7 +394,7 @@ namespace Twm4Nx inline bool isIconMgr(void) { - return m_isIconMgr; + return WFLAGS_IS_ICONMGR_WINDOW(m_tbFlags); } /** @@ -648,7 +671,12 @@ namespace Twm4Nx inline bool pollToolbarEvents(void) { NXWidgets::CWidgetControl *control = m_toolbar->getWidgetControl(); - return control->pollEvents(); + + // pollEvents() returns true if any interesting event occurred. + // false is not a failure. + + (void)control->pollEvents(); + return true; } /** diff --git a/include/graphics/twm4nx/cwindowfactory.hxx b/include/graphics/twm4nx/cwindowfactory.hxx index 28bd773fc..ea17e683c 100644 --- a/include/graphics/twm4nx/cwindowfactory.hxx +++ b/include/graphics/twm4nx/cwindowfactory.hxx @@ -139,18 +139,17 @@ namespace Twm4Nx /** * Create a new window and add it to the window list. * - * @param name The window name + * @param name The window name * @param sbitmap The Icon bitmap - * @param isIconMgr Flag to tell if this is an icon manager window - * @param iconMgr Pointer to icon manager instance - * @param noToolbar True: Don't add Title Bar - * @return Reference to the allocated CWindow instance + * @param iconMgr Pointer to icon manager instance + * @param flags Toolbar customizations see WFLAGS_NO_* definitions + * @return Reference to the allocated CWindow instance */ FAR CWindow * createWindow(FAR const char *name, FAR const struct NXWidgets::SRlePaletteBitmap *sbitmap, - bool isIconMgr, FAR CIconMgr *iconMgr, bool noToolbar); + FAR CIconMgr *iconMgr, uint8_t flags); /** * Handle the EVENT_WINDOW_DELETE event. The logic sequence is as