Squashed commit of the following:

apps/graphics/tmw4nx and apps/graphics/slcd:  This seems the last of the show stopper bugs.  All seems functional.

    apps/graphics/slcd:  Correct some errors found in early texting.  Now the Twm4Nx::CClock window comes up, but there are problems with the way that the segments are being displayed.

    apps/graphicx/twm4nx:  CClock is complete and compiles correctly.  Crashes with a hardware when the clock is selected from the Main Menu, however.
This commit is contained in:
Gregory Nutt 2019-06-01 13:00:02 -06:00
parent 51c3d3a054
commit c1bb142e18
14 changed files with 1225 additions and 91 deletions

View File

@ -85,6 +85,10 @@ CSLcd::CSLcd(NXWidgets::INxWindow *wnd, nxgl_coord_t height)
void CSLcd::scale(nxgl_coord_t height)
{
// Save the new height
m_height = height;
// Scale each segment
scaleSegment(GTop_Runs, m_top, NTOP_TRAPEZOIDS + 1);
@ -92,8 +96,8 @@ void CSLcd::scale(nxgl_coord_t height)
scaleSegment(GTopRight_Runs, m_topRight, NTOPRIGHT_TRAPEZOIDS + 1);
scaleSegment(GMiddle_Runs, m_middle, NMIDDLE_TRAPEZOIDS + 1);
scaleSegment(GBottomLeft_Runs, m_bottomLeft, NBOTTOMLEFT_TRAPEZOIDS + 1);
scaleSegment(GBottomRight_Runs, m_bottom, NBOTTOMRIGHT_TRAPEZOIDS + 1);
scaleSegment(GBottom_Runs, m_top, NBOTTOM_TRAPEZOIDS + 1);
scaleSegment(GBottomRight_Runs, m_bottomRight, NBOTTOMRIGHT_TRAPEZOIDS + 1);
scaleSegment(GBottom_Runs, m_bottom, NBOTTOM_TRAPEZOIDS + 1);
}
/**
@ -209,12 +213,12 @@ bool CSLcd::show(uint8_t code, FAR const struct nxgl_point_s &pos)
if ((code & SEGMENT_6) != 0)
{
showSegment(m_bottom, pos, NBOTTOMRIGHT_TRAPEZOIDS);
showSegment(m_bottomRight, pos, NBOTTOMRIGHT_TRAPEZOIDS);
}
if ((code & SEGMENT_7) != 0)
{
showSegment(m_top, pos, NBOTTOM_TRAPEZOIDS);
showSegment(m_bottom, pos, NBOTTOM_TRAPEZOIDS);
}
return true;
@ -240,7 +244,8 @@ void CSLcd::scaleSegment(FAR const struct SLcdTrapezoidRun *run,
trapezoid[0].top.x2 = m_height * run[0].rightx;
trapezoid[0].top.y = b16toi(m_height * run[0].y);
for (int i = 1; i <= nRuns; i++)
int nTraps = nRuns - 1;
for (int i = 1; i < nRuns; i++)
{
// Get the bottom of the previous trapezoid
@ -248,7 +253,7 @@ void CSLcd::scaleSegment(FAR const struct SLcdTrapezoidRun *run,
trapezoid[i - 1].bot.x2 = m_height * run[i].rightx;
trapezoid[i - 1].bot.y = b16toi(m_height * run[i].y);
if (i < nRuns)
if (i < nTraps)
{
// Get the top of the current trapezoid

View File

@ -43,19 +43,12 @@
#include <cstdint>
#include <fixedmath.h>
#include "graphics/nxwidgets/nxconfig.hxx"
#include "graphics/slcd.hxx"
/////////////////////////////////////////////////////////////////////////////
// Pre-processor definitions
/////////////////////////////////////////////////////////////////////////////
// Default colors: Light grey-green background, greenish-black foreground.
// Similar to what you would see on a classic LCD.
#define SLCD_BACKGROUND MKRGB(128, 140, 128)
#define SLCD_FOREGROUND MKRGB(0, 16, 0)
// Segment encoding:
//
// 11111111

View File

@ -68,6 +68,10 @@ ifeq ($(CONFIG_TWM4NX_CALIBRATION),y)
CXXSRCS += ccalibration.cxx
endif
ifeq ($(CONFIG_TWM4NX_CLOCK),y)
CXXSRCS += cclock.cxx
endif
ifeq ($(CONFIG_TWM4NX_NXTERM),y)
CXXSRCS += cnxterm.cxx
endif

View File

@ -32,3 +32,24 @@ config TWM4NX_NXTERM
---help---
Enable support for the NxTerm window which provides a text window
in which you can interact with NSH.
if TWM4NX_NXTERM
endif # TWM4NX_NXTERM
config TWM4NX_CLOCK
bool "Retro segment LCD clock"
default y
select GRAPHICS_SLCD
---help---
Enable support for the LCD clock window based on the retro segment
LCD driver of apps/graphics/slcd.
if TWM4NX_CLOCK
config TWM4NX_CLOCK_HEIGHT
int "LCD clock height"
default 64
---help---
Fixed height of the LCD clock. The clock window is not re-sizeable.
endif # TWM4NX_CLOCK

View File

@ -195,7 +195,7 @@ bool CCalibration::initialize(void)
m_nxWin = m_twm4nx->createRawWindow(control, wflags);
if (m_nxWin == (FAR NXWidgets::CNxWindow *)0)
{
gerr("ERROR: Failed open raw window\n");
twmerr("ERROR: Failed open raw window\n");
delete control;
return false;
}
@ -242,7 +242,7 @@ bool CCalibration::initialize(void)
if (!createWidgets())
{
gerr("ERROR: failed to create widgets\n");
twmerr("ERROR: failed to create widgets\n");
return (FAR void *)0;
}
#endif
@ -268,7 +268,7 @@ bool CCalibration::run(void)
if (m_calthread == CALTHREAD_RUNNING)
{
gwarn("WARNING: The calibration thread is already running\n");
twmwarn("WARNING: The calibration thread is already running\n");
return false;
}
@ -292,11 +292,11 @@ bool CCalibration::run(void)
int ret = pthread_create(&m_thread, &attr, calibration, (FAR void *)this);
if (ret != 0)
{
gerr("ERROR: pthread_create failed: %d\n", ret);
twmerr("ERROR: pthread_create failed: %d\n", ret);
return false;
}
ginfo("Calibration thread m_calthread=%d\n", (int)m_calthread);
twminfo("Calibration thread m_calthread=%d\n", (int)m_calthread);
return true;
}
@ -426,7 +426,7 @@ bool CCalibration::createWidgets(void)
CONFIG_TWM4NX_DEFAULT_FONTCOLOR, CONFIG_TWM4NX_TRANSPARENT_COLOR);
if (!m_font)
{
gerr("ERROR failed to create font\n");
twmerr("ERROR failed to create font\n");
return false;
}
@ -435,7 +435,7 @@ bool CCalibration::createWidgets(void)
struct nxgl_size_s windowSize;
if (!m_nxWin->getSize(&windowSize))
{
gerr("ERROR: Failed to get window size\n");
twmerr("ERROR: Failed to get window size\n");
delete m_font;
m_font = (NXWidgets::CNxFont *)0;
return false;
@ -474,7 +474,7 @@ bool CCalibration::createWidgets(void)
if (!m_text)
{
gerr("ERROR: Failed to create CLabel\n");
twmerr("ERROR: Failed to create CLabel\n");
delete m_font;
m_font = (NXWidgets::CNxFont *)0;
return false;
@ -530,7 +530,7 @@ FAR void *CCalibration::calibration(FAR void *arg)
This->m_calthread = CALTHREAD_RUNNING;
This->m_calphase = CALPHASE_NOT_STARTED;
ginfo("Started: m_calthread=%d\n", (int)This->m_calthread);
twminfo("Started: m_calthread=%d\n", (int)This->m_calthread);
// Make the calibration display visible and show the initial calibration
// display
@ -574,7 +574,7 @@ FAR void *CCalibration::calibration(FAR void *arg)
This->destroy();
ginfo("Terminated: m_calthread=%d\n", (int)This->m_calthread);
twminfo("Terminated: m_calthread=%d\n", (int)This->m_calthread);
return (FAR void *)0;
}
@ -783,7 +783,7 @@ bool CCalibration::averageSamples(struct nxgl_point_s &average)
void CCalibration::stateMachine(void)
{
ginfo("Old m_calphase=%d\n", m_calphase);
twminfo("Old m_calphase=%d\n", m_calphase);
#ifdef CONFIG_TWM4NX_CALIBRATION_AVERAGE
// Are we collecting samples?
@ -1092,7 +1092,7 @@ void CCalibration::finishCalibration(void)
sizeof(struct SCalibrationData));
if (ret != 0)
{
gerr("ERROR: Failed to save calibration data\n");
twmerr("ERROR: Failed to save calibration data\n");
}
#endif
// And provide the calibration data to CInput, enabling
@ -1116,7 +1116,7 @@ void CCalibration::finishCalibration(void)
void CCalibration::stop(void)
{
ginfo("Stopping calibration: m_calthread=%d\n", (int)m_calthread);
twminfo("Stopping calibration: m_calthread=%d\n", (int)m_calthread);
// Was the calibration thread created?
@ -1135,7 +1135,7 @@ void CCalibration::stop(void)
// Try to wake up the calibration thread so that it will see our
// termination request
ginfo("Stopping calibration: m_calthread=%d\n", (int)m_calthread);
twminfo("Stopping calibration: m_calthread=%d\n", (int)m_calthread);
(void)pthread_kill(m_thread, CONFIG_TWM4NX_CALIBRATION_SIGNO);
// Wait for the calibration thread to exit
@ -1187,7 +1187,7 @@ bool CCalibration::createCalibrationData(struct SCalibrationData &data)
struct nxgl_size_s windowSize;
if (!m_nxWin->getSize(&windowSize))
{
gerr("ERROR: NXWidgets::INxWindow::getSize failed\n");
twmerr("ERROR: NXWidgets::INxWindow::getSize failed\n");
return false;
}

View File

@ -0,0 +1,658 @@
/////////////////////////////////////////////////////////////////////////////
// apps/graphics/twm4nx/src/cnxterm.cxx
// Clock window
//
// Copyright (C) 2019 Gregory Nutt. All rights reserved.
// Author: Gregory Nutt <gnutt@nuttx.org>
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// 3. Neither the name NuttX nor the names of its contributors may be
// used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Included Files
/////////////////////////////////////////////////////////////////////////////
#include <nuttx/config.h>
#include <ctime>
#include <cstring>
#include <csched>
#include <cassert>
#include <semaphore.h>
#include <debug.h>
#include <nuttx/semaphore.h>
#include "nshlib/nshlib.h"
#include "graphics/nxwidgets/cwidgetcontrol.hxx"
#include "graphics/nxglyphs.hxx"
#include "graphics/twm4nx/twm4nx_config.hxx"
#include "graphics/twm4nx/ctwm4nx.hxx"
#include "graphics/twm4nx/cwindow.hxx"
#include "graphics/twm4nx/cwindowfactory.hxx"
#include "graphics/twm4nx/cmainmenu.hxx"
#include "graphics/slcd.hxx"
#include "graphics/twm4nx/apps/clock_config.hxx"
#include "graphics/twm4nx/apps/cclock.hxx"
/////////////////////////////////////////////////////////////////////////////
// Private Types
/////////////////////////////////////////////////////////////////////////////
namespace Twm4Nx
{
/////////////////////////////////////////////////////////////////////////////
// Private Types
/////////////////////////////////////////////////////////////////////////////
/**
* This structure is used to pass start up parameters to the Clock task
* and to assure the the Clock is successfully started.
*/
struct SClock
{
FAR CClock *that; /**< The CClock 'this' pointer */
sem_t exclSem; /**< Sem that gives exclusive access to this structure */
sem_t waitSem; /**< Sem that posted when the task is initialized */
bool success; /**< True if successfully initialized */
};
/////////////////////////////////////////////////////////////////////////////
// Private Data
/////////////////////////////////////////////////////////////////////////////
/**
* This global data structure is used to pass start parameters to Clock
* task and to assure that the Clock is successfully started.
*/
static struct SClock GClockVars;
}
/////////////////////////////////////////////////////////////////////////////
// CClock Method Implementations
/////////////////////////////////////////////////////////////////////////////
using namespace Twm4Nx;
/**
* CClock constructor
*
* @param twm4nx. The Twm4Nx session instance
*/
CClock::CClock(FAR CTwm4Nx *twm4nx)
{
// Save/initialize the context data
m_twm4nx = twm4nx;
m_window = (FAR CWindow *)0;
m_slcd = (FAR SLcd::CSLcd *)0;
// The clock task is not running
m_pid = (pid_t)-1;
// This is un-neccessary but helpful in debugging to have a known value
std::memset(m_digits, 0, CLOCK_NDIGITS * sizeof(struct SClockDigit));
}
/**
* CClock destructor
*/
CClock::~CClock(void)
{
// There would be a problem if we were stopped with the Clock task
// running... that should never happen but we'll check anyway:
stop();
// Destroy the CSLcd instance
if (m_window != (FAR CWindow *)0)
{
delete m_window;
}
// Destroy the CSLcd instance
if (m_slcd != (FAR SLcd::CSLcd *)0)
{
delete m_slcd;
}
}
/**
* CClock initializers. Perform miscellaneous post-construction
* initialization that may fail (and hence is not appropriate to be
* done in the constructor)
*
* @return True if the Clock application was successfully initialized.
*/
bool CClock::initialize(void)
{
// Call CWindowFactory::createWindow() to create a window for the Clock
// application. Customizations:
//
// Flags:
// WFLAGS_NO_MENU_BUTTON No menu button in the toolbar
// WFLAGS_NO_RESIZE_BUTTON No resize button in the toolbar
// WFLAGS_HIDDEN Window is initially hidden
//
// Null Icon manager means to use the system, common Icon Manager
NXWidgets::CNxString name("Clock");
uint8_t wflags = (WFLAGS_NO_MENU_BUTTON | WFLAGS_NO_RESIZE_BUTTON |
WFLAGS_HIDDEN);
FAR CWindowFactory *factory = m_twm4nx->getWindowFactory();
m_window = factory->createWindow(name, &CONFIG_TWM4NX_CLOCK_ICON,
(FAR CIconMgr *)0, wflags);
if (m_window == (FAR CWindow *)0)
{
twmerr("ERROR: Failed to create CWindow\n");
return false;
}
// Get the minimum tool bar
// Configure events needed by the Clock applications
struct SAppEvents events;
events.eventObj = (FAR void *)this;
events.redrawEvent = EVENT_CLOCK_REDRAW;
events.resizeEvent = EVENT_CLOCK_RESIZE;
events.mouseEvent = EVENT_CLOCK_XYINPUT;
events.kbdEvent = EVENT_CLOCK_KBDINPUT;
events.closeEvent = EVENT_CLOCK_CLOSE;
events.deleteEvent = EVENT_CLOCK_DELETE;
bool success = m_window->configureEvents(events);
if (!success)
{
delete m_window;
m_window = (FAR CWindow *)0;
return false;
}
// Create an instance of the segment LCD emulation
m_slcd = new SLcd::CSLcd(m_window->getNxWindow(),
CONFIG_TWM4NX_CLOCK_HEIGHT);
if (m_slcd == (FAR SLcd::CSLcd *)0)
{
twmerr("ERROR: Failed to create SLcd::CSLcd instance\n");
delete m_window;
m_window = (FAR CWindow *)0;
return false;
}
// Set the correct size and position of the window based on the SLCD
// character height.
nxgl_coord_t segmentWidth = m_slcd->getWidth();
nxgl_coord_t gapWidth = segmentWidth / 2;
struct nxgl_size_s windowSize;
windowSize.w = 4 * (segmentWidth + CONFIG_TWM4NX_CLOCK_HSPACING) + gapWidth;
windowSize.h = m_slcd->getHeight() + 2 * CONFIG_TWM4NX_CLOCK_HSPACING;
// Check against the minimum toolbar width
nxgl_coord_t minWidth = minimumToolbarWidth(m_twm4nx, name, wflags);
nxgl_coord_t xOffset = CONFIG_TWM4NX_CLOCK_HSPACING;
if (windowSize.w < minWidth)
{
xOffset += (minWidth - windowSize.w) / 2;
windowSize.w = minWidth;
}
// Resize and position the frame. The window is initially position in
// the upper left hand corner of the display.
struct nxgl_size_s frameSize;
m_window->windowToFrameSize(&windowSize, &frameSize);
struct nxgl_point_s framePos;
framePos.x = 0;
framePos.y = 0;
if (!m_window->resizeFrame(&frameSize, &framePos))
{
delete m_window;
m_window = (FAR CWindow *)0;
delete m_slcd;
m_slcd = (FAR SLcd::CSLcd *)0;
return false;
}
// Initialize the SLCD digit horizontal positions
m_digits[0].xOffset = xOffset;
m_digits[1].xOffset = m_digits[0].xOffset + segmentWidth +
CONFIG_TWM4NX_CLOCK_HSPACING;
m_digits[2].xOffset = m_digits[1].xOffset + segmentWidth +
gapWidth;
m_digits[3].xOffset = m_digits[2].xOffset + segmentWidth +
CONFIG_TWM4NX_CLOCK_HSPACING;
// Display the initial time
redraw();
// Now we can show the completed window
return m_window->showWindow();
}
/**
* Start the application (perhaps in the minimized state).
*
* @return True if the application was successfully started.
*/
bool CClock::run(void)
{
// Some sanity checking
if (m_pid >= 0)
{
twmerr("ERROR: All ready running?\n");
return false;
}
// Get exclusive access to the global data structure
if (sem_wait(&GClockVars.exclSem) != 0)
{
// This might fail if a signal is received while we are waiting. Or,
// perhaps if the task is canceled.
twmerr("ERROR: Failed to get semaphore\n");
return false;
}
// Initialize the rest of parameter passing area for temporary use to
// start the new Clock task
sem_init(&GClockVars.waitSem, 0, 0);
sem_setprotocol(&GClockVars.waitSem, SEM_PRIO_NONE);
GClockVars.that = this;
GClockVars.success = false;
// Start the Clock task
sched_lock();
m_pid = task_create("Clock", CONFIG_TWM4NX_CLOCK_PRIO,
CONFIG_TWM4NX_CLOCK_STACKSIZE, clock,
(FAR char * const *)0);
// Did we successfully start the Clock task?
bool success = true;
if (m_pid < 0)
{
twmerr("ERROR: Failed to create the Clock task\n");
success = false;
}
else
{
// Wait for up to two seconds for the task to initialize
struct timespec abstime;
clock_gettime(CLOCK_REALTIME, &abstime);
abstime.tv_sec += 2;
int ret = sem_timedwait(&GClockVars.waitSem, &abstime);
sched_unlock();
if (ret < 0 || !GClockVars.success)
{
// sem_timedwait failed OR the Clock task reported a
// failure. Stop the application
twmerr("ERROR: Failed start the Clock task\n");
stop();
success = false;
}
}
sem_destroy(&GClockVars.waitSem);
sem_post(&GClockVars.exclSem);
return success;
}
/**
* This is the close window event handler. It will stop the Clock
* application thread.
*/
void CClock::stop(void)
{
// Delete the Clock task if it is still running (this could strand
// resources).
if (m_pid >= 0)
{
pid_t pid = m_pid;
m_pid = (pid_t)-1;
// Then delete the NSH task, possibly stranding resources
std::task_delete(pid);
}
}
/**
* This is the Clock task.
*/
int CClock::clock(int argc, char *argv[])
{
// Get the 'this' pointer
FAR CClock *This = GClockVars.that;
// Inform the parent thread that we successfully initialized
GClockVars.success = true;
sem_post(&GClockVars.waitSem);
// Loop forever. When the window is deleted, this task will be brutally
// terminated via task_delete()
for (; ; )
{
// Update the clock
This->update();
// Then sleep for a minute
sleep(60);
}
return EXIT_FAILURE; // Never get here
}
/**
* Handle Twm4Nx events. This overrides a method from CTwm4NXEvent
*
* @param eventmsg. The received NxWidget WINDOW event message.
* @return True if the message was properly handled. false is
* return on any failure.
*/
bool CClock::event(FAR struct SEventMsg *eventmsg)
{
bool success = true;
switch (eventmsg->eventID)
{
case EVENT_CLOCK_REDRAW: // Redraw event (doesn't happen)
redraw(); // Redraw the whole window
break;
case EVENT_CLOCK_CLOSE: // Window close event
stop(); // Stop the Clock thread
break;
default:
success = false;
break;
}
return success;
}
/**
* Update the Clock.
*/
void CClock::update(void)
{
// Get the current time.
FAR struct std::timespec ts;
int ret = std::clock_gettime(CLOCK_REALTIME, &ts);
if (ret < 0)
{
twmerr("ERROR: clock_gettime() failed\n");
return;
}
// Break out the time
//
// tm_hour - The number of hours past midnight, in the range 0 to 23.
// tm_min - The number of minutes after the hour, in the range 0 to 59.
struct std::tm tm;
if (std::gmtime_r(&ts.tv_sec, &tm) == (FAR struct std::tm *)0)
{
twmerr("ERROR: gmtime_r() failed\n");
return;
}
// Convert hours and minutes into SLCD segment codes
//
// Conversion of 24 hour clock (0-23) to twelve hour (1-12)
// 0 -> 12 6 -> 6 12 -> 12 18 -> 6
// 1 -> 1 7 -> 7 13 -> 1 19 -> 7
// 2 -> 2 8 -> 8 14 -> 2 20 -> 8
// 3 -> 3 9 -> 9 15 -> 3 21 -> 9
// 4 -> 4 10 -> 10 16 -> 4 22 -> 10
// 5 -> 5 11 -> 11 17 -> 5 23 -> 11
unsigned int hour = tm.tm_hour; /* Range 0-23 */
if (hour == 0)
{
hour = 12;
}
else if (hour > 12) /* Range 1-23 */
{
hour -= 12; /* Range 1-11 */
}
uint8_t codes[CLOCK_NDIGITS];
char ascii = (hour > 9) ? '1' : ' ';
(void)m_slcd->convert(ascii, codes[0]);
ascii = (hour % 10) + '0';
(void)m_slcd->convert(ascii, codes[1]);
ascii = (tm.tm_min / 10) + '0';
(void)m_slcd->convert(ascii, codes[2]);
ascii = (tm.tm_min % 10) + '0';
(void)m_slcd->convert(ascii, codes[3]);
struct nxgl_point_s pos;
pos.y = CONFIG_TWM4NX_CLOCK_VSPACING;
// Then show each segment LCD
// There might be a more efficient way to to this than to erase the entire
// SLCD on each update.
for (int i = 0; i < CLOCK_NDIGITS; i++)
{
if (m_digits[i].segments != codes[i])
{
pos.x = m_digits[i].xOffset;
m_slcd->erase(pos);
m_slcd->show(codes[i], pos);
m_digits[i].segments = codes[i];
}
}
}
/**
* Redraw the entire clock.
*/
void CClock::redraw(void)
{
// Get the size of the window
struct nxgl_size_s windowSize;
(void)m_window->getWindowSize(&windowSize);
// Create a bounding box
struct nxgl_rect_s windowRect;
windowRect.pt1.x = 0;
windowRect.pt1.y = 0;
windowRect.pt2.x = windowSize.w - 1;
windowRect.pt2.y = windowSize.h - 1;
// Fill the entire window with the clock background color
FAR NXWidgets::INxWindow *nxWindow = m_window->getNxWindow();
if (!nxWindow->fill(&windowRect, SLCD_BACKGROUND))
{
twmerr("ERROR: Failed to fill window");
return;
}
// Reset the saved codes to force a complete update
for (int i = 0; i < CLOCK_NDIGITS; i++)
{
m_digits[i].segments = 0;
}
// Then update the Clock window
update();
}
/////////////////////////////////////////////////////////////////////////////
// CClockFactory Method Implementations
/////////////////////////////////////////////////////////////////////////////
/**
* CClockFactory Initializer. Performs parts of the instance
* construction that may fail. In this implementation, it will
* initialize the NSH library and register an menu item in the
* Main Menu.
*/
bool CClockFactory::initialize(FAR CTwm4Nx *twm4nx)
{
// Save the session instance
m_twm4nx = twm4nx;
// Initialize the parameter passing area. Other fields are initialized
// by CClock thread-specific logic.
sem_init(&GClockVars.exclSem, 0, 1);
// Register an entry with the Main menu. When selected, this will
// Case the start
FAR CMainMenu *cmain = twm4nx->getMainMenu();
return cmain->addApplication(this);
}
/**
* Handle CClockFactory events. This overrides a method from
* CTwm4NXEvent
*
* @param eventmsg. The received NxWidget WINDOW event message.
* @return True if the message was properly handled. false is
* return on any failure.
*/
bool CClockFactory::event(FAR struct SEventMsg *eventmsg)
{
bool success = true;
switch (eventmsg->eventID)
{
case EVENT_CLOCK_START: // Main menu selection
startFunction(); // Create a new Clock instance
break;
default:
success = false;
break;
}
return success;
}
/**
* Create and start a new instance of CClock.
*/
bool CClockFactory::startFunction(void)
{
// Instantiate the Nxterm application, providing only the session session
// instance to the constructor
FAR CClock *clock = new CClock(m_twm4nx);
if (clock == (FAR CClock *)0)
{
twmerr("ERROR: Failed to instantiate CClock\n");
return false;
}
// Initialize the Clock application
if (!clock->initialize())
{
twmerr("ERROR: Failed to initialize CClock instance\n");
delete clock;
return false;
}
// Start the Clock application instance
if (!clock->run())
{
twmerr("ERROR: Failed to start the Clock application\n");
delete clock;
return false;
}
return true;
}

