X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f97c985452b20a8c2f0bbfb1d0275298bf09fb45..84c5b38d579e140df28cfbb649587e8862148c89:/src/motif/region.cpp

diff --git a/src/motif/region.cpp b/src/motif/region.cpp
index 3a8f5603d0..fb3b1e3db2 100644
--- a/src/motif/region.cpp
+++ b/src/motif/region.cpp
@@ -3,7 +3,7 @@
 // Purpose:   Region class
 // Author:    Markus Holzem/Julian Smart
 // Created:   Fri Oct 24 10:46:34 MET 1997
-// RCS-ID:	  $Id$
+// RCS-ID:      $Id$
 // Copyright: (c) 1997 Markus Holzem/Julian Smart
 // Licence:   wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
@@ -15,13 +15,25 @@
 #include "wx/region.h"
 #include "wx/gdicmn.h"
 
+#ifdef __VMS__
+#pragma message disable nosimpint
+#endif
 #include <Xm/Xm.h>
+#ifdef __VMS__
+#pragma message enable nosimpint
+#endif
 // #include "wx/motif/private.h"
 
-#if !USE_SHARED_LIBRARY
-	IMPLEMENT_DYNAMIC_CLASS(wxRegion, wxGDIObject)
-	IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator, wxObject)
-#endif
+    IMPLEMENT_DYNAMIC_CLASS(wxRegion, wxGDIObject)
+    IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator, wxObject)
+
+// ----------------------------------------------------------------------------
+// list types
+// ----------------------------------------------------------------------------
+
+#include "wx/listimpl.cpp"
+
+WX_DEFINE_LIST(wxRectList);
 
 //-----------------------------------------------------------------------------
 // wxRegionRefData implementation
@@ -29,24 +41,89 @@
 
 class WXDLLEXPORT wxRegionRefData : public wxGDIRefData {
 public:
-	wxRegionRefData()
-	{
-		m_region = XCreateRegion();
-	}
-
-	wxRegionRefData(const wxRegionRefData& data)
-	{
-		m_region = XCreateRegion();
-		XUnionRegion(m_region, data.m_region, m_region);
-	}
-
-	~wxRegionRefData()
-	{
-		XDestroyRegion(m_region);
-	}
-    Region  m_region;
+    wxRegionRefData()
+    {
+        m_region = XCreateRegion();
+        m_usingRects = FALSE;
+        m_rects = (wxRect*) NULL;
+        m_rectCount = 0;
+    }
+
+    wxRegionRefData(const wxRegionRefData& data)
+    {
+        m_region = XCreateRegion();
+        m_rects = (wxRect*) NULL;
+        m_rectCount = 0;
+        XUnionRegion(m_region, data.m_region, m_region);
+
+        SetRects(data.m_rectCount, data.m_rects);
+    }
+
+    ~wxRegionRefData()
+    {
+        XDestroyRegion(m_region);
+        DeleteRects();
+    }
+
+    wxRect* GetRects() { return m_rects; };
+    void SetRects(const wxRectList& rectList);
+    void SetRects(int count, const wxRect* rects);
+    bool UsingRects() const { return m_usingRects; }
+    int GetRectCount() const { return m_rectCount; }
+
+    void DeleteRects();
+
+    Region      m_region;
+    wxRect*     m_rects;
+    int         m_rectCount;
+    bool        m_usingRects;  // TRUE if we're using the above.
 };
 
