]> git.saurik.com Git - wxWidgets.git/blobdiff - src/motif/dcclient.cpp
Fixed three mouse event bugs
[wxWidgets.git] / src / motif / dcclient.cpp
index 1a9b9abb6a947303dee35c59aaa91b5ec7f5db0d..e99b12a34706d6c618d274a5f4655458f8ca10cd 100644 (file)
@@ -146,7 +146,7 @@ wxWindowDC::wxWindowDC( wxWindow *window )
 
 wxWindowDC::~wxWindowDC(void)
 {
-    if ((m_oldFont != (WXFont) 0) && ((long) m_oldFont != -1))
+    if (m_gc && (m_oldFont != (WXFont) 0) && ((long) m_oldFont != -1))
     {
       XSetFont ((Display*) m_display, (GC) m_gc, (Font) m_oldFont);
 
@@ -172,7 +172,7 @@ wxWindowDC::~wxWindowDC(void)
 };
 
 void wxWindowDC::FloodFill( long WXUNUSED(x1), long WXUNUSED(y1), 
-  wxColour* WXUNUSED(col), int WXUNUSED(style) )
+  const wxColour& WXUNUSED(col), int WXUNUSED(style) )
 {
   // TODO
 };
@@ -354,7 +354,7 @@ void wxWindowDC::DrawEllipticArc( long x, long y, long width, long height, doubl
           XLOG2DEV_2 (x), YLOG2DEV_2 (y),wd,hd,start,end);
     }
 