View File

@ -91,9 +91,13 @@
namespace Twm4Nx
{
/////////////////////////////////////////////////////////////////////////////
// Private Types
/////////////////////////////////////////////////////////////////////////////
/**
* This structure is used to pass start up parameters to the NxTerm task and to assure the
* the NxTerm is successfully started.
* This structure is used to pass start up parameters to the NxTerm task
* and to assure the the NxTerm is successfully started.
*/
struct SNxTerm
@ -113,11 +117,11 @@ namespace Twm4Nx
/////////////////////////////////////////////////////////////////////////////
/**
* This global data structure is used to pass start parameters to NxTerm task and to
* assure that the NxTerm is successfully started.
* This global data structure is used to pass start parameters to NxTerm
* task and to assure that the NxTerm is successfully started.
*/
static struct SNxTerm g_nxtermvars;
static struct SNxTerm GNxTermVars;
}
/////////////////////////////////////////////////////////////////////////////
@ -139,7 +143,7 @@ CNxTerm::CNxTerm(FAR CTwm4Nx *twm4nx)
m_twm4nx = twm4nx;
m_nxtermWindow = (FAR CWindow *)0;
// The NxTerm is not runing
// The NxTerm is not running
m_pid = (pid_t)-1;
m_NxTerm = (NXTERM)0;
@ -155,16 +159,6 @@ CNxTerm::~CNxTerm(void)
// running... that should never happen but we'll check anyway:
stop();
// The following is not necessary. The system will automatically
// delete the CWindow instance when the terminate button is pressed.
// We simply have to terminate the application behind the window
#if 0
// Delete the application window
delete m_nxtermWindow;
#endif
}
/**
@ -182,7 +176,7 @@ bool CNxTerm::initialize(void)
//
// Flags: WFLAGS_NO_MENU_BUTTON indicates that there is no menu associated
// with the NxTerm application window
// Null Icon mager means to use the system, common Icon Manager
// Null Icon manager means to use the system, common Icon Manager
NXWidgets::CNxString name("NuttShell");
@ -237,7 +231,7 @@ bool CNxTerm::run(void)
// Get exclusive access to the global data structure
if (sem_wait(&g_nxtermvars.exclSem) != 0)
if (sem_wait(&GNxTermVars.exclSem) != 0)
{
// This might fail if a signal is received while we are waiting.
@ -251,21 +245,21 @@ bool CNxTerm::run(void)
// Get the window handle from the widget control
g_nxtermvars.hwnd = control->getWindowHandle();
GNxTermVars.hwnd = control->getWindowHandle();
// Describe the NxTerm
g_nxtermvars.wndo.wcolor[0] = CONFIG_TWM4NX_NXTERM_WCOLOR;
g_nxtermvars.wndo.fcolor[0] = CONFIG_TWM4NX_NXTERM_FONTCOLOR;
g_nxtermvars.wndo.fontid = CONFIG_TWM4NX_NXTERM_FONTID;
GNxTermVars.wndo.wcolor[0] = CONFIG_TWM4NX_NXTERM_WCOLOR;
GNxTermVars.wndo.fcolor[0] = CONFIG_TWM4NX_NXTERM_FONTCOLOR;
GNxTermVars.wndo.fontid = CONFIG_TWM4NX_NXTERM_FONTID;
// Remember the device minor number (before it is incremented)
m_minor = g_nxtermvars.minor;
m_minor = GNxTermVars.minor;
// Get the size of the window
if (!m_nxtermWindow->getWindowSize(&g_nxtermvars.wndo.wsize))
if (!m_nxtermWindow->getWindowSize(&GNxTermVars.wndo.wsize))
{
twmerr("ERROR: getWindowSize() failed\n");
return false;
@ -273,9 +267,9 @@ bool CNxTerm::run(void)
// Start the NxTerm task
g_nxtermvars.console = (FAR void *)this;
g_nxtermvars.success = false;
g_nxtermvars.nxterm = 0;
GNxTermVars.console = (FAR void *)this;
GNxTermVars.success = false;
GNxTermVars.nxterm = 0;
sched_lock();
m_pid = task_create("NxTerm", CONFIG_TWM4NX_NXTERM_PRIO,
@ -298,20 +292,20 @@ bool CNxTerm::run(void)
clock_gettime(CLOCK_REALTIME, &abstime);
abstime.tv_sec += 2;
int ret = sem_timedwait(&g_nxtermvars.waitSem, &abstime);
int ret = sem_timedwait(&GNxTermVars.waitSem, &abstime);
sched_unlock();
if (ret == OK && g_nxtermvars.success)
if (ret == OK && GNxTermVars.success)
{
#ifdef CONFIG_NXTERM_NXKBDIN
// Re-direct NX keyboard input to the new NxTerm driver
DEBUGASSERT(g_nxtermvars.nxterm != 0);
m_nxtermWindow->redirectNxTerm(g_nxtermvars.nxterm);
DEBUGASSERT(GNxTermVars.nxterm != 0);
m_nxtermWindow->redirectNxTerm(GNxTermVars.nxterm);
#endif
// Save the handle to use in the stop method
m_NxTerm = g_nxtermvars.nxterm;
m_NxTerm = GNxTermVars.nxterm;
}
else
{
@ -324,13 +318,13 @@ bool CNxTerm::run(void)
}
}
sem_post(&g_nxtermvars.exclSem);
sem_post(&GNxTermVars.exclSem);
return success;
}
/**
* This is the close windoe event handler. It will stop the NxTerm
* application trhead.
* This is the close window event handler. It will stop the NxTerm
* application thread.
*/
void CNxTerm::stop(void)
@ -387,10 +381,10 @@ int CNxTerm::nxterm(int argc, char *argv[])
struct boardioc_nxterm_create_s nxcreate;
nxcreate.nxterm = (FAR void *)0;
nxcreate.hwnd = g_nxtermvars.hwnd;
nxcreate.wndo = g_nxtermvars.wndo;
nxcreate.hwnd = GNxTermVars.hwnd;
nxcreate.wndo = GNxTermVars.wndo;
nxcreate.type = BOARDIOC_XTERM_FRAMED;
nxcreate.minor = g_nxtermvars.minor;
nxcreate.minor = GNxTermVars.minor;
ret = boardctl(BOARDIOC_NXTERM, (uintptr_t)&nxcreate);
if (ret < 0)
@ -399,17 +393,17 @@ int CNxTerm::nxterm(int argc, char *argv[])
goto errout;
}
g_nxtermvars.nxterm = nxcreate.nxterm;
DEBUGASSERT(g_nxtermvars.nxterm != NULL);
GNxTermVars.nxterm = nxcreate.nxterm;
DEBUGASSERT(GNxTermVars.nxterm != NULL);
// Construct the driver name using this minor number
char devname[32];
snprintf(devname, 32, "/dev/nxterm%d", g_nxtermvars.minor);
snprintf(devname, 32, "/dev/nxterm%d", GNxTermVars.minor);
// Increment the minor number while it is protect by the semaphore
g_nxtermvars.minor++;
GNxTermVars.minor++;
// Open the NxTerm driver
@ -460,8 +454,8 @@ int CNxTerm::nxterm(int argc, char *argv[])
// Inform the parent thread that we successfully initialized
g_nxtermvars.success = true;
sem_post(&g_nxtermvars.waitSem);
GNxTermVars.success = true;
sem_post(&GNxTermVars.waitSem);
// Run the NSH console
@ -476,9 +470,9 @@ int CNxTerm::nxterm(int argc, char *argv[])
return EXIT_SUCCESS;
errout:
g_nxtermvars.nxterm = 0;
g_nxtermvars.success = false;
sem_post(&g_nxtermvars.waitSem);
GNxTermVars.nxterm = 0;
GNxTermVars.success = false;
sem_post(&GNxTermVars.waitSem);
return EXIT_FAILURE;
}
@ -612,8 +606,8 @@ bool CNxTermFactory::nshlibInitialize(void)
{
// Initialize the global data structure
sem_init(&g_nxtermvars.exclSem, 0, 1);
sem_init(&g_nxtermvars.waitSem, 0, 0);
sem_init(&GNxTermVars.exclSem, 0, 1);
sem_init(&GNxTermVars.waitSem, 0, 0);
// Initialize the NSH library

View File

@ -484,13 +484,13 @@ bool CResize::startResize(FAR struct SEventMsg *eventmsg)
if (!m_resizeWindow->getFramePosition(&m_lastPos))
{
gerr("ERROR: Failed to get frame position");
twmerr("ERROR: Failed to get frame position");
return false;
}
if (!m_resizeWindow->getFrameSize(&m_lastSize))
{
gerr("ERROR: Failed to get frame size");
twmerr("ERROR: Failed to get frame size");
return false;
}
@ -699,7 +699,7 @@ bool CResize::pauseResize(FAR struct SEventMsg *eventmsg)
if (!updateSize(eventmsg))
{
gerr("ERROR: Failed to update the window size\n");
twmerr("ERROR: Failed to update the window size\n");
}
// Set the new frame position and size if the size has changed
@ -746,13 +746,13 @@ bool CResize::resumeResize(FAR struct SEventMsg *eventmsg)
if (!m_resizeWindow->getFramePosition(&m_lastPos))
{
gerr("ERROR: Failed to get frame position");
twmerr("ERROR: Failed to get frame position");
return false;
}
if (!m_resizeWindow->getFrameSize(&m_lastSize))
{
gerr("ERROR: Failed to get frame size");
twmerr("ERROR: Failed to get frame size");
return false;
}

View File

@ -56,6 +56,7 @@
#include "graphics/twm4nx/apps/ccalibration.hxx"
#include "graphics/twm4nx/apps/cnxterm.hxx"
#include "graphics/twm4nx/apps/cclock.hxx"
/////////////////////////////////////////////////////////////////////////////
// Public Function Prototypes
@ -187,6 +188,16 @@ int twm4nx_main(int argc, char *argv[])
}
#endif
#ifdef CONFIG_TWM4NX_CLOCK
CClockFactory clockFactory;
success = clockFactory.initialize(twm4nx);
if (!success)
{
twmerr(" ERROR: Failed to initialize CClockFactory\n");
return EXIT_FAILURE;
}
#endif
#ifdef CONFIG_TWM4NX_NXTERM
CNxTermFactory nxtermFactory;
success = nxtermFactory.initialize(twm4nx);

