From 925415fbda596e6da11429a72f57f2574ce50844 Mon Sep 17 00:00:00 2001 From: patacongo Date: Sat, 17 Nov 2012 13:50:02 +0000 Subject: Patches 7-9 from Petteri Aimonen git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5365 42af7a65-404d-4744-a932-0658087f49c3 --- NxWidgets/ChangeLog.txt | 6 + NxWidgets/libnxwidgets/include/cimage.hxx | 16 +- NxWidgets/libnxwidgets/include/cnxtimer.hxx | 55 +++---- NxWidgets/libnxwidgets/src/cnxtimer.cxx | 220 +++------------------------- NxWidgets/libnxwidgets/src/cnxtkwindow.cxx | 14 +- NxWidgets/nxwm/src/ctaskbar.cxx | 35 ++--- 6 files changed, 84 insertions(+), 262 deletions(-) (limited to 'NxWidgets') diff --git a/NxWidgets/ChangeLog.txt b/NxWidgets/ChangeLog.txt index ece08e4fd..65022ea15 100644 --- a/NxWidgets/ChangeLog.txt +++ b/NxWidgets/ChangeLog.txt @@ -206,4 +206,10 @@ Contributed by Petteri, Aimonen. * NxWM::CStartWindow: Fix mq_receive error handling with signal is recieved. From Petteri Aimonen. +* NxWidgets:CNxTimer: Replace the original (apparently non-functional) signal- + based solution with a work queue-based solution. This raises some isses about + using the internal work queues from user space. I have decided to implemented + user-space work queues (someday) in order to accomplish that functionaliy. + Submitted by Petteri Aimonen. + solutions diff --git a/NxWidgets/libnxwidgets/include/cimage.hxx b/NxWidgets/libnxwidgets/include/cimage.hxx index 0fe275624..6093c5f33 100644 --- a/NxWidgets/libnxwidgets/include/cimage.hxx +++ b/NxWidgets/libnxwidgets/include/cimage.hxx @@ -73,7 +73,7 @@ /**************************************************************************** * Included Files ****************************************************************************/ - + #include #include @@ -86,11 +86,11 @@ /**************************************************************************** * Pre-Processor Definitions ****************************************************************************/ - + /**************************************************************************** * Implementation Classes ****************************************************************************/ - + #if defined(__cplusplus) namespace NXWidgets @@ -120,7 +120,7 @@ namespace NXWidgets * @param port The CGraphicsPort to draw to. * @see redraw() */ - + virtual void drawContents(CGraphicsPort *port); /** @@ -150,7 +150,7 @@ namespace NXWidgets */ virtual void onPreRelease(nxgl_coord_t x, nxgl_coord_t y); - + /** * Redraws the image. * @@ -201,6 +201,12 @@ namespace NXWidgets virtual inline ~CImage() { } + /** + * Get pointer to the bitmap that this image contains. + */ + + inline FAR IBitmap *getBitmap() const { return m_bitmap; } + /** * Insert the dimensions that this widget wants to have into the rect * passed in as a parameter. All coordinates are relative to the diff --git a/NxWidgets/libnxwidgets/include/cnxtimer.hxx b/NxWidgets/libnxwidgets/include/cnxtimer.hxx index be6038dac..d4715b378 100644 --- a/NxWidgets/libnxwidgets/include/cnxtimer.hxx +++ b/NxWidgets/libnxwidgets/include/cnxtimer.hxx @@ -80,6 +80,8 @@ #include #include +#include + #include "cnxwidget.hxx" /**************************************************************************** @@ -108,42 +110,18 @@ namespace NXWidgets class CNxTimer : public CNxWidget { protected: - FAR timer_t m_timerid; /**< POSIX timer */ + struct work_s m_work; /**< Work queue entry */ uint32_t m_timeout; /**< The timeout value in milliseconds */ bool m_isRunning; /**< Indicates whether or not the timer is running */ bool m_isRepeater; /**< Indicates whether or not the timer repeats */ /** - * The SIGALM signal handler that will be called when the timer goes off - * - * @param signo The signal number call caused the handler to run (SIGALM) - */ - - static void signalHandler(int signo); - - /** - * Handle an expired timer - */ - - void handleTimerExpiration(void); - - /** - * Convert a timespec to milliseconds + * Static function called from work queue when the timeout expires. * - * @param tp The pointer to the timespec to convert - * @return The corresponding time in milliseconds + * @param arg Pointer to the CNxTimer instance. */ - uint32_t timespecToMilliseconds(FAR const struct timespec *tp); - - /** - * Convert milliseconds to a timespec - * - * @param milliseconds The milliseconds to be converted - * @param tp The pointer to the location to store the converted timespec - */ - - void millisecondsToTimespec(uint32_t milliseconds, FAR struct timespec *tp); + static void workQueueCallback(FAR void *arg); /** * Copy constructor is protected to prevent usage. @@ -171,15 +149,6 @@ namespace NXWidgets ~CNxTimer(void); - /** - * Return the time remaining on this timer. - * - * @return The number of milliseconds that this timer runs before - * firing an event. Zero is returned if the timer is not running. - */ - - const uint32_t getTimeout(void); - /** * Resets the (running) timer to its initial timeout value. This * call does nothing if the timer is not running. @@ -212,6 +181,18 @@ namespace NXWidgets { m_timeout = timeout; } + + /** + * Return the timeout of this timer. + * + * @return The number of milliseconds that this timer will run before + * firing an event. + */ + + inline uint32_t getTimeout(void) const + { + return m_timeout; + } }; } diff --git a/NxWidgets/libnxwidgets/src/cnxtimer.cxx b/NxWidgets/libnxwidgets/src/cnxtimer.cxx index e351d2357..d663df036 100644 --- a/NxWidgets/libnxwidgets/src/cnxtimer.cxx +++ b/NxWidgets/libnxwidgets/src/cnxtimer.cxx @@ -70,18 +70,20 @@ /**************************************************************************** * Included Files ****************************************************************************/ - + #include #include #include #include #include -#include #include +#include + +#include +#include #include "cnxtimer.hxx" -#include "singletons.hxx" /**************************************************************************** * Pre-Processor Definitions @@ -116,44 +118,9 @@ CNxTimer::CNxTimer(CWidgetControl *pWidgetControl, uint32_t timeout, bool repeat m_isRepeater = repeat; m_isRunning = false; - // Create a POSIX timer (We can't do anything about failures here) - - int ret = timer_create(CLOCK_REALTIME, (FAR struct sigevent *)NULL, &m_timerid); - if (ret < 0) - { - gdbg("timer_create() failed\n"); - return; - } - - // If we are the first timer created in the whole system, then create - // the timer list and attach the SIGALRM timer handler. - - if (!g_nxTimers) - { - if (!g_nxTimers) - { - gdbg("Failed to create the timer list\n"); - return; - } - - // Attach the SIGALM signal handler (no harm if this is done multiple times) - - struct sigaction sigact; - sigact.sa_handler = signalHandler; - sigact.sa_flags = 0; - sigemptyset(&sigact.sa_mask); + // Reset the work structure - ret = sigaction(SIGALRM, &sigact, (FAR struct sigaction *)NULL); - if (ret < 0) - { - gdbg("sigaction() failed\n"); - return; - } - } - - // Add ourself onto the array of timers -#warning "Need to disable SIGALRM here" - g_nxTimers->push_back(this); + memset(&m_work, 0, sizeof(m_work)); } /** @@ -162,54 +129,6 @@ CNxTimer::CNxTimer(CWidgetControl *pWidgetControl, uint32_t timeout, bool repeat CNxTimer::~CNxTimer(void) { - // Locate ourself in the list of timers and remove ourselves - -#warning "Need to disable SIGALRM here" - for (int i = 0; i < g_nxTimers->size(); i++) - { - CNxTimer *timer = g_nxTimers->at(i); - if (timer == this) - { - g_nxTimers->erase(i); - break; - } - } - - // Destroy the timer - - (void)timer_delete(m_timerid); -} - -/** - * Return the timeout of this timer. - * - * @return The number of milliseconds that this timer will run before firing - * an event. - */ - -const uint32_t CNxTimer::getTimeout(void) -{ - // If the timer is not running, then just return the timeout value - - if (!m_isRunning) - { - return m_timeout; - } - else - { - // Get the time remaining on the POSIX timer. Of course, there - // are race conditions here.. the timer could expire at anytime - - struct itimerspec remaining; - int ret = timer_gettime(m_timerid, &remaining); - if (ret < 0) - { - gdbg("timer_gettime() failed\n"); - return 0; - } - - return timespecToMilliseconds(&remaining.it_value); - } } /** @@ -222,11 +141,7 @@ void CNxTimer::reset(void) if (m_isRunning) { - // If the specified timer was already armed when timer_settime() is - // called, this call will reset the time until next expiration to the - // value specified. - - m_isRunning = false; + stop(); start(); } } @@ -241,24 +156,14 @@ void CNxTimer::start(void) if (!m_isRunning) { - // If the specified timer was already armed when timer_settime() is - // called, this call will reset the time until next expiration to the - // value specified. - - struct itimerspec timerspec; - millisecondsToTimespec(m_timeout, &timerspec.it_value); - timerspec.it_interval.tv_sec = 0; - timerspec.it_interval.tv_nsec = 0; - - int ret = timer_settime(m_timerid, 0, &timerspec, - (FAR struct itimerspec *)NULL); + uint32_t ticks = m_timeout / MSEC_PER_TICK; + int ret = work_queue(USRWORK, &m_work, workQueueCallback, this, ticks); + if (ret < 0) { - gdbg("timer_settime() failed\n"); + gdbg("work_queue failed: %d\n", ret); } - // The timer is now running - m_isRunning = true; } } @@ -271,112 +176,33 @@ void CNxTimer::stop(void) { if (m_isRunning) { - // If the it_value member of value is zero, the timer will be disarmed. - // The effect of disarming or resetting a timer with pending expiration - // notifications is unspecified. + int ret = work_cancel(USRWORK, &m_work); - struct itimerspec nullTime; - memset(&nullTime, 0, sizeof(struct itimerspec)); - - int ret = timer_settime(m_timerid, 0, &nullTime, - (FAR struct itimerspec *)NULL); if (ret < 0) { - gdbg("timer_settime failed\n"); + gdbg("work_cancel failed: %d\n", ret); } - // The time is no longer running - m_isRunning = false; } } -/** - * The SIGALM signal handler that will be called when the timer goes off - * - * @param signo The signal number call caused the handler to run (SIGALM) - */ - -void CNxTimer::signalHandler(int signo) +void CNxTimer::workQueueCallback(FAR void *arg) { - // Call handlerTimerExpiration on every timer instance + CNxTimer* This = (CNxTimer*)arg; - for (int i = 0; i < g_nxTimers->size(); i++) - { - CNxTimer *timer = g_nxTimers->at(i); - timer->handleTimerExpiration(); - } -} + This->m_isRunning = false; -/** - * Handle an expired timer - */ - -void CNxTimer::handleTimerExpiration(void) -{ - // Do we think our timer is running? + // Raise the action event. - if (m_isRunning) - { - // Is it running? It the timer is not running, it will return an - // it_value of zero. + This->m_widgetEventHandlers->raiseActionEvent(); - struct itimerspec status; - int ret = timer_gettime(m_timerid, &status); - if (ret < 0) - { - gdbg("timer_gettime() failed\n"); - return; - } + // Restart the timer if this is a repeating timer - // it_value == 0 means that timer is not running - - if (status.it_value.tv_sec == 0 && status.it_value.tv_nsec == 0) - { - // It has expired - - m_isRunning = false; - - // Raise the action event. Hmmm.. are there any issues with - // doing this from a signal handler? We'll find out - - m_widgetEventHandlers->raiseActionEvent(); - - // Restart the timer if this is a repeating timer - - if (m_isRepeater) - { - start(); - } - } + if (This->m_isRepeater) + { + This->start(); } } - -/** - * Convert a timespec to milliseconds - * - * @param tp The pointer to the timespec to convert - * @return The corresponding time in milliseconds - */ - -uint32_t CNxTimer::timespecToMilliseconds(FAR const struct timespec *tp) -{ - return (uint32_t)tp->tv_sec * 1000 + (uint32_t)tp->tv_nsec / 10000000; -} - -/** - * Convert milliseconds to a timespec - * - * @param milliseconds The milliseconds to be converted - * @param tp The pointer to the location to store the converted timespec - */ - - void CNxTimer::millisecondsToTimespec(uint32_t milliseconds, - FAR struct timespec *tp) - { - tp->tv_sec = milliseconds / 1000; - uint32_t remainder = milliseconds - (uint32_t)tp->tv_sec * 1000; - tp->tv_nsec = remainder * 1000000; - } diff --git a/NxWidgets/libnxwidgets/src/cnxtkwindow.cxx b/NxWidgets/libnxwidgets/src/cnxtkwindow.cxx index 05241817c..57ca5eb2b 100644 --- a/NxWidgets/libnxwidgets/src/cnxtkwindow.cxx +++ b/NxWidgets/libnxwidgets/src/cnxtkwindow.cxx @@ -65,7 +65,7 @@ using namespace NXWidgets; * @param hNxServer Handle to the NX server. * @param widgetControl Controlling widget for this window. */ - + CNxTkWindow::CNxTkWindow(NXHANDLE hNxServer, CWidgetControl *widgetControl) : CCallback(widgetControl) { @@ -101,6 +101,8 @@ CNxTkWindow::~CNxTkWindow(void) // constructed-us. (void)nxtk_closewindow(m_hNxTkWindow); + + delete m_widgetControl; } /** @@ -137,7 +139,7 @@ CWidgetControl *CNxTkWindow::getWidgetControl(void) const /** * Open a toolbar on the framed window. This method both instantiates - * the toolbar object AND calls the INxWindow::open() method to + * the toolbar object AND calls the INxWindow::open() method to * create the toolbar. The toolbar is ready for use upon return. * * @param height. The height in rows of the tool bar @@ -184,7 +186,7 @@ CNxToolbar *CNxTkWindow::openToolbar(nxgl_coord_t height, CWidgetControl *widget widgetControl->setWidgetStyle(&style); // And create the toolbar - + m_toolbar = new CNxToolbar(this, m_hNxTkWindow, widgetControl, height); if (!m_toolbar) @@ -218,7 +220,7 @@ CNxToolbar *CNxTkWindow::openToolbar(nxgl_coord_t height, CWidgetControl *widget // Provide parent widget control information to new widget control instance. // This information is reported by an NX callback for "normal" windows. But - // the toolbar widget control does not get NX callbacks and has to get the + // the toolbar widget control does not get NX callbacks and has to get the // window size through the setWindowBounds method. // Disable preemption so that we can be assured that all of the following @@ -309,7 +311,7 @@ bool CNxTkWindow::getSize(FAR struct nxgl_size_s *size) * @param pos The new position of the window. * @return True on success, false on any failure. */ - + bool CNxTkWindow::setPosition(FAR const struct nxgl_point_s *pos) { // Set the window size and position @@ -323,7 +325,7 @@ bool CNxTkWindow::setPosition(FAR const struct nxgl_point_s *pos) * @param size The new size of the window. * @return True on success, false on any failure. */ - + bool CNxTkWindow::setSize(FAR const struct nxgl_size_s *size) { // Set the window size diff --git a/NxWidgets/nxwm/src/ctaskbar.cxx b/NxWidgets/nxwm/src/ctaskbar.cxx index 23d2d23b5..031edbf3a 100644 --- a/NxWidgets/nxwm/src/ctaskbar.cxx +++ b/NxWidgets/nxwm/src/ctaskbar.cxx @@ -90,7 +90,7 @@ CTaskbar::~CTaskbar(void) /** * Connect to the server */ - + bool CTaskbar::connect(void) { // Connect to the server @@ -116,7 +116,7 @@ bool CTaskbar::connect(void) void CTaskbar::disconnect(void) { - // Stop all applications and remove them from the task bar. Clearly, there + // Stop all applications and remove them from the task bar. Clearly, there // are some ordering issues here... On an orderly system shutdown, disconnection // should really occur priority to deleting instances @@ -279,7 +279,7 @@ bool CTaskbar::startWindowManager(void) for (int i = 0; i < m_slots.size(); ) { - IApplication *app = m_slots.at(i).app; + IApplication *app = m_slots.at(i).app; gvdbg("Starting app[%d]\n", i); if (!app->run()) @@ -294,7 +294,7 @@ bool CTaskbar::startWindowManager(void) // 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; } @@ -631,7 +631,7 @@ bool CTaskbar::stopApplication(IApplication *app) app->setTopApplication(false); m_topApp = (IApplication *)0; } - + // Hide the application window. That will move the application to the // bottom of the hiearachy. @@ -655,6 +655,7 @@ bool CTaskbar::stopApplication(IApplication *app) // Yes.. found it. Delete the icon image and remove the entry // from the list of applications + delete m_slots.at(i).image->getBitmap(); delete m_slots.at(i).image; m_slots.erase(i); break; @@ -743,7 +744,7 @@ void CTaskbar::clickIcon(int index, bool click) #endif /** - * Create a raw window. + * Create a raw window. * * 1) Create a dumb CWigetControl instance (see note below) * 2) Pass the dumb CWidgetControl instance to the window constructor @@ -796,7 +797,7 @@ NXWidgets::CNxWindow *CTaskbar::openRawWindow(void) * * @return A partially initialized application window instance. */ - + NXWidgets::CNxTkWindow *CTaskbar::openFramedWindow(void) { // Create the widget control (with the window messenger) using the default style @@ -892,13 +893,13 @@ void CTaskbar::setApplicationGeometry(NXWidgets::INxWindow *window, bool fullscr * @param pPos The new position of the window. * @return True on success, false on failure. */ - + window->setPosition(&pos); window->setSize(&size); } /** - * Create the task bar window. + * Create the task bar window. * * @return true on success */ @@ -962,7 +963,7 @@ bool CTaskbar::createTaskbarWindow(void) } /** - * Create the background window. + * Create the background window. * * @return true on success */ @@ -984,7 +985,7 @@ bool CTaskbar::createBackgroundWindow(void) } /** - * Create the background image. + * Create the background image. * * @return true on success */ @@ -1056,7 +1057,7 @@ bool CTaskbar::createBackgroundImage(void) m_backImage->setBorderless(true); m_backImage->setRaisesEvents(false); #endif - + return true; } @@ -1132,9 +1133,9 @@ bool CTaskbar::redrawTaskbarWindow(void) image->setRaisesEvents(false); // Highlight the icon for the top-most window - + image->highlight(m_slots.at(i).app == m_topApp); - + // Get the size of the icon image NXWidgets::CRect rect; @@ -1295,7 +1296,7 @@ bool CTaskbar::redrawBackgroundWindow(void) // Raise the background window to the top of the hierarchy m_background->raise(); - + // Fill the entire window with the background color port->drawFilledRect(0, 0, windowSize.w, windowSize.h, @@ -1314,7 +1315,7 @@ bool CTaskbar::redrawBackgroundWindow(void) m_backImage->enableDrawing(); m_backImage->redraw(); } - + return true; } @@ -1344,7 +1345,7 @@ bool CTaskbar::redrawApplicationWindow(IApplication *app) // Redraw taskbar redrawTaskbarWindow(); - + // Every application provides a method to obtain its application window IApplicationWindow *appWindow = app->getWindow(); -- cgit v1.2.3