-  if (!m_pen.Ok() && m_pen.GetStyle () != wxTRANSPARENT)
+  if (m_pen.Ok() && m_pen.GetStyle () != wxTRANSPARENT)
     {
       if (m_autoSetting)
     SetPen (m_pen);
@@ -1229,7 +1229,8 @@ void wxWindowDC::GetTextExtent( const wxString &string, long *width, long *heigh
   if (!theFont->Ok())
   {
     // TODO: this should be an error log function
-    cerr << "wxWindows warning - set a valid font before calling GetTextExtent!\n";
+    wxFAIL_MSG("set a valid font before calling GetTextExtent!");
+
     *width = -1;
     *height = -1;
     return;
@@ -1298,7 +1299,6 @@ void wxWindowDC::Clear(void)
   int w, h;
   if (m_window)
     {
-      // TODO: should we get the virtual size?
       m_window->GetSize(&w, &h);
 
       if (m_window && m_window->GetBackingPixmap())
@@ -1330,6 +1330,24 @@ void wxWindowDC::Clear(void)
   m_brush = saveBrush;
 };
 
+void wxWindowDC::Clear(const wxRect& rect)
+{
+  if (!Ok()) return;
+  
+  int x = rect.x; int y = rect.y;
+  int w = rect.width; int h = rect.height;
+
+  wxBrush saveBrush = m_brush;
+  SetBrush (m_backgroundBrush);
+
+  XFillRectangle ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, x, y, w, h);
+
+  if (m_window && m_window->GetBackingPixmap())
+    XFillRectangle ((Display*) m_display, (Pixmap) m_window->GetBackingPixmap(),(GC) m_gcBacking, x, y, w, h);
+
+  m_brush = saveBrush;
+};
+
 void wxWindowDC::SetFont( const wxFont &font )
 {
   if (!Ok()) return;
@@ -1385,7 +1403,7 @@ void wxWindowDC::SetPen( const wxPen &pen )
   m_currentPenDash = m_pen.GetDash();
 
   if (m_currentStyle == wxSTIPPLE)
-    m_currentStipple = m_pen.GetStipple ();
+    m_currentStipple = m_pen.GetStipple ();
 
   bool sameStyle = (oldStyle == m_currentStyle &&
              oldFill == m_currentFill &&
@@ -1522,7 +1540,7 @@ void wxWindowDC::SetPen( const wxPen &pen )
     {
       Pixmap myStipple;
 
-      oldStipple = NULL;    // For later reset!!
+      oldStipple = wxNullBitmap;    // For later reset!!
 
       switch (m_currentFill)
       {
@@ -1673,7 +1691,7 @@ void wxWindowDC::SetBrush( const wxBrush &brush )
 
   m_currentFill = m_brush.GetStyle ();
   if (m_currentFill == wxSTIPPLE)
-    m_currentStipple = m_brush.GetStipple ();
+    m_currentStipple = m_brush.GetStipple ();
 
   wxColour oldBrushColour(m_currentColour);
   m_currentColour = m_brush.GetColour ();
@@ -1855,7 +1873,9 @@ void wxWindowDC::SetBackground( const wxBrush &brush )
 
   int pixel = m_backgroundBrush.GetColour().AllocColour(m_display);
 
-  XSetWindowBackground ((Display*) m_display, (Pixmap) m_pixmap, pixel);
+  // XSetWindowBackground doesn't work for non-Window pixmaps
+  if (!this->IsKindOf(CLASSINFO(wxMemoryDC)))
+      XSetWindowBackground ((Display*) m_display, (Pixmap) m_pixmap, pixel);
 
   // Necessary for ::DrawIcon, which use fg/bg pixel or the GC.
   // And Blit,... (Any fct that use XCopyPlane, in fact.)
@@ -1990,17 +2010,17 @@ void wxWindowDC:: SetDCClipping ()
   // clipping imposed on a window by a repaint.
   // We'll combine it with the user region. But for now,
   // just use the currently-defined user clipping region.
-  if (m_userRegion || (m_window && m_window->GetPaintRegion()) )
+  if (m_userRegion || (m_window && m_window->GetUpdateRegion().Ok()) )
     m_currentRegion = (WXRegion) XCreateRegion ();
   else
     m_currentRegion = (WXRegion) NULL;
 
-  if ((m_window && m_window->GetPaintRegion()) && m_userRegion)
-    XIntersectRegion ((Region) m_window->GetPaintRegion(), (Region) m_userRegion, (Region) m_currentRegion);
+  if ((m_window && m_window->GetUpdateRegion().Ok()) && m_userRegion)
+    XIntersectRegion ((Region) m_window->GetUpdateRegion().GetXRegion(), (Region) m_userRegion, (Region) m_currentRegion);
   else if (m_userRegion)
     XIntersectRegion ((Region) m_userRegion, (Region) m_userRegion, (Region) m_currentRegion);
-  else if (m_window && m_window->GetPaintRegion())
-    XIntersectRegion ((Region) m_window->GetPaintRegion(), (Region) m_window->GetPaintRegion(), 
+  else if (m_window && m_window->GetUpdateRegion().Ok())
+    XIntersectRegion ((Region) m_window->GetUpdateRegion().GetXRegion(), (Region) m_window->GetUpdateRegion().GetXRegion(), 
 (Region) m_currentRegion);
 
   if (m_currentRegion)
@@ -2043,6 +2063,34 @@ void wxWindowDC::SetClippingRegion( long x, long y, long width, long height )
   }
 };
 
+void wxWindowDC::SetClippingRegion( const wxRegion& region )
+{
+  wxRect box = region.GetBox();
+
+  wxDC::SetClippingRegion( box.x, box.y, box.width, box.height );
+
+  if (m_userRegion)
+    XDestroyRegion ((Region) m_userRegion);
+  m_userRegion = (WXRegion) XCreateRegion ();
+
+  XUnionRegion((Region) m_userRegion, (Region) region.GetXRegion(), (Region) m_userRegion);
+
+  SetDCClipping ();
+
+  // Needs to work differently for Pixmap: without this,
+  // there's a nasty (Display*) m_display bug. 8/12/94
+  if (m_window && m_window->GetBackingPixmap())
+  {
+    XRectangle rects[1];
+    rects[0].x = XLOG2DEV_2(box.x);
+    rects[0].y = YLOG2DEV_2(box.y);
+    rects[0].width = XLOG2DEVREL(box.width);
+    rects[0].height = YLOG2DEVREL(box.height);
+    XSetClipRectangles((Display*) m_display, (GC) m_gcBacking, 0, 0, rects, 1, Unsorted);
+  }
+};
+
+
 void wxWindowDC::DestroyClippingRegion(void)
 {
   wxDC::DestroyClippingRegion();
@@ -2223,3 +2271,56 @@ void wxWindowDC::DrawSpline( wxList *points )
 
     wx_spline_draw_point_array( this );
 };
+
+/*
+ * wxPaintDC
+ */
+
+wxPaintDC::wxPaintDC(wxWindow* win): wxWindowDC(win)
+{
+    wxRegion* region = NULL;
+
+    // Combine all the update rects into a region
+    if (win->m_updateRects.Number() > 0)
+    {
+        int i = 0;
+        for (i = 0; i < win->m_updateRects.Number(); i++)
+        {
+            wxRect* rect = (wxRect*) win->m_updateRects.Nth(i)->Data();
+           /*
+            cout << "wxPaintDC. wxRect: " << rect->x << ", " << rect->y << ", ";
+            cout << rect->width << ", " << rect->height << "\n\n";
+           */
+
+            if (!region)
+                region = new wxRegion(*rect);
+            else
+                // TODO: is this correct? In SetDCClipping above,
+                // XIntersectRegion is used to combine paint and user
+                // regions. XIntersectRegion appears to work in that case...
+                region->Union(*rect);
+        }
+    }
+    else
+    {
+        int cw, ch;
+        win->GetClientSize(&cw, &ch);
+        region = new wxRegion(wxRect(0, 0, cw, ch));
+    }
+
+    win->m_updateRegion = *region;
+
+    // Set the clipping region. Any user-defined region will be combined with this
+    // one in SetDCClipping.
+    XSetRegion ((Display*) m_display, (GC) m_gc, (Region) region->GetXRegion());
+
+    delete region;
+}
+
+wxPaintDC::~wxPaintDC()
+{
+    XSetClipMask ((Display*) m_display, (GC) m_gc, None);
+    if (m_window)
+        m_window->m_updateRegion.Clear();
+}
+