View File

@ -40,8 +40,11 @@
// Included Files
/////////////////////////////////////////////////////////////////////////////
#include <fixedmath.h>
#include <nuttx/nx/nxglib.h>
#include "graphics/nxwidgets/nxconfig.hxx"
/////////////////////////////////////////////////////////////////////////////
// Pre-processor definitions
/////////////////////////////////////////////////////////////////////////////
@ -68,6 +71,12 @@
#define NBOTTOMRIGHT_TRAPEZOIDS 5
#define NBOTTOM_TRAPEZOIDS 2
// Clock colors: Light grey-green background, greenish-black foreground.
// Similar to what you would see on a classic LCD.
#define SLCD_BACKGROUND MKRGB(128, 140, 128)
#define SLCD_FOREGROUND MKRGB(0, 16, 0)
/////////////////////////////////////////////////////////////////////////////
// CSLcd Implementation Class
/////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,291 @@
/////////////////////////////////////////////////////////////////////////////
// apps/include/graphics/twm4nx/apps/cclock.hxx
// Retro LCD Clock
//
// Copyright (C) 2019 Gregory Nutt. All rights reserved.
// Author: Gregory Nutt <gnutt@nuttx.org>
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// 3. Neither the name NuttX nor the names of its contributors may be
// used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef __APPS_INCLUDE_GRAPHICS_TWM4NX_APPS_CCLOCK_HXX
#define __APPS_INCLUDE_GRAPHICS_TWM4NX_APPS_CCLOCK_HXX
/////////////////////////////////////////////////////////////////////////////
// Included Files
/////////////////////////////////////////////////////////////////////////////
#include <nuttx/config.h>
#include <sys/types.h>
#include <nuttx/nx/nxtk.h>
#include "graphics/twm4nx/ctwm4nx.hxx"
#include "graphics/twm4nx/ctwm4nxevent.hxx"
#include "graphics/twm4nx/twm4nx_events.hxx"
#include "graphics/twm4nx/iapplication.hxx"
/////////////////////////////////////////////////////////////////////////////
// Pre-processor Definitions
/////////////////////////////////////////////////////////////////////////////
// CClock application events
// Window Events
#define EVENT_CLOCK_REDRAW (EVENT_RECIPIENT_APP | 0x0000) /* Not necessary */
#define EVENT_CLOCK_RESIZE EVENT_SYSTEM_NOP
#define EVENT_CLOCK_XYINPUT EVENT_SYSTEM_NOP
#define EVENT_CLOCK_KBDINPUT EVENT_SYSTEM_NOP
#define EVENT_CLOCK_DELETE EVENT_WINDOW_DELETE
// Button Events
#define EVENT_CLOCK_CLOSE (EVENT_RECIPIENT_APP | 0x0001)
// Menu Events
#define EVENT_CLOCK_START (EVENT_RECIPIENT_APP | 0x0002)
// Number of digits in clock display
#define CLOCK_NDIGITS 4
/////////////////////////////////////////////////////////////////////////////
// Implementation Classes
/////////////////////////////////////////////////////////////////////////////
namespace SLcd
{
class CSLcd; // Forward reference
}
namespace Twm4Nx
{
/**
* This structure describes the state of one clock digit
*/
struct SClockDigit
{
nxgl_coord_t xOffset; /**< X offset from left side of the window */
uint8_t segments; /**< LCD segment code of number */
};
/**
* This class implements the Clock application.
*/
class CClock : public CTwm4NxEvent
{
private:
FAR CTwm4Nx *m_twm4nx; /**< Reference to the Twm4Nx session instance */
FAR CWindow *m_window; /**< Reference to the Clock application window */
FAR SLcd::CSLcd *m_slcd; /**< Reference to the segment LCD helper */
pid_t m_pid; /**< Task ID of the Clock thread */
// The current clock state, digit-by-digit:
struct SClockDigit m_digits[CLOCK_NDIGITS];
/**
* This is the Clock task.
*/
static int clock(int argc, char *argv[]);
/**
* Handle Twm4Nx events. This overrides a method from CTwm4NXEvent
*
* @param eventmsg. The received NxWidget WINDOW event message.
* @return True if the message was properly handled. false is
* return on any failure.
*/
bool event(FAR struct SEventMsg *eventmsg);
/**
* Update the Clock.
*/
void update(void);
/**
* Redraw the entire clock.
*/
void redraw(void);
/**
* This is the close window event handler. It will stop the Clock
* application thread.
*/
void stop(void);
public:
/**
* CClock constructor
*
* @param twm4nx. The Twm4Nx session instance
*/
CClock(FAR CTwm4Nx *twm4nx);
/**
* CClock destructor
*/
~CClock(void);
/**
* CClock initializers. Perform miscellaneous post-construction
* initialization that may fail (and hence is not appropriate to be
* done in the constructor)
*
* @return True if the Clock application was successfully initialized.
*/
bool initialize(void);
/**
* Start the Clock.
*
* @return True if the Clock application was successfully started.
*/
bool run(void);
};
class CClockFactory : public IApplication,
public IApplicationFactory,
public CTwm4NxEvent
{
private:
FAR CTwm4Nx *m_twm4nx; /**< Twm4Nx session instance */
/**
* Handle CClockFactory events. This overrides a method from
* CTwm4NXEvent
*
* @param eventmsg. The received NxWidget WINDOW event message.
* @return True if the message was properly handled. false is
* return on any failure.
*/
bool event(FAR struct SEventMsg *eventmsg);
/**
* Create and start a new instance of an CClock.
*/
bool startFunction(void);
/**
* Return the Main Menu item string. This overrides the method from
* IApplication
*
* @param name The name of the application.
*/
inline NXWidgets::CNxString getName(void)
{
return NXWidgets::CNxString("Clock");
}
/**
* There is no sub-menu for this Main Menu item. This overrides
* the method from IApplication.
*
* @return This implementation will always return a null value.
*/
inline FAR CMenus *getSubMenu(void)
{
return (FAR CMenus *)0;
}
/**
* There is no custom event handler. We use the common event handler.
*
* @return. null is always returned in this implementation.
*/
inline FAR CTwm4NxEvent *getEventHandler(void)
{
return (FAR CTwm4NxEvent *)this;
}
/**
* Return the Twm4Nx event that will be generated when the Main Menu
* item is selected.
*
* @return. This function always returns EVENT_SYSTEM_NOP.
*/
inline uint16_t getEvent(void)
{
return EVENT_CLOCK_START;
}
public:
/**
* CClockFactory Constructor
*
* @param twm4nx. The Twm4Nx session instance
*/
inline CClockFactory(void)
{
m_twm4nx = (FAR CTwm4Nx *)0;
}
/**
* CClockFactory Destructor
*/
inline ~CClockFactory(void)
{
// REVISIT: Would need to remove Main Menu item
}
/**
* CClockFactory Initializer. Performs parts of the instance
* construction that may fail. In this implemenation, it will
* initialize the NSH library and register an menu item in the
* Main Menu.
*/
bool initialize(FAR CTwm4Nx *twm4nx);
};
}
#endif // __APPS_INCLUDE_GRAPHICS_TWM4NX_APPS_CCLOCK_HXX