+void wxRegionRefData::SetRects(const wxRectList& rectList)
+{
+    DeleteRects();
+    m_usingRects = (rectList.Number() > 0);
+    if (m_usingRects)
+    {
+      m_rectCount = rectList.Number();
+      m_rects = new wxRect[m_rectCount];
+    }
+
+    wxRectList::Node* node = rectList.GetFirst();
+    int i = 0;
+    while (node) {
+        wxRect* rect = node->GetData();
+        m_rects[i] = * rect;
+        node = node->GetNext();
+        i ++;
+    }
+}
+
+void wxRegionRefData::SetRects(int count, const wxRect* rects)
+{
+    DeleteRects();
+    m_usingRects = (count > 0);
+    if (m_usingRects)
+    {
+      m_rectCount = count;
+      m_rects = new wxRect[m_rectCount];
+      int i;
+      for (i = 0; i < m_rectCount; i++)
+        m_rects[i] = rects[i];
+    }
+}
+
+void wxRegionRefData::DeleteRects()
+{
+   if (m_rects)
+   {
+      delete[] m_rects;
+      m_rects = (wxRect*) NULL;
+   }
+   m_rectCount = 0;
+   m_usingRects = FALSE;
+ }
+
 #define M_REGION (((wxRegionRefData*)m_refData)->m_region)
 
 //-----------------------------------------------------------------------------
@@ -60,28 +137,28 @@ wxRegion::wxRegion()
 {
 }
 
-wxRegion::wxRegion(long x, long y, long w, long h)
+wxRegion::wxRegion(wxCoord x, wxCoord y, wxCoord w, wxCoord h)
 {
     m_refData = new wxRegionRefData;
 
-	XRectangle rect;
-	rect.x		= x;
-	rect.y		= y;
-	rect.width	= w;
-	rect.height = h;
-	XUnionRectWithRegion(&rect, M_REGION, M_REGION);
+    XRectangle rect;
+    rect.x        = x;
+    rect.y        = y;
+    rect.width    = w;
+    rect.height = h;
+    XUnionRectWithRegion(&rect, M_REGION, M_REGION);
 }
 
 wxRegion::wxRegion(const wxPoint& topLeft, const wxPoint& bottomRight)
 {
     m_refData = new wxRegionRefData;
 
-	XRectangle rect;
-	rect.x		= topLeft.x;
-	rect.y		= topLeft.y;
-	rect.width	= bottomRight.x - topLeft.x;
-	rect.height = bottomRight.y - topLeft.y;
-	XUnionRectWithRegion(&rect, M_REGION, M_REGION);
+    XRectangle rect;
+    rect.x        = topLeft.x;
+    rect.y        = topLeft.y;
+    rect.width    = bottomRight.x - topLeft.x;
+    rect.height = bottomRight.y - topLeft.y;
+    XUnionRectWithRegion(&rect, M_REGION, M_REGION);
 }
 
 wxRegion::wxRegion(const wxRect& rect)
@@ -89,9 +166,9 @@ wxRegion::wxRegion(const wxRect& rect)
     m_refData = new wxRegionRefData;
 
     XRectangle rect1;
-    rect1.x		= rect.x;
-    rect1.y		= rect.y;
-    rect1.width	= rect.width;
+    rect1.x        = rect.x;
+    rect1.y        = rect.y;
+    rect1.width    = rect.width;
     rect1.height = rect.height;
     XUnionRectWithRegion(&rect1, M_REGION, M_REGION);
 }
@@ -104,6 +181,14 @@ wxRegion::~wxRegion()
     // m_refData unrefed in ~wxObject
 }
 
+// Get the internal region handle
+WXRegion wxRegion::GetXRegion() const
+{
+    wxASSERT( m_refData !=NULL );
+
+    return (WXRegion) ((wxRegionRefData*)m_refData)->m_region;
+}
+
 //-----------------------------------------------------------------------------
 //# Modify region
 //-----------------------------------------------------------------------------
@@ -115,35 +200,34 @@ void wxRegion::Clear()
 }
 
 //! Combine rectangle (x, y, w, h) with this.
