Squashed commit of the following:

apps/graphics/NxWidgets:  Fix a possible deadlock condition when waiting for window geometry data that will never come.  Fixed by re-requesting geometry data if we don't already have it.

    apps/graphics/twm4nx:  Add some debug output.

    apps/graphics/twm4nx:  Rethink how background events are handled.

    apps/grephics/twm4nx:  Expermimental organization to capture background events.
This commit is contained in:
Gregory Nutt 2019-05-01 11:11:43 -06:00
parent 8f5944c4a8
commit f730108adb
18 changed files with 427 additions and 327 deletions

View File

@ -160,21 +160,21 @@ void CCallback::synchronize(NXWINDOW hwnd, enum WindowType windowType)
* ReDraw Callback. The redraw action is handled by CWidgetControl:redrawEvent.
*
* @param hwnd Handle to a specific NX window.
* @param rect The rectangle that needs to be re-drawn (in window
* @param nxRect The rectangle that needs to be re-drawn (in window
* relative coordinates).
* @param bMore true: More re-draw requests will follow.
* @param more true: More re-draw requests will follow.
* @param arg User provided argument (see nx_openwindow, nx_requestbg,
* nxtk_openwindow, or nxtk_opentoolbar).
*/
void CCallback::redraw(NXHANDLE hwnd,
FAR const struct nxgl_rect_s *rect,
bool bMore, FAR void *arg)
FAR const struct nxgl_rect_s *nxRect,
bool more, FAR void *arg)
{
ginfo("hwnd=%p rect={(%d,%d),(%d,%d)} bMore=%s\n",
ginfo("hwnd=%p nxRect={(%d,%d),(%d,%d)} more=%s\n",
hwnd,
rect->pt1.x, rect->pt1.y, rect->pt2.x, rect->pt2.y,
bMore ? "true" : "false");
nxRect->pt1.x, nxRect->pt1.y, nxRect->pt2.x, nxRect->pt2.y,
more ? "true" : "false");
// The argument must be the CCallback instance
@ -182,7 +182,7 @@ void CCallback::redraw(NXHANDLE hwnd,
// Just forward the callback to the CWidgetControl::redrawEvent method
This->m_widgetControl->redrawEvent(rect, bMore);
This->m_widgetControl->redrawEvent(nxRect, more);
}
/**

View File

@ -427,16 +427,13 @@ void CWidgetControl::geometryEvent(NXHANDLE hWindow,
* in particular, will occur when the a portion of the window that was
* previously obscured is now exposed.
*
* @param rect The region in the window that must be redrawn.
* @param nxRect The region in the window that must be redrawn.
* @param more True means that more re-draw requests will follow
*/
void CWidgetControl::redrawEvent(FAR const struct nxgl_rect_s *nxRect, bool more)
{
// REVISIT. This is not not yet used and not fully implemented.
CRect rect;
rect.setNxRect(nxRect);
m_eventHandlers.raiseRedrawEvent();
m_eventHandlers.raiseRedrawEvent(nxRect, more);
}
/**
@ -908,7 +905,7 @@ bool CWidgetControl::pollCursorControlEvents(void)
void CWidgetControl::takeGeoSem(void)
{
// Take the geometry semaphore. Retry is an error occurs (only if
// Take the geometry semaphore. Retry if an error occurs (only if
// the error is due to a signal interruption).
int ret;
@ -919,6 +916,41 @@ void CWidgetControl::takeGeoSem(void)
while (ret < 0 && errno == EINTR);
}
/**
* Check if geomtry data is available. If not, [re-]request the
* geomtry data and wait for it to become valid.
*
* CAREFUL: This assumes that if we already have geometry data, then
* it is valid. This might not be true if the size position was
* recently changed.
*
* REVISIT: Ideally m_haveGeometry would be set false an any calls to
* reposition or resize the window.
*/
void CWidgetControl::waitGeoData(void)
{
// Check if we already have geometry data available.
while (!m_haveGeometry)
{
// No.. it is probably on its way, but to avoid any possibility
// of a deadlock wait, request the position data again.
int ret = nx_getposition(m_hWindow);
if (ret < 0)
{
gerr("ERROR: nx_getposition failed: %d\n", errno);
}
takeGeoSem();
}
// Put the semaphore count back to 1 for the next guy
giveGeoSem();
}
/**
* Take the bounds semaphore (handling signal interruptions)
*/

View File

@ -112,11 +112,11 @@ bool CWindowEventHandlerList::findWindowEventHandler(CWindowEventHandler *eventH
* Raise the NX window redraw event.
*/
void CWindowEventHandlerList::raiseRedrawEvent(void)
void CWindowEventHandlerList::raiseRedrawEvent(FAR const struct nxgl_rect_s *nxRect, bool more)
{
for (int i = 0; i < m_eventHandlers.size(); ++i)
{
m_eventHandlers.at(i)->handleRedrawEvent();
m_eventHandlers.at(i)->handleRedrawEvent(nxRect, more);
}
}

View File

@ -325,7 +325,7 @@ bool CTaskbar::startWindowManager(void)
i++;
}
// If there is no top appliation (i.e., no applications or all applications
// If there is no top application (i.e., no applications or all applications
// are minimized), then draw the background image
if (!m_topApp)

View File

@ -48,10 +48,12 @@
#include "graphics/nxwidgets/cbgwindow.hxx"
#include "graphics/nxwidgets/cwidgetcontrol.hxx"
#include "graphics/nxwidgets/crlepalettebitmap.hxx"
#include "graphics/nxwidgets/crect.hxx"
#include "graphics/nxwidgets/cimage.hxx"
#include "graphics/twm4nx/twm4nx_config.hxx"
#include "graphics/twm4nx/cwindowevent.hxx"
#include "graphics/twm4nx/cicon.hxx"
#include "graphics/twm4nx/cbackground.hxx"
/////////////////////////////////////////////////////////////////////////////
@ -68,9 +70,9 @@ using namespace Twm4Nx;
CBackground::CBackground(FAR CTwm4Nx *twm4nx)
{
m_twm4nx = twm4nx;
m_backWindow = (NXWidgets::CBgWindow *)0;
m_backImage = (NXWidgets::CImage *)0;
m_twm4nx = twm4nx; // Save the session instance
m_backWindow = (NXWidgets::CBgWindow *)0; // No background window yet
m_backImage = (NXWidgets::CImage *)0; // No background image yet
}
/**
@ -95,7 +97,6 @@ CBackground::~CBackground(void)
// Then delete the background
delete m_backWindow;
m_backWindow = (NXWidgets::CBgWindow *)0;
}
// Delete the background image
@ -103,40 +104,41 @@ CBackground::~CBackground(void)
if (m_backImage != (NXWidgets::CImage *)0)
{
delete m_backImage;
m_backImage = (NXWidgets::CImage *)0;
}
}
/**
* Set the background image
* Finish construction of the background instance. This performs
* That are not appropriate for the constructor because they may
* fail.
*
* @param sbitmap. Identifies the bitmap to paint on background
* @return true on success
*/
bool CBackground::
setBackgroundImage(FAR const struct NXWidgets::SRlePaletteBitmap *sbitmap)
initialize(FAR const struct NXWidgets::SRlePaletteBitmap *sbitmap)
{
ginfo("Create the backgound window\n");
// Create the background window (if we have not already done so)
if (m_backWindow == (NXWidgets::CBgWindow *)0 &&
!createBackgroundWindow())
{
gerr("ERROR: Failed to create the background window\n");
return false;
}
// Free any existing background image
if (m_backImage != (NXWidgets::CImage *)0)
{
delete m_backImage;
m_backImage = (NXWidgets::CImage *)0;
}
ginfo("Create the backgound image\n");
// Create the new background image
if (!createBackgroundImage(sbitmap))
{
gerr("ERROR: Failed to create the background image\n");
delete m_backWindow;
m_backWindow = (NXWidgets::CBgWindow *)0;
return false;
}
@ -146,6 +148,7 @@ bool CBackground::
/**
* Get the size of the physical display device which is equivalent to
* size of the background window.
* size of the background window.
*
* @return The size of the display
*/
@ -166,6 +169,39 @@ void CBackground::getDisplaySize(FAR struct nxgl_size_s &size)
rect.getSize(size);
}
/**
* Handle EVENT_BACKGROUND events.
*
* @param eventmsg. The received NxWidget WINDOW event message.
* @return True if the message was properly handled. false is
* return on any failure.
*/
bool CBackground::event(FAR struct SEventMsg *eventmsg)
{
ginfo("eventID: %u\n", eventmsg->eventID);
bool success = true;
switch (eventmsg->eventID)
{
case EVENT_BACKGROUND_REDRAW: // Redraw the background
{
FAR struct SRedrawEventMsg *redrawmsg =
(FAR struct SRedrawEventMsg *)eventmsg;
success = redrawBackgroundWindow(&redrawmsg->rect,
redrawmsg->more);
}
break;
default:
success = false;
break;
}
return success;
}
/**
* Create the background window.
*
@ -182,7 +218,7 @@ bool CBackground::createBackgroundWindow(void)
// 3. Create a Widget control instance for the window using the default
// style for now. CWindowEvent derives from CWidgetControl.
FAR CWindowEvent *control = new CWindowEvent(m_twm4nx);
FAR CWindowEvent *control = new CWindowEvent(m_twm4nx, true);
m_backWindow = m_twm4nx->getBgWindow(control);
if (m_backWindow == (FAR NXWidgets::CBgWindow *)0)
@ -255,28 +291,36 @@ bool CBackground::
m_backImage = new NXWidgets::CImage(control, imagePos.x, imagePos.y,
imageSize.w, imageSize.h, cbitmap);
if (!m_backImage)
if (m_backImage != (NXWidgets::CImage *)0)
{
delete cbitmap;
return false;
}
// Configure the background image
// Configure and draw the background image
m_backImage->setBorderless(true);
m_backImage->setRaisesEvents(false);
m_backImage->enable();
m_backImage->enableDrawing();
m_backImage->redraw();
return true;
}
/**
* (Re-)draw the background window.
* Handle the background window redraw.
*
* @param nxRect The region in the window that must be redrawn.
* @param more True means that more re-draw requests will follow
* @return true on success
*/
bool CBackground::redrawBackgroundWindow(void)
bool CBackground::redrawBackgroundWindow(FAR const struct nxgl_rect_s *rect,
bool more)
{
ginfo("Redrawing..\n");
// Get the widget control from the background window
NXWidgets::CWidgetControl *control = m_backWindow->getWidgetControl();
@ -285,26 +329,43 @@ bool CBackground::redrawBackgroundWindow(void)
NXWidgets::CGraphicsPort *port = control->getGraphicsPort();
// Get the size of the window
// Get the size of the region to redraw
struct nxgl_size_s windowSize;
if (!m_backWindow->getSize(&windowSize))
{
return false;
}
struct nxgl_size_s redrawSize;
redrawSize.w = rect->pt2.x - rect->pt1.x + 1;
redrawSize.h = rect->pt2.y - rect->pt1.y + 1;
// Fill the entire window with the background color
// Fill the redraw region with the background color
port->drawFilledRect(0, 0, windowSize.w, windowSize.h,
port->drawFilledRect(rect->pt1.x, rect->pt1.y,
redrawSize.w, redrawSize.h,
CONFIG_TWM4NX_DEFAULT_BACKGROUNDCOLOR);
// Then re-draw the background image on the window
if (m_backImage)
if (m_backImage != (NXWidgets::CImage *)0)
{
m_backImage->enableDrawing();
m_backImage->redraw();
// Does any part of the image need to be redrawn?
FAR NXWidgets::CRect cimageRect = m_backImage->getBoundingBox();
struct nxgl_rect_s imageRect;
cimageRect.getNxRect(&imageRect);
struct nxgl_rect_s intersection;
nxgl_rectintersect(&intersection, rect, &imageRect);
if (!nxgl_nullrect(&intersection))
{
// Then re-draw the background image on the window
m_backImage->enableDrawing();
m_backImage->redraw();
}
}
// Now redraw any background icons that need to be redrawn
FAR CIcon *cicon = m_twm4nx->getIcon();
cicon->redrawIcons(rect, more);
return true;
}

View File

@ -340,6 +340,59 @@ void CIcon::down(FAR CWindow *cwin)
}
}
/**
* Redraw icons. The icons are drawn on the background window. When
* the background window receives a redraw request, it will call this
* method in order to redraw any effected icons drawn in the
* background.
*
* @param nxRect The region in the window to be redrawn
* @param more More redraw requests will follow
*/
void CIcon::redrawIcons(FAR const nxgl_rect_s *nxRect, bool more)
{
ginfo("Redrawing...\n");
// Try each region
FAR struct SIconEntry *ie = (FAR struct SIconEntry *)0;
for (FAR struct SIconRegion *ir = m_regionHead; ir; ir = ir->flink)
{
// Try each entry in the region
for (ie = ir->entries; ie; ie = ie->flink)
{
// Create a bounding box for the icon
FAR CWindow *cwin = ie->cwin;
struct nxgl_size_s iconWindowSize;
cwin->getIconWidgetSize(iconWindowSize);
struct nxgl_point_s iconPosition;
cwin->getIconWidgetPosition(iconPosition);
struct nxgl_rect_s iconBounds;
iconBounds.pt1.x = iconPosition.x;
iconBounds.pt1.y = iconPosition.y;
iconBounds.pt2.x = iconPosition.x + iconWindowSize.w - 1;
iconBounds.pt2.y = iconPosition.y + iconWindowSize.h - 1;
struct nxgl_rect_s intersection;
nxgl_rectintersect(&intersection, nxRect, &iconBounds);
if (!nxgl_nullrect(&intersection))
{
// Redraw the icon (or a portion of the icon)
ginfo("Redraw icon\n");
cwin->redrawIcon();
}
}
}
}
/**
* Find the icon region holding the window 'cwin'
*

View File

@ -460,11 +460,11 @@ void CIconMgr::sort(void)
* return on any failure.
*/
bool CIconMgr::event(FAR struct SEventMsg *msg)
bool CIconMgr::event(FAR struct SEventMsg *eventmsg)
{
bool ret = true;
switch (msg->eventID)
switch (eventmsg->eventID)
{
default:
ret = false;

View File

@ -202,9 +202,9 @@ bool CTwm4Nx::run(void)
return false;
}
// Paint the background image
// Initialize the backgound instance and paint the background image
if (!m_background->setBackgroundImage(&CONFIG_TWM4NX_BACKGROUND_IMAGE))
if (!m_background->initialize(&CONFIG_TWM4NX_BACKGROUND_IMAGE))
{
gerr("ERROR: Failed to set backgournd image\n");
cleanup();
@ -383,6 +383,8 @@ void CTwm4Nx::genMqName(void)
bool CTwm4Nx::systemEvent(FAR struct SEventMsg *eventmsg)
{
ginfo("eventID: %u\n", eventmsg->eventID);
switch (eventmsg->eventID)
{
case EVENT_SYSTEM_NOP: // Null event
@ -413,6 +415,8 @@ bool CTwm4Nx::systemEvent(FAR struct SEventMsg *eventmsg)
bool CTwm4Nx::dispatchEvent(FAR struct SEventMsg *eventmsg)
{
ginfo("eventID: %u\n", eventmsg->eventID);
enum EEventRecipient recipient =
(enum EEventRecipient)(eventmsg->eventID & EVENT_RECIPIENT_MASK);
@ -423,7 +427,11 @@ bool CTwm4Nx::dispatchEvent(FAR struct SEventMsg *eventmsg)
ret = CWindowEvent::event(eventmsg);
break;
case EVENT_RECIPIENT_SYSTEM: // Twm4Nx system event
case EVENT_RECIPIENT_SYSTEM: // Twm4Nx system event
ret = m_background->event(eventmsg);
break;
case EVENT_RECIPIENT_BACKGROUND: // Background window event
ret = systemEvent(eventmsg);
break;

View File

@ -60,16 +60,18 @@ using namespace Twm4Nx;
* CWindowEvent Constructor
*
* @param twm4nx. The Twm4Nx session instance.
* @param isBackground. True is this for the background window.
* @param style The default style that all widgets on this display
* should use. If this is not specified, the widget will use the
* values stored in the defaultCWidgetStyle object.
*/
CWindowEvent::CWindowEvent(FAR CTwm4Nx *twm4nx,
CWindowEvent::CWindowEvent(FAR CTwm4Nx *twm4nx, bool isBackground,
FAR const NXWidgets::CWidgetStyle *style)
: NXWidgets::CWidgetControl(style)
{
m_twm4nx = twm4nx; // Cache the Twm4Nx session
m_twm4nx = twm4nx; // Cache the Twm4Nx session
m_isBackground = isBackground; // Background window?
// Open a message queue to send raw NX events. This cannot fail!
@ -115,10 +117,11 @@ CWindowEvent::~CWindowEvent(void)
bool CWindowEvent::event(FAR struct SEventMsg *eventmsg)
{
bool success = true;
ginfo("eventID: %u\n", eventmsg->eventID);
// Handle the event
bool success = true;
switch (eventmsg->eventID)
{
case EVENT_MSG_POLL: // Poll for event
@ -144,6 +147,8 @@ bool CWindowEvent::event(FAR struct SEventMsg *eventmsg)
void CWindowEvent::sendInputEvent(void)
{
ginfo("Input...\n");
// The logic path here is tortuous but flexible:
//
// 1. A listener thread receives mouse or touchscreen input and injects
@ -191,6 +196,46 @@ void CWindowEvent::sendInputEvent(void)
}
}
/**
* Handle a NX window redraw request event
*
* @param nxRect The region in the window to be redrawn
* @param more More redraw requests will follow
*/
void CWindowEvent::handleRedrawEvent(FAR const nxgl_rect_s *nxRect,
bool more)
{
ginfo("backgound=%s\n", m_isBackground ? "YES" : "NO");
// At present, only the background window will get redraw events
if (m_isBackground)
{
struct SRedrawEventMsg msg;
msg.eventID = EVENT_BACKGROUND_REDRAW;
msg.rect.pt1.x = nxRect->pt1.x;
msg.rect.pt1.y = nxRect->pt1.y;
msg.rect.pt2.x = nxRect->pt2.x;
msg.rect.pt2.y = nxRect->pt2.y;
msg.more = more;
// NOTE that we cannot block because we are on the same thread
// as the message reader. If the event queue becomes full then
// we have no other option but to lose events.
//
// I suppose we could recurse and call Twm4Nx::dispatchEvent at
// the risk of runaway stack usage.
int ret = mq_send(m_eventq, (FAR const char *)&msg,
sizeof(struct SRedrawEventMsg), 100);
if (ret < 0)
{
gerr("ERROR: mq_send failed: %d\n", ret);
}
}
}
/**
* Handle an NX window mouse input event.
*/
@ -198,6 +243,8 @@ void CWindowEvent::sendInputEvent(void)
#ifdef CONFIG_NX_XYINPUT
void CWindowEvent::handleMouseEvent(void)
{
ginfo("Mouse input...\n");
// Stimulate an input poll
sendInputEvent();
@ -211,6 +258,8 @@ void CWindowEvent::handleMouseEvent(void)
void CWindowEvent::handleKeyboardEvent(void)
{
ginfo("Keyboard input...\n");
// Stimulate an input poll
sendInputEvent();
@ -233,6 +282,8 @@ void CWindowEvent::handleKeyboardEvent(void)
void CWindowEvent::handleBlockedEvent(FAR void *arg)
{
ginfo("Blocked...\n");
struct SNxEventMsg msg =
{
.eventID = EVENT_WINDOW_DELETE,

View File

@ -179,10 +179,10 @@ namespace NXWidgets
awaiting deletion. */
TNxArray<CNxWidget*> m_widgets; /**< List of controlled
widgets. */
bool m_haveGeometry; /**< True: indicates that we
volatile bool m_haveGeometry; /**< True: indicates that we
have valid geometry data. */
#ifdef CONFIG_NXWIDGET_EVENTWAIT
bool m_waiting; /**< True: Extternal logic waiting for
bool m_waiting; /**< True: External logic waiting for
window event */
sem_t m_waitSem; /**< External loops waits for
events on this semaphore */
@ -322,14 +322,14 @@ namespace NXWidgets
}
/**
* Wait for geometry data
* Check if geomtry data is available. If not, [re-]request the
* geomtry data and wait for it to become valid.
* CAREFUL: This assumes that if we already have geometry data, then
* it is valid. This might not be true if the size position was
* recently changed.
*/
inline void waitGeoData(void)
{
takeGeoSem();
giveGeoSem();
}
void waitGeoData(void);
/**
* Take the bounds semaphore (handling signal interruptions)
@ -698,6 +698,10 @@ namespace NXWidgets
inline bool getWindowPosition(FAR struct nxgl_point_s *pos)
{
// Check if we already have geometry data available. CAREFUL: This
// might refer to OLD geometry data if the position was recently
// changed!
waitGeoData();
pos->x = m_pos.x;
pos->y = m_pos.y;
@ -713,6 +717,10 @@ namespace NXWidgets
inline bool getWindowSize(FAR struct nxgl_size_s *size)
{
// Check if we already have geometry data available. CAREFUL: This
// might refer to OLD geometry data if the position was recently
// changed!
waitGeoData();
size->h = m_size.h;
size->w = m_size.w;
@ -728,6 +736,10 @@ namespace NXWidgets
inline nxgl_coord_t getWindowWidth(void)
{
// Check if we already have geometry data available. CAREFUL: This
// might refer to OLD geometry data if the position was recently
// changed!
waitGeoData();
return m_size.w;
}
@ -741,6 +753,10 @@ namespace NXWidgets
inline nxgl_coord_t getWindowHeight(void)
{
// Check if we already have geometry data available. CAREFUL: This
// might refer to OLD geometry data if the position was recently
// changed!
waitGeoData();
return m_size.h;
}

View File

@ -78,9 +78,14 @@ namespace NXWidgets
/**
* Handle a NX window redraw request event
*
* @param nxRect The region in the window to be redrawn
* @param more More redraw requests will follow
*/
virtual void handleRedrawEvent(void) { }
virtual void handleRedrawEvent(FAR const nxgl_rect_s *nxRect, bool more)
{
}
/**
* Handle a NX window position/size change event

View File

@ -135,9 +135,12 @@ namespace NXWidgets
/**
* Raise the NX window redraw event.
*
* @param nxRect The region in the window to be redrawn
* @param more More redraw requests will follow
*/
void raiseRedrawEvent(void);
void raiseRedrawEvent(FAR const nxgl_rect_s *nxRect, bool more);
/**
* Raise an NX window position/size change event.

View File

@ -49,6 +49,8 @@
#include "graphics/nxwidgets/cwidgeteventhandler.hxx"
#include "graphics/nxwidgets/cwidgeteventargs.hxx"
#include "graphics/twm4nx/ctwm4nxevent.hxx"
/////////////////////////////////////////////////////////////////////////////
// Implementation Class Definition
/////////////////////////////////////////////////////////////////////////////
@ -69,7 +71,7 @@ namespace Twm4Nx
* Background management
*/
class CBackground
class CBackground : protected NXWidgets::CWidgetEventHandler, public CTwm4NxEvent
{
protected:
FAR CTwm4Nx *m_twm4nx; /**< Cached CTwm4Nx instance */
@ -84,6 +86,13 @@ namespace Twm4Nx
bool createBackgroundWindow(void);
/**
* Create the background widget. The background widget is simply a
* container for all of the widgets on the background.
*/
bool createBackgroundWidget(void);
/**
* Create the background image.
*
@ -94,12 +103,14 @@ namespace Twm4Nx
bool createBackgroundImage(FAR const struct NXWidgets::SRlePaletteBitmap *sbitmap);
/**
* (Re-)draw the background window.
* Handle the background window redraw.
*
* @param nxRect The region in the window to be redrawn
* @param more More redraw requests will follow
* @return true on success
*/
bool redrawBackgroundWindow(void);
bool redrawBackgroundWindow(FAR const struct nxgl_rect_s *rect, bool more);
public:
/**
@ -127,13 +138,15 @@ namespace Twm4Nx
}
/**
* Set the background image
* Finish construction of the background instance. This performs
* That are not appropriate for the constructor because they may
* fail.
*
* @param sbitmap. Identifies the bitmap to paint on background
* @return true on success
*/
bool setBackgroundImage(FAR const struct NXWidgets::SRlePaletteBitmap *sbitmap);
bool initialize(FAR const struct NXWidgets::SRlePaletteBitmap *sbitmap);
/**
* Get the size of the physical display device which is equivalent to
@ -143,6 +156,16 @@ namespace Twm4Nx
*/
void getDisplaySize(FAR struct nxgl_size_s &size);
/**
* Handle EVENT_BACKGROUND events.
*
* @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);
};
}

View File

@ -57,7 +57,7 @@ namespace Twm4Nx
FAR struct SIconRegion *flink;
struct nxgl_point_s pos;
struct nxgl_size_s size;
struct nxgl_point_s step; // allocation granularity
struct nxgl_point_s step; // Allocation granularity
FAR struct SIconEntry *entries;
};
@ -183,6 +183,18 @@ namespace Twm4Nx
*/
void down(FAR CWindow *cwin);
/**
* Redraw icons. The icons are drawn on the background window. When
* the background window receives a redraw request, it will call this
* method in order to redraw any effected icons drawn in the
* background.
*
* @param nxRect The region in the window to be redrawn
* @param more More redraw requests will follow
*/
void redrawIcons(FAR const nxgl_rect_s *nxRect, bool more);
};
}

View File

@ -590,7 +590,21 @@ namespace Twm4Nx
inline bool setIconWindowPosition(FAR const struct nxgl_point_s &pos)
{
return m_iconWidget->resize(pos.x, pos.y);
return m_iconWidget->moveTo(pos.x, pos.y);
}
/**
* Redraw the icon.
*/
inline void redrawIcon(void)
{
// Make sure that the icon is properly enabled, then redraw it
m_iconWidget->enable();
m_iconWidget->enableDrawing();
m_iconWidget->setRaisesEvents(true);
m_iconWidget->redraw();
}
/**
@ -626,7 +640,7 @@ namespace Twm4Nx
}
/**
* Handle Twm4Nx events.
* Handle EVENT_WINDOW events.
*
* @param eventmsg. The received NxWidget WINDOW event message.
* @return True if the message was properly handled. false is

View File

@ -44,6 +44,7 @@
#include <nuttx/config.h>
#include <sys/types.h>
#include <cstdbool>
#include <mqueue.h>
#include "graphics/nxwidgets/cwindoweventhandler.hxx"
@ -73,8 +74,9 @@ namespace Twm4Nx
public NXWidgets::CWidgetControl
{
private:
FAR CTwm4Nx *m_twm4nx; /**< Cached instance of CTwm4Nx */
mqd_t m_eventq; /**< NxWidget event message queue */
FAR CTwm4Nx *m_twm4nx; /**< Cached instance of CTwm4Nx */
mqd_t m_eventq; /**< NxWidget event message queue */
bool m_isBackground; /**< True if this serves the background window */
/**
* Send the EVENT_MSG_POLL input event message to the Twm4Nx event loop.
@ -82,7 +84,16 @@ namespace Twm4Nx
void sendInputEvent(void);
// Override CWidgetEventHandler virutal methods ///////////////////////
// Override CWidgetEventHandler virtual methods ///////////////////////
/**
* Handle a NX window redraw request event
*
* @param nxRect The region in the window to be redrawn
* @param more More redraw requests will follow
*/
void handleRedrawEvent(FAR const nxgl_rect_s *nxRect, bool more);
#ifdef CONFIG_NX_XYINPUT
/**
@ -114,12 +125,13 @@ namespace Twm4Nx
* CWindowEvent Constructor
*
* @param twm4nx. The Twm4Nx session instance.
* @param isBackground. True is this for the background window.
* @param style The default style that all widgets on this display
* should use. If this is not specified, the widget will use the
* values stored in the defaultCWidgetStyle object.
*/
CWindowEvent(FAR CTwm4Nx *twm4nx,
CWindowEvent(FAR CTwm4Nx *twm4nx, bool isBackground = false,
FAR const NXWidgets::CWidgetStyle *style =
(const NXWidgets::CWidgetStyle *)NULL);

View File

@ -83,14 +83,15 @@ namespace Twm4Nx
{
EVENT_RECIPIENT_MSG = 0x0000, /**< Twm4Nx messenging event */
EVENT_RECIPIENT_SYSTEM = 0x1000, /**< Twm4Nx system event */
EVENT_RECIPIENT_ICONWIDGET = 0x2000, /**< Icon Widget event */
EVENT_RECIPIENT_ICONMGR = 0x3000, /**< Icon Manager event */
EVENT_RECIPIENT_MENU = 0x4000, /**< Menu related event */
EVENT_RECIPIENT_WINDOW = 0x5000, /**< Window related event */
EVENT_RECIPIENT_TOOLBAR = 0x6000, /**< Toolbar related event */
EVENT_RECIPIENT_BORDER = 0x7000, /**< Window border related event */
EVENT_RECIPIENT_RESIZE = 0x8000, /**< Window resize event */
EVENT_RECIPIENT_APP = 0x9000, /**< App received event via CTwn4NxEvent */
EVENT_RECIPIENT_BACKGROUND = 0x2000, /**< Background window event */
EVENT_RECIPIENT_ICONWIDGET = 0x3000, /**< Icon Widget event */
EVENT_RECIPIENT_ICONMGR = 0x4000, /**< Icon Manager event */
EVENT_RECIPIENT_MENU = 0x5000, /**< Menu related event */
EVENT_RECIPIENT_WINDOW = 0x6000, /**< Window related event */
EVENT_RECIPIENT_TOOLBAR = 0x7000, /**< Toolbar related event */
EVENT_RECIPIENT_BORDER = 0x8000, /**< Window border related event */
EVENT_RECIPIENT_RESIZE = 0x9000, /**< Window resize event */
EVENT_RECIPIENT_APP = 0xa000, /**< App received event via CTwn4NxEvent */
EVENT_RECIPIENT_MASK = 0xf000, /**< Used to isolate recipient */
};
@ -110,55 +111,59 @@ namespace Twm4Nx
EVENT_SYSTEM_ERROR = 0x1001, /**< Report system error */
EVENT_SYSTEM_EXIT = 0x1002, /**< Terminate the Twm4Nx session */
// Recipient == BACKGOUND
EVENT_BACKGROUND_REDRAW = 0x2000, /**< Redraw the background */
// Recipient == ICONWIDGET
EVENT_ICONWIDGET_GRAB = 0x2000, /**< Click on toolbar title */
EVENT_ICONWIDGET_DRAG = 0x2001, /**< Drag window */
EVENT_ICONWIDGET_UNGRAB = 0x2002, /**< Release click on toolbar */
EVENT_ICONWIDGET_GRAB = 0x3000, /**< Click on toolbar title */
EVENT_ICONWIDGET_DRAG = 0x3001, /**< Drag window */
EVENT_ICONWIDGET_UNGRAB = 0x3002, /**< Release click on toolbar */
// Recipient == ICONMGR
// Recipient == MENU
EVENT_MENU_IDENTIFY = 0x4001, /**< Describe the window */
EVENT_MENU_VERSION = 0x4002, /**< Show the Twm4Nx version */
EVENT_MENU_ICONIFY = 0x4003, /**< Tool bar minimize button pressed */
EVENT_MENU_DEICONIFY = 0x4004, /**< Window icon pressed */
EVENT_MENU_FUNCTION = 0x4005, /**< Perform function on unknown menu */
EVENT_MENU_TITLE = 0x4006, /**< REVISIT: Really an action not an event */
EVENT_MENU_ROOT = 0x4007, /**< REVISIT: Popup root menu */
EVENT_MENU_IDENTIFY = 0x5001, /**< Describe the window */
EVENT_MENU_VERSION = 0x5002, /**< Show the Twm4Nx version */
EVENT_MENU_ICONIFY = 0x5003, /**< Tool bar minimize button pressed */
EVENT_MENU_DEICONIFY = 0x5004, /**< Window icon pressed */
EVENT_MENU_FUNCTION = 0x5005, /**< Perform function on unknown menu */
EVENT_MENU_TITLE = 0x5006, /**< REVISIT: Really an action not an event */
EVENT_MENU_ROOT = 0x5007, /**< REVISIT: Popup root menu */
// Recipient == WINDOW
EVENT_WINDOW_FOCUS = 0x5000, /**< Enter modal state */
EVENT_WINDOW_UNFOCUS = 0x5001, /**< Exit modal state */
EVENT_WINDOW_RAISE = 0x5002, /**< Raise window to the top of the heirarchy */
EVENT_WINDOW_LOWER = 0x5003, /**< Lower window to the bottom of the heirarchy */
EVENT_WINDOW_DEICONIFY = 0x5004, /**< De-iconify and raise window */
EVENT_WINDOW_DRAG = 0x5005, /**< Drag window */
EVENT_WINDOW_DELETE = 0x5006, /**< Delete window */
EVENT_WINDOW_FOCUS = 0x6000, /**< Enter modal state */
EVENT_WINDOW_UNFOCUS = 0x6001, /**< Exit modal state */
EVENT_WINDOW_RAISE = 0x6002, /**< Raise window to the top of the heirarchy */
EVENT_WINDOW_LOWER = 0x6003, /**< Lower window to the bottom of the heirarchy */
EVENT_WINDOW_DEICONIFY = 0x6004, /**< De-iconify and raise window */
EVENT_WINDOW_DRAG = 0x6005, /**< Drag window */
EVENT_WINDOW_DELETE = 0x6006, /**< Delete window */
// Recipient == TOOLBAR
EVENT_TOOLBAR_GRAB = 0x6000, /**< Click on title widget */
EVENT_TOOLBAR_UNGRAB = 0x6001, /**< Release click on title widget */
EVENT_TOOLBAR_MENU = 0x6002, /**< Toolbar menu button released */
EVENT_TOOLBAR_MINIMIZE = 0x6003, /**< Toolbar minimize button released */
EVENT_TOOLBAR_RESIZE = 0x6004, /**< Toolbar resize button released */
EVENT_TOOLBAR_TERMINATE = 0x6005, /**< Toolbar delete button released */
EVENT_TOOLBAR_GRAB = 0x7000, /**< Click on title widget */
EVENT_TOOLBAR_UNGRAB = 0x7001, /**< Release click on title widget */
EVENT_TOOLBAR_MENU = 0x7002, /**< Toolbar menu button released */
EVENT_TOOLBAR_MINIMIZE = 0x7003, /**< Toolbar minimize button released */
EVENT_TOOLBAR_RESIZE = 0x7004, /**< Toolbar resize button released */
EVENT_TOOLBAR_TERMINATE = 0x7005, /**< Toolbar delete button released */
// Recipient == BORDER
// Recipient == RESIZE
EVENT_RESIZE_START = 0x8000, /**< Start window resize */
EVENT_RESIZE_VERTZOOM = 0x8001, /**< Zoom vertically only */
EVENT_RESIZE_HORIZOOM = 0x8002, /**< Zoom horizontally only */
EVENT_RESIZE_FULLZOOM = 0x8003, /**< Zoom both vertically and horizontally */
EVENT_RESIZE_LEFTZOOM = 0x8004, /**< Zoom left only */
EVENT_RESIZE_RIGHTZOOM = 0x8005, /**< Zoom right only */
EVENT_RESIZE_TOPZOOM = 0x8006, /**< Zoom top only */
EVENT_RESIZE_BOTTOMZOOM = 0x8007, /**< Zoom bottom only */
EVENT_RESIZE_START = 0x9000, /**< Start window resize */
EVENT_RESIZE_VERTZOOM = 0x9001, /**< Zoom vertically only */
EVENT_RESIZE_HORIZOOM = 0x9002, /**< Zoom horizontally only */
EVENT_RESIZE_FULLZOOM = 0x9003, /**< Zoom both vertically and horizontally */
EVENT_RESIZE_LEFTZOOM = 0x9004, /**< Zoom left only */
EVENT_RESIZE_RIGHTZOOM = 0x9005, /**< Zoom right only */
EVENT_RESIZE_TOPZOOM = 0x9006, /**< Zoom top only */
EVENT_RESIZE_BOTTOMZOOM = 0x9007, /**< Zoom bottom only */
// Recipient == APP
// All application defined events must (1) use recepient == EVENT_RECIPIENT_APP,
@ -195,6 +200,17 @@ namespace Twm4Nx
FAR void *obj; /**< Window object (CWindow or CIconWidget) */
};
/**
* This is the alternative form of the message used with redraw commands
*/
struct SRedrawEventMsg
{
uint16_t eventID; /**< Encoded event ID */
struct nxgl_rect_s rect; /**< Region to be redrawn */
bool more; /**< True: More redraw requests will follow */
};
/**
* This is the alternative form of the message used on in
* CWindowEvent::event()
@ -202,9 +218,9 @@ namespace Twm4Nx
struct SNxEventMsg
{
uint16_t eventID; /**< Encoded event ID */
FAR CWindowEvent *instance; /**< X/Y position */
FAR struct SWindow *win; /**< Twm4NX window reference */
uint16_t eventID; /**< Encoded event ID */
FAR CWindowEvent *instance; /**< X/Y position */
FAR struct SWindow *win; /**< Twm4NX window reference */
};
}

View File

@ -1,206 +0,0 @@
/****************************************************************************
* apps/netutils/json/cJSON.c
*
* This file is a part of NuttX:
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Ported by: Darcy Gong
*
* And derives from the cJSON Project which has an MIT license:
*
* Copyright (c) 2009 Dave Gamble
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
****************************************************************************/
#ifndef __APPS_INCLUDE_NETUTILS_JSON_H
#define __APPS_INCLUDE_NETUTILS_JSON_H
#ifdef __cplusplus
extern "C"
{
#endif
/****************************************************************************
* Included Files
****************************************************************************/
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define cJSON_False 0
#define cJSON_True 1
#define cJSON_NULL 2
#define cJSON_Number 3
#define cJSON_String 4
#define cJSON_Array 5
#define cJSON_Object 6
#define cJSON_IsReference 256
#define cJSON_AddNullToObject(object,name) \
cJSON_AddItemToObject(object, name, cJSON_CreateNull())
#define cJSON_AddTrueToObject(object,name) \
cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
#define cJSON_AddFalseToObject(object,name) \
cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
#define cJSON_AddNumberToObject(object,name,n) \
cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object,name,s) \
cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
/****************************************************************************
* Public Types
****************************************************************************/
/* The cJSON structure: */
typedef struct cJSON
{
/* next/prev allow you to walk array/object chains. Alternatively, use
* GetArraySize/GetArrayItem/GetObjectItem
*/
struct cJSON *next,*prev;
/* An array or object item will have a child pointer pointing to a chain
* of the items in the array/object.
*/
struct cJSON *child;
int type; /* The type of the item, as above. */
char *valuestring; /* The item's string, if type==cJSON_String */
int valueint; /* The item's number, if type==cJSON_Number */
double valuedouble; /* The item's number, if type==cJSON_Number */
/* The item's name string, if this item is the child of, or is in the list
* of subitems of an object.
*/
char *string;
} cJSON;
typedef struct cJSON_Hooks
{
void *(*malloc_fn)(size_t sz);
void (*free_fn)(void *ptr);
} cJSON_Hooks;
/****************************************************************************
* Public Functions
****************************************************************************/
/* Supply malloc, realloc and free functions to cJSON */
void cJSON_InitHooks(cJSON_Hooks* hooks);
/* Supply a block of JSON, and this returns a cJSON object you can
* interrogate. Call cJSON_Delete when finished.
*/
cJSON *cJSON_Parse(const char *value);
/* Render a cJSON entity to text for transfer/storage. Free the char* when
* finished.
*/
char *cJSON_Print(cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any
* formatting. Free the char* when finished.
*/
char *cJSON_PrintUnformatted(cJSON *item);
/* Delete a cJSON entity and all subentities. */
void cJSON_Delete(cJSON *c);
/* Returns the number of items in an array (or object). */
int cJSON_GetArraySize(cJSON *array);
/* Retrieve item number "item" from array "array". Returns NULL if
* unsuccessful.
*/
cJSON *cJSON_GetArrayItem(cJSON *array, int item);
/* Get item "string" from object. Case insensitive. */
cJSON *cJSON_GetObjectItem(cJSON *object, const char *string);
/* For analysing failed parses. This returns a pointer to the parse error.
* You'll probably need to look a few chars back to make sense of it.
* Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds.
*/
const char *cJSON_GetErrorPtr(void);
/* These calls create a cJSON item of the appropriate type. */
cJSON *cJSON_CreateNull(void);
cJSON *cJSON_CreateTrue(void);
cJSON *cJSON_CreateFalse(void);
cJSON *cJSON_CreateBool(int b);
cJSON *cJSON_CreateNumber(double num);
cJSON *cJSON_CreateString(const char *string);
cJSON *cJSON_CreateArray(void);
cJSON *cJSON_CreateObject(void);
/* These utilities create an Array of count items. */
cJSON *cJSON_CreateIntArray(const int *numbers, int count);
cJSON *cJSON_CreateFloatArray(const float *numbers, int count);
cJSON *cJSON_CreateDoubleArray(const double *numbers, int count);
cJSON *cJSON_CreateStringArray(const char **strings, int count);
/* Append item to the specified array/object. */
void cJSON_AddItemToArray(cJSON *array, cJSON *item);
void cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
/* Append reference to item to the specified array/object. Use this when you
* want to add an existing cJSON to a new cJSON, but don't want to corrupt
* your existing cJSON.
*/
void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
void cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
/* Remove/Detatch items from Arrays/Objects. */
cJSON *cJSON_DetachItemFromArray(cJSON *array, int which);
void cJSON_DeleteItemFromArray(cJSON *array, int which);
cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string);
void cJSON_DeleteItemFromObject(cJSON *object, const char *string);
/* Update array items. */
void cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
void cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem);
#ifdef __cplusplus
}
#endif
#endif /* __APPS_INCLUDE_NETUTILS_JSON_H */