View File

@ -0,0 +1,135 @@
/////////////////////////////////////////////////////////////////////////////
// apps/include/graphics/twm4nx/apps/clock_config.hxx
// Clock configuration settings
//
// Copyright (C) 2019 Gregory Nutt. All rights reserved.
// Author: Gregory Nutt <gnutt@nuttx.org>
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// 3. Neither the name NuttX nor the names of its contributors may be
// used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef __APPS_INCLUDE_GRAPHICS_TWM4NX_APPS_CLOCK_CONFIG_HXX
#define __APPS_INCLUDE_GRAPHICS_TWM4NX_APPS_CLOCK_CONFIG_HXX
/////////////////////////////////////////////////////////////////////////////
// Included Files
/////////////////////////////////////////////////////////////////////////////
#include <nuttx/config.h>
#include <debug.h>
#include "graphics/nxglyphs.hxx"
#include "graphics/nxwidgets/crlepalettebitmap.hxx"
#include "graphics/twm4nx/twm4nx_config.hxx"
#ifdef CONFIG_TWM4NX_CLOCK
/////////////////////////////////////////////////////////////////////////////
// Pre-Processor Definitions
/////////////////////////////////////////////////////////////////////////////
// General Configuration ////////////////////////////////////////////////////
/**
* Required settings:
*
* CONFIG_HAVE_CXX : C++ support is required
* CONFIG_NX : NX must enabled
* CONFIG_GRAPHICS_SLCD : For segment LCD emulation
*/
#ifndef CONFIG_HAVE_CXX
# error C++ support is required (CONFIG_HAVE_CXX)
#endif
#ifndef CONFIG_NX
# error NX support is required (CONFIG_NX)
#endif
#ifndef CONFIG_GRAPHICS_SLCD
# warning Segment LCD emulation is required (CONFIG_GRAPHICS_SLCD)
#endif
// Clock Window /////////////////////////////////////////////////////////////
/**
* Clock Window Configuration
*
* CONFIG_TWM4NX_CLOCK_PRIO - Priority of the Clock task. Default:
* SCHED_PRIORITY_DEFAULT. NOTE: This priority should be less than
* CONFIG_NXSTART_SERVERPRIO or else there may be data overrun errors.
* Such errors would most likely appear as duplicated rows of data on the
* display.
* CONFIG_TWM4NX_CLOCK_STACKSIZE - The stack size to use when starting the
* Clock task. Default: 1024 bytes.
* CONFIG_TWM4NX_CLOCK_ICON - The glyph to use as the Clock icon
* CONFIG_TWM4NX_CLOCK_HEIGHT - The fixed height of the clock
*/
// Tasking
#ifndef CONFIG_TWM4NX_CLOCK_PRIO
# define CONFIG_TWM4NX_CLOCK_PRIO SCHED_PRIORITY_DEFAULT
#endif
#if CONFIG_NXSTART_SERVERPRIO <= CONFIG_TWM4NX_CLOCK_PRIO
# warning "CONFIG_NXSTART_SERVERPRIO <= CONFIG_TWM4NX_CLOCK_PRIO"
# warning" -- This can result in data overrun errors"
#endif
#ifndef CONFIG_TWM4NX_CLOCK_STACKSIZE
# define CONFIG_TWM4NX_CLOCK_STACKSIZE 1024
#endif
// Colors -- Controlled by the CSLcd configuration
// The Clock window glyph
#ifndef CONFIG_TWM4NX_CLOCK_ICON
# define CONFIG_TWM4NX_CLOCK_ICON NXWidgets::g_lcdClockBitmap
#endif
// The fixed clock window height
#ifndef CONFIG_TWM4NX_CLOCK_HEIGHT
# define CONFIG_TWM4NX_CLOCK_HEIGHT 64
#endif
// Spacing
#ifndef CONFIG_TWM4NX_CLOCK_HSPACING
# define CONFIG_TWM4NX_CLOCK_HSPACING 2
#endif
#ifndef CONFIG_TWM4NX_CLOCK_VSPACING
# define CONFIG_TWM4NX_CLOCK_VSPACING 2
#endif
#endif // CONFIG_TWM4NX_CLOCK
#endif // __APPS_INCLUDE_GRAPHICS_TWM4NX_APPS_CLOCK_CONFIG_HXX