-bool wxRegion::Combine(long x, long y, long width, long height, wxRegionOp op)
-{
-	// Don't change shared data
-	if (!m_refData) {
-		m_refData = new wxRegionRefData();
-	} else if (m_refData->GetRefCount() > 1) {
-		wxRegionRefData* ref = (wxRegionRefData*)m_refData;
-		UnRef();
-		m_refData = new wxRegionRefData(*ref);
-	}
+bool wxRegion::Combine(wxCoord x, wxCoord y, wxCoord width, wxCoord height, wxRegionOp op)
+{
+    // Don't change shared data
+    if (!m_refData) {
+        m_refData = new wxRegionRefData();
+    } else if (m_refData->GetRefCount() > 1) {
+        wxRegionRefData* ref = (wxRegionRefData*)m_refData;
+        UnRef();
+        m_refData = new wxRegionRefData(*ref);
+    }
     // If ref count is 1, that means it's 'ours' anyway so no action.
 
     Region rectRegion = XCreateRegion();
 
-	XRectangle rect;
-	rect.x		= x;
-	rect.y		= y;
-	rect.width	= width;
-	rect.height = height;
-	XUnionRectWithRegion(&rect, rectRegion, rectRegion);
+    XRectangle rect;
+    rect.x        = x;
+    rect.y        = y;
+    rect.width    = width;
+    rect.height = height;
+    XUnionRectWithRegion(&rect, rectRegion, rectRegion);
 
-    int mode = 0; // TODO platform-specific code
     switch (op)
     {
         case wxRGN_AND:
-	        XIntersectRegion(M_REGION, rectRegion, M_REGION);
+            XIntersectRegion(M_REGION, rectRegion, M_REGION);
             break ;
         case wxRGN_OR:
-	        XUnionRegion(M_REGION, rectRegion, M_REGION);
+            XUnionRegion(M_REGION, rectRegion, M_REGION);
             break ;
         case wxRGN_XOR:
             // TODO
@@ -163,28 +247,27 @@ bool wxRegion::Combine(long x, long y, long width, long height, wxRegionOp op)
 //! Union /e region with this.
 bool wxRegion::Combine(const wxRegion& region, wxRegionOp op)
 {
-	if (region.Empty())
-		return FALSE;
-
-	// Don't change shared data
-	if (!m_refData) {
-		m_refData = new wxRegionRefData();
-	} else	if (m_refData->GetRefCount() > 1) {
-		wxRegionRefData* ref = (wxRegionRefData*)m_refData;
-		UnRef();
-		m_refData = new wxRegionRefData(*ref);
-	}
+    if (region.Empty())
+        return FALSE;
+
+    // Don't change shared data
+    if (!m_refData) {
+        m_refData = new wxRegionRefData();
+    } else    if (m_refData->GetRefCount() > 1) {
+        wxRegionRefData* ref = (wxRegionRefData*)m_refData;
+        UnRef();
+        m_refData = new wxRegionRefData(*ref);
+    }
 
-    int mode = 0; // TODO platform-specific code
     switch (op)
     {
         case wxRGN_AND:
-	        XIntersectRegion(M_REGION, ((wxRegionRefData*)region.m_refData)->m_region,
-				 M_REGION);
+            XIntersectRegion(M_REGION, ((wxRegionRefData*)region.m_refData)->m_region,
+                 M_REGION);
             break ;
         case wxRGN_OR:
-	        XUnionRegion(M_REGION, ((wxRegionRefData*)region.m_refData)->m_region,
-				 M_REGION);
+            XUnionRegion(M_REGION, ((wxRegionRefData*)region.m_refData)->m_region,
+                 M_REGION);
             break ;
         case wxRGN_XOR:
             // TODO
@@ -198,9 +281,7 @@ bool wxRegion::Combine(const wxRegion& region, wxRegionOp op)
             break ;
     }
 
-    // TODO combine region
-
-	return FALSE;
+  return FALSE;
 }
 
 bool wxRegion::Combine(const wxRect& rect, wxRegionOp op)
@@ -213,23 +294,23 @@ bool wxRegion::Combine(const wxRect& rect, wxRegionOp op)
 //-----------------------------------------------------------------------------
 
 // Outer bounds of region
-void wxRegion::GetBox(long& x, long& y, long&w, long &h) const
+void wxRegion::GetBox(wxCoord& x, wxCoord& y, wxCoord&w, wxCoord &h) const
 {
-	if (m_refData) {
-		XRectangle rect;
-		XClipBox(M_REGION, &rect);
-		x = rect.x;
-		y = rect.y;
-		w = rect.width;
-		h = rect.height;
-	} else {
-		x = y = w = h = 0;
-	}
+    if (m_refData) {
+        XRectangle rect;
+        XClipBox(M_REGION, &rect);
+        x = rect.x;
+        y = rect.y;
+        w = rect.width;
+        h = rect.height;
+    } else {
+        x = y = w = h = 0;
+    }
 }
 
 wxRect wxRegion::GetBox() const
 {
-    long x, y, w, h;
+    wxCoord x, y, w, h;
     GetBox(x, y, w, h);
     return wxRect(x, y, w, h);
 }
@@ -237,7 +318,7 @@ wxRect wxRegion::GetBox() const
 // Is region empty?
 bool wxRegion::Empty() const
 {
-	return m_refData ? XEmptyRegion(M_REGION) : FALSE;
+    return m_refData ? XEmptyRegion(M_REGION) : TRUE;
 }
 
 //-----------------------------------------------------------------------------
@@ -245,10 +326,10 @@ bool wxRegion::Empty() const
 //-----------------------------------------------------------------------------
 
 // Does the region contain the point (x,y)?
-wxRegionContain wxRegion::Contains(long x, long y) const
+wxRegionContain wxRegion::Contains(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y)) const
 {
-	if (!m_refData)
-		return wxOutRegion;
+    if (!m_refData)
+        return wxOutRegion;
 
     // TODO. Return wxInRegion if within region.
     if (0)
@@ -259,32 +340,32 @@ wxRegionContain wxRegion::Contains(long x, long y) const
 // Does the region contain the point pt?
 wxRegionContain wxRegion::Contains(const wxPoint& pt) const
 {
-	if (!m_refData)
-		return wxOutRegion;
+    if (!m_refData)
+        return wxOutRegion;
 
-	return XPointInRegion(M_REGION, pt.x, pt.y) ? wxInRegion : wxOutRegion;
+    return XPointInRegion(M_REGION, pt.x, pt.y) ? wxInRegion : wxOutRegion;
 }
 
 // Does the region contain the rectangle (x, y, w, h)?
-wxRegionContain wxRegion::Contains(long x, long y, long w, long h) const
+wxRegionContain wxRegion::Contains(wxCoord x, wxCoord y, wxCoord w, wxCoord h) const
 {
-	if (!m_refData)
-		return wxOutRegion;
+    if (!m_refData)
+        return wxOutRegion;
 
-	switch (XRectInRegion(M_REGION, x, y, w, h)) {
-	    case RectangleIn:	return wxInRegion;
-	    case RectanglePart: return wxPartRegion;
-	}
-	return wxOutRegion;
+    switch (XRectInRegion(M_REGION, x, y, w, h)) {
+        case RectangleIn:    return wxInRegion;
+        case RectanglePart: return wxPartRegion;
+    }
+    return wxOutRegion;
 }
 
 // Does the region contain the rectangle rect
 wxRegionContain wxRegion::Contains(const wxRect& rect) const
 {
-	if (!m_refData)
-		return wxOutRegion;
+    if (!m_refData)
+        return wxOutRegion;
 
-    long x, y, w, h;
+    wxCoord x, y, w, h;
     x = rect.x;
     y = rect.y;
     w = rect.GetWidth();
@@ -292,10 +373,42 @@ wxRegionContain wxRegion::Contains(const wxRect& rect) const
     return Contains(x, y, w, h);
 }
 
+bool wxRegion::UsingRects() const
+{
+    return ((wxRegionRefData*)m_refData)->UsingRects();
+}
+
+/*
+wxRectList& wxRegion::GetRectList()
+{
+    return ((wxRegionRefData*)m_refData)->GetRectList();
+}
+*/
+
+wxRect* wxRegion::GetRects()
+{
+    return ((wxRegionRefData*)m_refData)->GetRects();
+}
+
+int wxRegion::GetRectCount() const
+{
+    return ((wxRegionRefData*)m_refData)->GetRectCount();
+}
+
+void wxRegion::SetRects(const wxRectList& rectList)
+{
+    ((wxRegionRefData*)m_refData)->SetRects(rectList);
+}
+
+void wxRegion::SetRects(int count, const wxRect* rects)
+{
+    ((wxRegionRefData*)m_refData)->SetRects(count, rects);
+}
+
 ///////////////////////////////////////////////////////////////////////////////
-//																			 //
-//							   wxRegionIterator								 //
-//																			 //
+//                                                                             //
+//                               wxRegionIterator                                 //
+//                                                                             //
 ///////////////////////////////////////////////////////////////////////////////
 
 /*!
@@ -318,7 +431,7 @@ wxRegionIterator::wxRegionIterator(const wxRegion& region)
 {
     m_rects = NULL;
 
-	Reset(region);
+    Reset(region);
 }
 
 /*!
@@ -326,20 +439,50 @@ wxRegionIterator::wxRegionIterator(const wxRegion& region)
  */
 void wxRegionIterator::Reset(const wxRegion& region)
 {
-	m_current = 0;
-	m_region = region;
+    m_current = 0;
+    m_region = region;
 
     if (m_rects)
         delete[] m_rects;
 
     m_rects = NULL;
 
-	if (m_region.Empty())
-		m_numRects = 0;
-	else
-    {
-        // TODO create m_rects and fill with rectangles for this region
+    if (m_region.Empty())
         m_numRects = 0;
+    else
+    {
+        // Create m_rects and fill with rectangles for this region.
+        // Since we can't find the rectangles in a region, we cheat
+        // by retrieving the rectangles explicitly set in wxPaintDC::wxPaintDC
+        // (dcclient.cpp).
+        if (m_region.UsingRects())
+        {
+            wxRect* rects = m_region.GetRects();
+            int count = m_region.GetRectCount();
+            m_numRects = count;
+            m_rects = new wxRect[m_numRects];
+
+            for (size_t i = 0; i < m_numRects; i++)
+               m_rects[i] = rects[i];
+
+	    /*
+            int i = 0;
+            wxRectList::Node* node = rectList.GetFirst();
+            while (node) {
+                wxRect* rect = node->GetData();
+                m_rects[i] = * rect;
+                node = node->GetNext();
+                i ++;
+            }
+	    */
+        }
+        else
+        {
+            // For now, fudge by getting the whole bounding box.
+            m_rects = new wxRect[1];
+            m_numRects = 1;
+            m_rects[0] = m_region.GetBox();
+        }
     }
 }
 
@@ -349,8 +492,8 @@ void wxRegionIterator::Reset(const wxRegion& region)
  */
 void wxRegionIterator::operator ++ ()
 {
-	if (m_current < m_numRects)
-		++m_current;
+    if (m_current < m_numRects)
+        ++m_current;
 }
 
 /*!
@@ -359,35 +502,35 @@ void wxRegionIterator::operator ++ ()
  */
 void wxRegionIterator::operator ++ (int)
 {
-	if (m_current < m_numRects)
-		++m_current;
+    if (m_current < m_numRects)
+        ++m_current;
 }
 
-long wxRegionIterator::GetX() const
+wxCoord wxRegionIterator::GetX() const
 {
-	if (m_current < m_numRects)
-		return m_rects[m_current].x;
-	return 0;
+    if (m_current < m_numRects)
+        return m_rects[m_current].x;
+    return 0;
 }
 
-long wxRegionIterator::GetY() const
+wxCoord wxRegionIterator::GetY() const
 {
-	if (m_current < m_numRects)
-		return m_rects[m_current].y;
-	return 0;
+    if (m_current < m_numRects)
+        return m_rects[m_current].y;
+    return 0;
 }
 
-long wxRegionIterator::GetW() const
+wxCoord wxRegionIterator::GetW() const
 {
-	if (m_current < m_numRects)
-		return m_rects[m_current].width ;
-	return 0;
+    if (m_current < m_numRects)
+        return m_rects[m_current].width ;
+    return 0;
 }
 
-long wxRegionIterator::GetH() const
+wxCoord wxRegionIterator::GetH() const
 {
-	if (m_current < m_numRects)
-		return m_rects[m_current].height;
-	return 0;
+    if (m_current < m_numRects)
+        return m_rects[m_current].height;
+    return 0;
 }