View File

@ -86,8 +86,8 @@ namespace Twm4Nx
class CNxTerm : public CTwm4NxEvent
{
private:
CTwm4Nx *m_twm4nx; /**< Reference to the Twm4Nx session instance */
CWindow *m_nxtermWindow; /**< Reference to the NxTerm application window */
FAR CTwm4Nx *m_twm4nx; /**< Reference to the Twm4Nx session instance */
FAR CWindow *m_nxtermWindow; /**< Reference to the NxTerm application window */
NXTERM m_NxTerm; /**< NxTerm handle */
pid_t m_pid; /**< Task ID of the NxTerm thread */
int m_minor; /**< Terminal device minor number */
@ -123,7 +123,7 @@ namespace Twm4Nx
/**
* This is the close window event handler. It will stop the NxTerm
* application trhead.
* application thread.
*/
void stop(void);
@ -224,7 +224,7 @@ namespace Twm4Nx
/**
* There is no custom event handler. We use the common event handler.
*
* @return. null is always returned in this impementation.
* @return. null is always returned in this implementation.
*/
inline FAR CTwm4NxEvent *getEventHandler(void)

View File

@ -56,6 +56,7 @@
#include <nuttx/nx/nxglib.h>
#include <nuttx/nx/nxterm.h>
#include "graphics/nxwidgets/cnxtkwindow.hxx"
#include "graphics/nxwidgets/cnxtoolbar.hxx"
#include "graphics/nxwidgets/cwidgeteventhandler.hxx"
#include "graphics/nxwidgets/cwidgeteventargs.hxx"
@ -508,6 +509,18 @@ namespace Twm4Nx
return m_nxWin->getWidgetControl();
}
/**
* Get the raw window interface. This is sometimes needed for connecting
* the window to external NXWidgets applications.
*
* @return The raw window interface (NXWidgets::INxWindow)
*/
inline NXWidgets::INxWindow *getNxWindow(void)
{
return static_cast<NXWidgets::INxWindow *>(m_nxWin);
}
#ifdef CONFIG_NXTERM_NXKBDIN
/**
* By default, NX forwards keyboard input to the various widgets residing