]> git.saurik.com Git - wxWidgets.git/commitdiff
compilation fixes
authorVadim Zeitlin <vadim@wxwidgets.org>
Fri, 5 Mar 1999 13:23:38 +0000 (13:23 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Fri, 5 Mar 1999 13:23:38 +0000 (13:23 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1862 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/generic/laywin.h
include/wx/motif/icon.h
src/generic/dcpsg.cpp
src/motif/thread.cpp
src/motif/utilsexc.cpp

index 7a80b50e13b6e01bde585e035c816a8d9507062a..6fcbc5c300fb31f3ea8e596a72586040fa03bf4f 100644 (file)
@@ -9,7 +9,7 @@
 // Created:     04/01/98
 // RCS-ID:      $Id$
 // Copyright:   (c) Julian Smart
-// Licence:    wxWindows licence
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 #ifndef _WX_LAYWIN_H_G_
@@ -34,7 +34,7 @@ enum wxLayoutAlignment {
     wxLAYOUT_TOP,
     wxLAYOUT_LEFT,
     wxLAYOUT_RIGHT,
-    wxLAYOUT_BOTTOM,
+    wxLAYOUT_BOTTOM
 };
 
 // Not sure this is necessary
@@ -110,7 +110,7 @@ public:
     {
         SetEventType(wxEVT_CALCULATE_LAYOUT);
         m_flags = 0;
-       m_id = id;
+        m_id = id;
     }
 // Read by the app
     inline void SetFlags(int flags) { m_flags = flags; }
index cbb4f53c69abe990af27b58798e96414619eac30..3ac1eb445001ac549ab804f55191525e724c6e65 100644 (file)
@@ -56,8 +56,8 @@ public:
 
   bool LoadFile(const wxString& name, long flags = wxBITMAP_TYPE_XPM,
       int desiredWidth = -1, int desiredHeight = -1);
-//  bool LoadFile(const wxString& name, long type = wxBITMAP_TYPE_XBM)
-//    { return wxBitmap::LoadFile(name, type); }
+  bool LoadFile(const wxString& name, long type = wxBITMAP_TYPE_XBM)
+    { return wxBitmap::LoadFile(name, type); }
 
   inline wxIcon& operator = (const wxIcon& icon) { if (*this == icon) return (*this); Ref(icon); return *this; }
   inline bool operator == (const wxIcon& icon) { return m_refData == icon.m_refData; }
index dcd5c76c05e4fbe4cc5cd1900653ccfbb114e9c1..883b7665b1450a429ed87fc2c511ff0c9dced60b 100644 (file)
@@ -231,15 +231,15 @@ static char wxPostScriptHeaderReencodeISO2[] =
 wxPostScriptDC::wxPostScriptDC ()
 {
     m_pstream = (ofstream*) NULL;
-    
+
     m_currentRed = 0;
     m_currentGreen = 0;
     m_currentBlue = 0;
-    
+
     m_pageNumber = 0;
-    
+
     m_clipping = FALSE;
-    
+
     m_underlinePosition = 0.0;
     m_underlineThickness = 0.0;
 
@@ -250,15 +250,15 @@ wxPostScriptDC::wxPostScriptDC ()
 wxPostScriptDC::wxPostScriptDC (const wxString& file, bool interactive, wxWindow *parent)
 {
     m_pstream = (ofstream*) NULL;
-    
+
     m_currentRed = 0;
     m_currentGreen = 0;
     m_currentBlue = 0;
-    
+
     m_pageNumber = 0;
-    
+
     m_clipping = FALSE;
-    
+
     m_underlinePosition = 0.0;
     m_underlineThickness = 0.0;
 
@@ -288,7 +288,7 @@ bool wxPostScriptDC::Create(const wxString& file, bool interactive, wxWindow *pa
     {
         m_ok = TRUE;
     }
-    
+
     return m_ok;
 }
 
@@ -301,17 +301,17 @@ bool wxPostScriptDC::Ok() const
 {
   return m_ok;
 }
-  
+
 bool wxPostScriptDC::PrinterDialog(wxWindow *parent)
 {
-    wxPostScriptPrintDialog dialog( parent, _("Printer Settings"), wxPoint(150, 150), wxSize(400, 400), 
+    wxPostScriptPrintDialog dialog( parent, _("Printer Settings"), wxPoint(150, 150), wxSize(400, 400),
                                     wxDEFAULT_DIALOG_STYLE | wxDIALOG_MODAL );
     m_ok = (dialog.ShowModal () == wxID_OK);
 
     if (!m_ok) return FALSE;
 
-    if ((m_filename == "") && 
-        (wxThePrintSetupData->GetPrinterMode() == PS_PREVIEW  || 
+    if ((m_filename == "") &&
+        (wxThePrintSetupData->GetPrinterMode() == PS_PREVIEW  ||
          wxThePrintSetupData->GetPrinterMode() == PS_PRINTER))
     {
 // steve, 05.09.94
@@ -354,14 +354,14 @@ bool wxPostScriptDC::PrinterDialog(wxWindow *parent)
 void wxPostScriptDC::SetClippingRegion (long x, long y, long w, long h)
 {
     wxCHECK_RET( m_ok && m_pstream, "invalid postscript dc" );
-    
+
     if (m_clipping) return;
 
     wxDC::SetClippingRegion( x, y, w, h );
-    
+
     m_clipping = TRUE;
-    *m_pstream << "gsave\n" 
-               << "newpath\n" 
+    *m_pstream << "gsave\n"
+               << "newpath\n"
            << XLOG2DEV(x)   << " " << YLOG2DEV(y)   << " moveto\n"
            << XLOG2DEV(x+w) << " " << YLOG2DEV(y)   << " lineto\n"
            << XLOG2DEV(x+w) << " " << YLOG2DEV(y+h) << " lineto\n"
@@ -376,9 +376,9 @@ void wxPostScriptDC::SetClippingRegion( const wxRegion &WXUNUSED(region) )
 void wxPostScriptDC::DestroyClippingRegion()
 {
     wxCHECK_RET( m_ok && m_pstream, "invalid postscript dc" );
-    
+
     wxDC::DestroyClippingRegion();
-    
+
     if (m_clipping)
     {
         m_clipping = FALSE;
@@ -410,16 +410,16 @@ void wxPostScriptDC::CrossHair (long WXUNUSED(x), long WXUNUSED(y))
 void wxPostScriptDC::DrawLine (long x1, long y1, long x2, long y2)
 {
     wxCHECK_RET( m_ok && m_pstream, "invalid postscript dc" );
-    
+
     if  (m_pen.GetStyle() == wxTRANSPARENT) return;
-    
+
     SetPen( m_pen );
-    
+
     *m_pstream << "newpath\n"
            <<  XLOG2DEV(x1) << " " <<  YLOG2DEV (y1) << " moveto\n"
            <<  XLOG2DEV(x2) << " " <<  YLOG2DEV (y2) << " lineto\n"
            << "stroke\n";
-           
+
     CalcBoundingBox( x1, y1 );
     CalcBoundingBox( x2, y2 );
 }
@@ -429,20 +429,20 @@ void wxPostScriptDC::DrawLine (long x1, long y1, long x2, long y2)
 void wxPostScriptDC::DrawArc (long x1, long y1, long x2, long y2, long xc, long yc)
 {
     wxCHECK_RET( m_ok && m_pstream, "invalid postscript dc" );
-    
+
     long dx = x1 - xc;
     long dy = y1 - yc;
     long radius = (long) sqrt(dx*dx+dy*dy);
     double alpha1, alpha2;
 
-    if (x1 == x2 && y1 == y2) 
+    if (x1 == x2 && y1 == y2)
     {
     alpha1 = 0.0;
     alpha2 = 360.0;
-    } else if (radius == 0.0) 
+    } else if (radius == 0.0)
     {
     alpha1 = alpha2 = 0.0;
-    } else 
+    } else
     {
     alpha1 = (x1 - xc == 0) ?
         (y1 - yc < 0) ? 90.0 : -90.0 :
@@ -456,7 +456,7 @@ void wxPostScriptDC::DrawArc (long x1, long y1, long x2, long y2, long xc, long
     while (alpha1 > 360)  alpha1 -= 360; // 0 and 360 degree
     while (alpha2 > 360)  alpha2 -= 360;
 
-    if (m_brush.GetStyle() != wxTRANSPARENT) 
+    if (m_brush.GetStyle() != wxTRANSPARENT)
     {
     SetBrush( m_brush );
     *m_pstream << "newpath\n"
@@ -471,8 +471,8 @@ void wxPostScriptDC::DrawArc (long x1, long y1, long x2, long y2, long xc, long
          << "closepath\n"
              << "fill\n";
     }
-    
-    if (m_pen.GetStyle() != wxTRANSPARENT) 
+
+    if (m_pen.GetStyle() != wxTRANSPARENT)
     {
     SetPen( m_pen );
     *m_pstream << "newpath\n"
@@ -484,7 +484,7 @@ void wxPostScriptDC::DrawArc (long x1, long y1, long x2, long y2, long xc, long
          << alpha2               << " ellipse\n"
              << "stroke\n";
     }
-    
+
     CalcBoundingBox( xc-radius, yc-radius );
     CalcBoundingBox( xc+radius, yc+radius );
 }
@@ -492,12 +492,12 @@ void wxPostScriptDC::DrawArc (long x1, long y1, long x2, long y2, long xc, long
 void wxPostScriptDC::DrawEllipticArc(long x,long y,long w,long h,double sa,double ea)
 {
     wxCHECK_RET( m_ok && m_pstream, "invalid postscript dc" );
-    
+
     if (sa>=360 || sa<=-360) sa=sa-int(sa/360)*360;
     if (ea>=360 || ea<=-360) ea=ea-int(ea/360)*360;
     if (sa<0) sa+=360;
     if (ea<0) ea+=360;
-    
+
     if (sa==ea)
     {
         DrawEllipse(x,y,w,h);
@@ -508,22 +508,22 @@ void wxPostScriptDC::DrawEllipticArc(long x,long y,long w,long h,double sa,doubl
     {
         SetBrush( m_brush );
 
-        *m_pstream << "newpath\n" 
-               << XLOG2DEV(x+w/2) << " " << YLOG2DEV(y+h/2) << " " 
-           << XLOG2DEVREL(w/2) << " " << YLOG2DEVREL(h/2) << " " 
+        *m_pstream << "newpath\n"
+               << XLOG2DEV(x+w/2) << " " << YLOG2DEV(y+h/2) << " "
+           << XLOG2DEVREL(w/2) << " " << YLOG2DEVREL(h/2) << " "
            << int(sa) <<" "<< int(ea) << " true ellipticarc\n";
 
         CalcBoundingBox( x ,y );
         CalcBoundingBox( x+w, y+h );
     }
-    
+
     if (m_pen.GetStyle () != wxTRANSPARENT)
     {
         SetPen( m_pen );
 
-        *m_pstream << "newpath\n" 
-               << XLOG2DEV(x+w/2) << " " << YLOG2DEV(y+h/2) << " " 
-           << XLOG2DEVREL(w/2) << " " << XLOG2DEVREL(h/2) << " " 
+        *m_pstream << "newpath\n"
+               << XLOG2DEV(x+w/2) << " " << YLOG2DEV(y+h/2) << " "
+           << XLOG2DEVREL(w/2) << " " << XLOG2DEVREL(h/2) << " "
            << int(sa) <<" "<< int(ea) << " false ellipticarc\n";
 
         CalcBoundingBox( x, y );
@@ -534,29 +534,29 @@ void wxPostScriptDC::DrawEllipticArc(long x,long y,long w,long h,double sa,doubl
 void wxPostScriptDC::DrawPoint (long x, long y)
 {
     wxCHECK_RET( m_ok && m_pstream, "invalid postscript dc" );
-    
+
     if (m_pen.GetStyle() == wxTRANSPARENT) return;
-    
+
     SetPen (m_pen);
-    
+
     *m_pstream << "newpath\n"
          << XLOG2DEV(x)   << " " << YLOG2DEV (y) << " moveto\n"
          << XLOG2DEV(x+1) << " " << YLOG2DEV (y) << " lineto\n"
          << "stroke\n";
-    
+
     CalcBoundingBox( x, y );
 }
 
 void wxPostScriptDC::DrawPolygon (int n, wxPoint points[], long xoffset, long yoffset, int WXUNUSED(fillStyle))
 {
     wxCHECK_RET( m_ok && m_pstream, "invalid postscript dc" );
-    
+
     if (n <= 0) return;
-    
+
     if (m_brush.GetStyle () != wxTRANSPARENT)
     {
     SetBrush( m_brush );
-      
+
     *m_pstream << "newpath\n";
 
     long xx = XLOG2DEV(points[0].x + xoffset);
@@ -577,7 +577,7 @@ void wxPostScriptDC::DrawPolygon (int n, wxPoint points[], long xoffset, long yo
     if (m_pen.GetStyle () != wxTRANSPARENT)
     {
     SetPen( m_pen );
-    
+
     *m_pstream << "newpath\n";
 
     long xx = XLOG2DEV(points[0].x + xoffset);
@@ -600,14 +600,14 @@ void wxPostScriptDC::DrawPolygon (int n, wxPoint points[], long xoffset, long yo
 void wxPostScriptDC::DrawLines (int n, wxPoint points[], long xoffset, long yoffset)
 {
     wxCHECK_RET( m_ok && m_pstream, "invalid postscript dc" );
-    
+
     if (m_pen.GetStyle() == wxTRANSPARENT)
         return;
     if (n <= 0)
         return;
-  
+
     SetPen (m_pen);
-    
+
     int i;
     for ( i =0; i<n ; i++ )
     {
@@ -617,20 +617,20 @@ void wxPostScriptDC::DrawLines (int n, wxPoint points[], long xoffset, long yoff
     *m_pstream << "newpath\n"
                << XLOG2DEV(points[0].x+xoffset) << " "
                << YLOG2DEV(points[0].y+yoffset) << " moveto\n";
-         
-    for (i = 1; i < n; i++) 
+
+    for (i = 1; i < n; i++)
     {
         *m_pstream << XLOG2DEV(points[i].x+xoffset) << " "
                    << YLOG2DEV(points[i].y+yoffset) << " lineto\n";
     }
-    
+
     *m_pstream << "stroke\n";
 }
 
 void wxPostScriptDC::DrawRectangle (long x, long y, long width, long height)
 {
     wxCHECK_RET( m_ok && m_pstream, "invalid postscript dc" );
-    
+
     if (m_brush.GetStyle () != wxTRANSPARENT)
     {
         SetBrush( m_brush );
@@ -646,7 +646,7 @@ void wxPostScriptDC::DrawRectangle (long x, long y, long width, long height)
         CalcBoundingBox( x, y );
         CalcBoundingBox( x + width, y + height );
     }
-    
+
     if (m_pen.GetStyle () != wxTRANSPARENT)
     {
         SetPen (m_pen);
@@ -667,7 +667,7 @@ void wxPostScriptDC::DrawRectangle (long x, long y, long width, long height)
 void wxPostScriptDC::DrawRoundedRectangle (long x, long y, long width, long height, double radius)
 {
     wxCHECK_RET( m_ok && m_pstream, "invalid postscript dc" );
-    
+
     if (radius < 0.0)
     {
         // Now, a negative radius is interpreted to mean
@@ -679,13 +679,13 @@ void wxPostScriptDC::DrawRoundedRectangle (long x, long y, long width, long heig
         smallest = height;
         radius =  (-radius * smallest);
     }
-    
+
     long rad = (long) radius;
 
     if (m_brush.GetStyle () != wxTRANSPARENT)
     {
         SetBrush( m_brush );
-    
+
         // Draw rectangle anticlockwise
         *m_pstream << "newpath\n"
                    << XLOG2DEV(x + rad) << " " << YLOG2DEV(y + rad) << " " << XLOG2DEVREL(rad) << " 90 180 arc\n"
@@ -702,11 +702,11 @@ void wxPostScriptDC::DrawRoundedRectangle (long x, long y, long width, long heig
         CalcBoundingBox( x, y );
         CalcBoundingBox( x + width, y + height );
     }
-    
+
     if (m_pen.GetStyle () != wxTRANSPARENT)
     {
         SetPen (m_pen);
-    
+
         // Draw rectangle anticlockwise
         *m_pstream << "newpath\n"
                    << XLOG2DEV(x + rad) << " " << YLOG2DEV(y + rad) << " " << XLOG2DEVREL(rad) << " 90 180 arc\n"
@@ -728,27 +728,27 @@ void wxPostScriptDC::DrawRoundedRectangle (long x, long y, long width, long heig
 void wxPostScriptDC::DrawEllipse (long x, long y, long width, long height)
 {
     wxCHECK_RET( m_ok && m_pstream, "invalid postscript dc" );
-    
+
     if (m_brush.GetStyle () != wxTRANSPARENT)
     {
         SetBrush (m_brush);
 
-        *m_pstream << "newpath\n" 
-                   << XLOG2DEV(x + width / 2) << " " << YLOG2DEV(y + height / 2) << " " 
-                   << XLOG2DEV(width / 2) << " " << YLOG2DEVREL(height / 2) << " 0 360 ellipse\n" 
+        *m_pstream << "newpath\n"
+                   << XLOG2DEV(x + width / 2) << " " << YLOG2DEV(y + height / 2) << " "
+                   << XLOG2DEV(width / 2) << " " << YLOG2DEVREL(height / 2) << " 0 360 ellipse\n"
                    << "fill\n";
 
         CalcBoundingBox( x - width, y - height );
         CalcBoundingBox( x + width, y + height );
     }
-    
+
     if (m_pen.Ok() && m_pen.GetStyle () != wxTRANSPARENT)
     {
         SetPen (m_pen);
 
-        *m_pstream << "newpath\n" 
-                   << XLOG2DEV(x + width / 2) << " " << YLOG2DEV(y + height / 2) << " " 
-                   << XLOG2DEV(width / 2) << " " << YLOG2DEVREL(height / 2) << " 0 360 ellipse\n" 
+        *m_pstream << "newpath\n"
+                   << XLOG2DEV(x + width / 2) << " " << YLOG2DEV(y + height / 2) << " "
+                   << XLOG2DEV(width / 2) << " " << YLOG2DEVREL(height / 2) << " 0 360 ellipse\n"
                    << "stroke\n";
 
         CalcBoundingBox( x - width, y - height );
@@ -766,21 +766,21 @@ void wxPostScriptDC::DrawBitmap( const wxBitmap& bitmap, long x, long y, bool WX
     wxCHECK_RET( m_ok && m_pstream, "invalid postscript dc" );
 
     if (!bitmap.Ok()) return;
-    
+
     wxImage image( bitmap );
-    
+
     if (!image.Ok()) return;
-    
+
     int ww = XLOG2DEVREL(image.GetWidth());
     int hh = YLOG2DEVREL(image.GetHeight());
-    
+
     image = image.Scale( ww, hh );
-    
+
     if (!image.Ok()) return;
-    
+
     int xx = XLOG2DEV(x);
     int yy = YLOG2DEV(y + bitmap.GetHeight());
-    
+
     *m_pstream << "/origstate save def\n"
                << "20 dict begin\n"
                << "/pix " << ww << " string def\n"
@@ -793,7 +793,7 @@ void wxPostScriptDC::DrawBitmap( const wxBitmap& bitmap, long x, long y, bool WX
                << "[" << ww << " 0 0 " << (-hh) << " 0 " << hh << "]\n"
                << "{currentfile pix readhexstring pop}\n"
                << "false 3 colorimage\n";
-  
+
     for (int j = 0; j < hh; j++)
     {
         for (int i = 0; i < ww; i++)
@@ -812,15 +812,15 @@ void wxPostScriptDC::DrawBitmap( const wxBitmap& bitmap, long x, long y, bool WX
 
     *m_pstream << "end\n";
     *m_pstream << "origstate restore\n";
-    
+
 }
 
 void wxPostScriptDC::SetFont( const wxFont& font )
 {
     wxCHECK_RET( m_ok && m_pstream, "invalid postscript dc" );
-    
+
     if (!font.Ok())  return;
-    
+
     m_font = font;
 
     const char *name;
@@ -898,7 +898,7 @@ void wxPostScriptDC::SetFont( const wxFont& font )
     char buf[100];
     strcpy (buf, name);
     strcat (buf, style);
-    
+
     *m_pstream << buf << " reencodeISO def\n";
     *m_pstream << buf << " findfont\n";
     *m_pstream << YLOG2DEVREL(m_font.GetPointSize()) << " scalefont setfont\n";
@@ -907,9 +907,9 @@ void wxPostScriptDC::SetFont( const wxFont& font )
 void wxPostScriptDC::SetPen( const wxPen& pen )
 {
     wxCHECK_RET( m_ok && m_pstream, "invalid postscript dc" );
-    
+
     if (!pen.Ok()) return;
-    
+
     int oldStyle = m_pen.GetStyle();
 
     m_pen = pen;
@@ -918,7 +918,7 @@ void wxPostScriptDC::SetPen( const wxPen& pen )
 
 /*
      Line style - WRONG: 2nd arg is OFFSET
-     
+
      Here, I'm afraid you do not conceive meaning of parameters of 'setdash'
      operator correctly. You should look-up this in the Red Book: the 2nd parame-
      ter is not number of values in the array of the first one, but an offset
@@ -944,7 +944,7 @@ void wxPostScriptDC::SetPen( const wxPen& pen )
         case wxTRANSPARENT:
         default:              psdash = "[] 0";         break;
     }
-    
+
     if (oldStyle != m_pen.GetStyle())
     {
         *m_pstream << psdash << " setdash\n";
@@ -965,7 +965,7 @@ void wxPostScriptDC::SetPen( const wxPen& pen )
         green = (unsigned char) 0;
         blue = (unsigned char) 0;
     }
-    
+
     // setgray here ?
     }
 
@@ -986,9 +986,9 @@ void wxPostScriptDC::SetPen( const wxPen& pen )
 void wxPostScriptDC::SetBrush( const wxBrush& brush )
 {
     wxCHECK_RET( m_ok && m_pstream, "invalid postscript dc" );
-    
+
     if (!brush.Ok()) return;
-    
+
     m_brush = brush;
 
     // Brush colour
@@ -1006,7 +1006,7 @@ void wxPostScriptDC::SetBrush( const wxBrush& brush )
         green = (unsigned char) 255;
         blue = (unsigned char) 255;
     }
-    
+
     // setgray here ?
     }
 
@@ -1025,7 +1025,7 @@ void wxPostScriptDC::SetBrush( const wxBrush& brush )
 void wxPostScriptDC::DrawText( const wxString& text, long x, long y, bool WXUNUSED(use16bit) )
 {
     wxCHECK_RET( m_ok && m_pstream, "invalid postscript dc" );
-    
+
     SetFont( m_font );
 
     if (m_textForegroundColour.Ok ())
@@ -1045,9 +1045,9 @@ void wxPostScriptDC::DrawText( const wxString& text, long x, long y, bool WXUNUS
           blue = (unsigned char) 0;
         }
     }
-    
+
     // maybe setgray here ?
-    
+
         if (!(red == m_currentRed && green == m_currentGreen && blue == m_currentBlue))
         {
             long redPS = (long) (((int) red) / 255.0);
@@ -1065,7 +1065,7 @@ void wxPostScriptDC::DrawText( const wxString& text, long x, long y, bool WXUNUS
 
     long by = y + (long)floor( float(size) * 2.0 / 3.0 ); // approximate baseline
     *m_pstream << XLOG2DEV(x) << " " << YLOG2DEV(by) << " moveto\n";
-    
+
     *m_pstream << "(";
     int len = strlen ((char *)(const char *)text);
     int i;
@@ -1094,14 +1094,14 @@ void wxPostScriptDC::DrawText( const wxString& text, long x, long y, bool WXUNUS
         long uy = (long)(y + size - m_underlinePosition);
         long w, h;
         GetTextExtent(text, &w, &h);
-      
+
         *m_pstream << "gsave " << XLOG2DEV(x) << " " << YLOG2DEV(uy)
                    << " moveto\n"
                    << (long)m_underlineThickness << " setlinewidth "
                    << XLOG2DEV(x + w) << " " << YLOG2DEV(uy)
                    << " lineto stroke grestore\n";
     }
-    
+
     CalcBoundingBox( x, y );
     CalcBoundingBox( x + size * text.Length() * 2/3 , y );
 }
@@ -1120,7 +1120,7 @@ void wxPostScriptDC::SetLogicalFunction (int WXUNUSED(function))
 void wxPostScriptDC::DrawSpline( wxList *points )
 {
     wxCHECK_RET( m_ok && m_pstream, "invalid postscript dc" );
-    
+
     SetPen( m_pen );
 
     double a, b, c, d, x1, y1, x2, y2, x3, y3;
@@ -1128,20 +1128,20 @@ void wxPostScriptDC::DrawSpline( wxList *points )
 
     wxNode *node = points->First();
     p = (wxPoint *)node->Data();
-    x1 = p->x; 
+    x1 = p->x;
     y1 = p->y;
 
     node = node->Next();
     p = (wxPoint *)node->Data();
-    c = p->x; 
+    c = p->x;
     d = p->y;
     x3 = a = (double)(x1 + c) / 2;
     y3 = b = (double)(y1 + d) / 2;
 
-    *m_pstream  << "newpath " 
-                << XLOG2DEV((long)x1) << " " << YLOG2DEV((long)y1) << " moveto " 
+    *m_pstream  << "newpath "
+                << XLOG2DEV((long)x1) << " " << YLOG2DEV((long)y1) << " moveto "
         << XLOG2DEV((long)x3) << " " << YLOG2DEV((long)y3) << " lineto\n";
-        
+
     CalcBoundingBox( (long)x1, (long)y1 );
     CalcBoundingBox( (long)x3, (long)y3 );
 
@@ -1149,22 +1149,22 @@ void wxPostScriptDC::DrawSpline( wxList *points )
     {
         q = (wxPoint *)node->Data();
 
-    x1 = x3; 
+    x1 = x3;
     y1 = y3;
-    x2 = c;  
+    x2 = c;
     y2 = d;
-    c = q->x; 
+    c = q->x;
     d = q->y;
         x3 = (double)(x2 + c) / 2;
         y3 = (double)(y2 + d) / 2;
-        *m_pstream << XLOG2DEV((long)x1) << " " << YLOG2DEV((long)y1) << " " 
+        *m_pstream << XLOG2DEV((long)x1) << " " << YLOG2DEV((long)y1) << " "
                << XLOG2DEV((long)x2) << " " << YLOG2DEV((long)y2) << " "
                    << XLOG2DEV((long)x3) << " " << YLOG2DEV((long)y3) << " DrawSplineSection\n";
 
         CalcBoundingBox( (long)x1, (long)y1 );
         CalcBoundingBox( (long)x3, (long)y3 );
     }
-    
+
 /*
      At this point, (x2,y2) and (c,d) are the position of the
      next-to-last and last point respectively, in the point list
@@ -1183,10 +1183,10 @@ long wxPostScriptDC::GetCharWidth ()
 void wxPostScriptDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
 {
     wxCHECK_RET( m_ok && m_pstream, "invalid postscript dc" );
-    
+
     m_signX = (xLeftRight ? 1 : -1);
     m_signY = (yBottomUp  ? 1 : -1);
-    
+
     // FIXME there is no such function in MSW
 #ifndef __WXMSW__
     ComputeScaleAndOrigin();
@@ -1196,24 +1196,24 @@ void wxPostScriptDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
 void wxPostScriptDC::SetDeviceOrigin( long x, long y )
 {
     wxCHECK_RET( m_ok && m_pstream, "invalid postscript dc" );
-    
+
     int h = 0;
     int w = 0;
     GetSize( &w, &h );
-  
+
     wxDC::SetDeviceOrigin( x, h-y );
 }
 
 void wxPostScriptDC::GetSize(int* width, int* height) const
 {
     const char *paperType = wxThePrintSetupData->GetPaperName();
-    
+
     if (!paperType) paperType = _("A4 210 x 297 mm");
 
     wxPrintPaperType *paper = wxThePrintPaperDatabase->FindPaperType(paperType);
-    
+
     if (!paper) paper = wxThePrintPaperDatabase->FindPaperType(_("A4 210 x 297 mm"));
-    
+
     if (paper)
     {
         if (width) *width = paper->widthPixels;
@@ -1229,7 +1229,7 @@ void wxPostScriptDC::GetSize(int* width, int* height) const
 bool wxPostScriptDC::StartDoc (const wxString& message)
 {
     wxCHECK_MSG( m_ok, FALSE, "invalid postscript dc" );
-    
+
     if (m_filename == "")
     {
         m_filename = wxGetTempFileName("ps");
@@ -1242,14 +1242,14 @@ bool wxPostScriptDC::StartDoc (const wxString& message)
     }
 
     m_pstream = new ofstream (wxThePrintSetupData->GetPrinterFile());
-      
+
     if (!m_pstream || !m_pstream->good())
     {
     wxMessageBox (_("Cannot open file!"), _("Error"), wxOK);
     m_ok = FALSE;
     return FALSE;
     }
-    
+
     m_ok = TRUE;
 
     SetBrush( *wxBLACK_BRUSH );
@@ -1259,7 +1259,7 @@ bool wxPostScriptDC::StartDoc (const wxString& message)
 
     // set origin according to paper size
     SetDeviceOrigin( 0,0 );
-    
+
     wxPageNumber = 1;
     m_pageNumber = 1;
     m_title = message;
@@ -1269,7 +1269,7 @@ bool wxPostScriptDC::StartDoc (const wxString& message)
 void wxPostScriptDC::EndDoc ()
 {
     wxCHECK_RET( m_ok && m_pstream, "invalid postscript dc" );
-    
+
     if (m_clipping)
     {
         m_clipping = FALSE;
@@ -1283,7 +1283,7 @@ void wxPostScriptDC::EndDoc ()
     }
 
     char *header_file = wxGetTempFileName("ps");
-    
+
     m_pstream = new ofstream( header_file );
 
     *m_pstream << "%!PS-Adobe-2.0\n";   /* PostScript magic strings */
@@ -1427,9 +1427,9 @@ void wxPostScriptDC::EndDoc ()
 void wxPostScriptDC::StartPage ()
 {
     wxCHECK_RET( m_ok && m_pstream, "invalid postscript dc" );
-    
+
     *m_pstream << "%%Page: " << (wxPageNumber++) << "\n";
-    
+
 //  *m_pstream << "matrix currentmatrix\n";
 
     // Added by Chris Breeze
@@ -1437,48 +1437,48 @@ void wxPostScriptDC::StartPage ()
     // Each page starts with an "initgraphics" which resets the
     // transformation and so we need to reset the origin
     // (and rotate the page for landscape printing)
-    
+
 /*
     m_scaleFactor = 1.0;
     m_logicalOriginX = 0;
     m_logicalOriginY = 0;
 */
-       // Output scaling
-       long translate_x, translate_y;
-       double scale_x, scale_y;
-       wxThePrintSetupData->GetPrinterTranslation(&translate_x, &translate_y);
-       wxThePrintSetupData->GetPrinterScaling(&scale_x, &scale_y);
+    // Output scaling
+    long translate_x, translate_y;
+    double scale_x, scale_y;
+    wxThePrintSetupData->GetPrinterTranslation(&translate_x, &translate_y);
+    wxThePrintSetupData->GetPrinterScaling(&scale_x, &scale_y);
 
-       if (wxThePrintSetupData->GetPrinterOrientation() == PS_LANDSCAPE)
-       {
-               translate_y -= m_maxY;
-               *m_pstream << "90 rotate\n";
-       }
+    if (wxThePrintSetupData->GetPrinterOrientation() == PS_LANDSCAPE)
+    {
+        translate_y -= m_maxY;
+        *m_pstream << "90 rotate\n";
+    }
 
-       *m_pstream << scale_x << " " << scale_y << " scale\n";
-       *m_pstream << translate_x << " " << translate_y << " translate\n";
+    *m_pstream << scale_x << " " << scale_y << " scale\n";
+    *m_pstream << translate_x << " " << translate_y << " translate\n";
 }
 
 void wxPostScriptDC::EndPage ()
 {
     wxCHECK_RET( m_ok && m_pstream, "invalid postscript dc" );
-    
+
     *m_pstream << "showpage\n";
 }
 
-bool wxPostScriptDC::Blit( long xdest, long ydest, 
+bool wxPostScriptDC::Blit( long xdest, long ydest,
                            long fwidth, long fheight,
-                           wxDC *source, 
-                           long xsrc, long ysrc, 
+                           wxDC *source,
+                           long xsrc, long ysrc,
                            int rop, bool WXUNUSED(useMask) )
 {
     wxCHECK_MSG( m_ok && m_pstream, FALSE, "invalid postscript dc" );
-    
+
     wxCHECK_MSG( source, FALSE, "invalid source dc" );
-    
+
     /* blit into a bitmap */
-  
-    wxBitmap bitmap( fwidth, fheight );
+
+    wxBitmap bitmap( (int)fwidth, (int)fheight );
     wxMemoryDC memDC;
     memDC.SelectObject(bitmap);
     memDC.Blit(0, 0, fwidth, fheight, source, xsrc, ysrc, rop); /* TODO: Blit transparently? */
@@ -1487,7 +1487,7 @@ bool wxPostScriptDC::Blit( long xdest, long ydest,
     /* draw bitmap. scaling and positioning is done there */
 
     DrawBitmap( bitmap, xdest, ydest );
-    
+
     return TRUE;
 }
 
@@ -1504,7 +1504,7 @@ void wxPostScriptDC::GetTextExtent( const wxString& string, long *x, long *y,
                                     bool WXUNUSED(use16) )
 {
     wxFont *fontToUse = theFont;
-  
+
     if (!fontToUse) fontToUse = (wxFont*) &m_font;
 
     wxCHECK_RET( fontToUse, "GetTextExtent: no font defined" );
@@ -1515,55 +1515,55 @@ void wxPostScriptDC::GetTextExtent( const wxString& string, long *x, long *y,
     /* Provide a VERY rough estimate (avoid using it).
      * Produces accurate results for mono-spaced font
      * such as Courier (aka wxMODERN) */
-     
+
     int height = 12;
     if (fontToUse)
     {
-       height = fontToUse->GetPointSize();
+        height = fontToUse->GetPointSize();
     }
     *x = strlen (string) * height * 72 / 120;
-    *y = (long) (height * 1.32);       /* allow for descender */
+    *y = (long) (height * 1.32);    /* allow for descender */
     if (descent) *descent = 0;
     if (externalLeading) *externalLeading = 0;
 #else
 
-   /* method for calculating string widths in postscript:
-   /  read in the AFM (adobe font metrics) file for the
-   /  actual font, parse it and extract the character widths
-   /  and also the descender. this may be improved, but for now
-   /  it works well. the AFM file is only read in if the
-   /  font is changed. this may be chached in the future.
-   /  calls to GetTextExtent with the font unchanged are rather
-   /  efficient!!!
-   /
-   /  for each font and style used there is an AFM file necessary.
-   /  currently i have only files for the roman font family.
-   /  I try to get files for the other ones!
-   /
-   /  CAVE: the size of the string is currently always calculated
-   /        in 'points' (1/72 of an inch). this should later on be
-   /        changed to depend on the mapping mode.
-   /  CAVE: the path to the AFM files must be set before calling this
-   /        function. this is usually done by a call like the following:
-   /        wxSetAFMPath("d:\\wxw161\\afm\\");
-   /
-   /  example:
-   /
-   /    wxPostScriptDC dc(NULL, TRUE);
-   /    if (dc.Ok()){
-   /      wxSetAFMPath("d:\\wxw161\\afm\\");
-   /      dc.StartDoc("Test");
-   /      dc.StartPage();
-   /      long w,h;
-   /      dc.SetFont(new wxFont(10, wxROMAN, wxNORMAL, wxNORMAL));
-   /      dc.GetTextExtent("Hallo",&w,&h);
-   /      dc.EndPage();
-   /      dc.EndDoc();
-   /    }
-   /
-   /  by steve (stefan.hammes@urz.uni-heidelberg.de)
-   /  created: 10.09.94
-   /  updated: 14.05.95 */
+    /* method for calculating string widths in postscript:
+    /  read in the AFM (adobe font metrics) file for the
+    /  actual font, parse it and extract the character widths
+    /  and also the descender. this may be improved, but for now
+    /  it works well. the AFM file is only read in if the
+    /  font is changed. this may be chached in the future.
+    /  calls to GetTextExtent with the font unchanged are rather
+    /  efficient!!!
+    /
+    /  for each font and style used there is an AFM file necessary.
+    /  currently i have only files for the roman font family.
+    /  I try to get files for the other ones!
+    /
+    /  CAVE: the size of the string is currently always calculated
+    /        in 'points' (1/72 of an inch). this should later on be
+    /        changed to depend on the mapping mode.
+    /  CAVE: the path to the AFM files must be set before calling this
+    /        function. this is usually done by a call like the following:
+    /        wxSetAFMPath("d:\\wxw161\\afm\\");
+    /
+    /  example:
+    /
+    /    wxPostScriptDC dc(NULL, TRUE);
+    /    if (dc.Ok()){
+    /      wxSetAFMPath("d:\\wxw161\\afm\\");
+    /      dc.StartDoc("Test");
+    /      dc.StartPage();
+    /      long w,h;
+    /      dc.SetFont(new wxFont(10, wxROMAN, wxNORMAL, wxNORMAL));
+    /      dc.GetTextExtent("Hallo",&w,&h);
+    /      dc.EndPage();
+    /      dc.EndDoc();
+    /    }
+    /
+    /  by steve (stefan.hammes@urz.uni-heidelberg.de)
+    /  created: 10.09.94
+    /  updated: 14.05.95 */
 
     /* these static vars are for storing the state between calls */
     static int lastFamily= INT_MIN;
@@ -1591,51 +1591,51 @@ void wxPostScriptDC::GetTextExtent( const wxString& string, long *x, long *y,
         char *name = (char*) NULL;
 
         switch (Family)
-       {
-           case wxMODERN:
-           {
-                    if ((Style == wxITALIC) && (Weight == wxBOLD)) name = "CourBoO";
-               else if ((Style != wxITALIC) && (Weight == wxBOLD)) name = "CourBo";
-               else if ((Style == wxITALIC) && (Weight != wxBOLD)) name = "Cour0";
-               else name = "Cour";
-           }
-           break;
-           case wxROMAN:
-           {
-                    if ((Style == wxITALIC) && (Weight == wxBOLD)) name = "TimesBoO";
-               else if ((Style != wxITALIC) && (Weight == wxBOLD)) name = "TimesBo";
-               else if ((Style == wxITALIC) && (Weight != wxBOLD)) name = "TimesO";
-               else if name = "TimesRo";  /* no typo */
-           }
-           break;
-           default:
-           {
-                    if ((Style == wxITALIC) && (Weight == wxBOLD)) name = "HelvBoO";
-               else if ((Style != wxITALIC) && (Weight == wxBOLD)) name = "HelvBo";
-               else if ((Style == wxITALIC) && (Weight != wxBOLD)) name = "Helv0";
-               else name = "Helv";
-           }
-           break;
-       }
+        {
+            case wxMODERN:
+                {
+                    if ((Style == wxITALIC) && (Weight == wxBOLD)) name = "CourBoO";
+                    else if ((Style != wxITALIC) && (Weight == wxBOLD)) name = "CourBo";
+                    else if ((Style == wxITALIC) && (Weight != wxBOLD)) name = "Cour0";
+                    else name = "Cour";
+                }
+                break;
+            case wxROMAN:
+                {
+                    if ((Style == wxITALIC) && (Weight == wxBOLD)) name = "TimesBoO";
+                    else if ((Style != wxITALIC) && (Weight == wxBOLD)) name = "TimesBo";
+                    else if ((Style == wxITALIC) && (Weight != wxBOLD)) name = "TimesO";
+                    else if name = "TimesRo";  /* no typo */
+                }
+                break;
+            default:
+                {
+                    if ((Style == wxITALIC) && (Weight == wxBOLD)) name = "HelvBoO";
+                    else if ((Style != wxITALIC) && (Weight == wxBOLD)) name = "HelvBo";
+                    else if ((Style == wxITALIC) && (Weight != wxBOLD)) name = "Helv0";
+                    else name = "Helv";
+                }
+                break;
+        }
 
         /* get the directory of the AFM files */
         char afmName[256];
         afmName[0] = 0;
         if (wxGetAFMPath()) strcpy( afmName, wxGetAFMPath() );
 
-    /* 2. open and process the file
-    /  a short explanation of the AFM format:
-    /  we have for each character a line, which gives its size
-    /  e.g.:
-    / 
-    /    C 63 ; WX 444 ; N question ; B 49 -14 395 676 ;
-    / 
-    /  that means, we have a character with ascii code 63, and width
-    /  (444/1000 * fontSize) points.
-    /  the other data is ignored for now!
-    / 
-    /  when the font has changed, we read in the right AFM file and store the
-    /  character widths in an array, which is processed below (see point 3.). */
+        /* 2. open and process the file
+           /  a short explanation of the AFM format:
+           /  we have for each character a line, which gives its size
+           /  e.g.:
+           /
+           /    C 63 ; WX 444 ; N question ; B 49 -14 395 676 ;
+           /
+           /  that means, we have a character with ascii code 63, and width
+           /  (444/1000 * fontSize) points.
+           /  the other data is ignored for now!
+           /
+           /  when the font has changed, we read in the right AFM file and store the
+           /  character widths in an array, which is processed below (see point 3.). */
 
         /* new elements JC Sun Aug 25 23:21:44 MET DST 1996 */
 
@@ -1649,8 +1649,8 @@ void wxPostScriptDC::GetTextExtent( const wxString& string, long *x, long *y,
             for (int i=0; i<256; i++) lastWidths[i] = 500; /* an approximate value */
             lastDescender = -150; /* dito. */
         }
-       else
-       {
+        else
+        {
             /* init the widths array */
             for(int i=0; i<256; i++) lastWidths[i] = INT_MIN;
             /* some variables for holding parts of a line */
@@ -1660,67 +1660,67 @@ void wxPostScriptDC::GetTextExtent( const wxString& string, long *x, long *y,
             int ascii,cWidth;
             /* read in the file and parse it */
             while(fgets(line,sizeof(line),afmFile)!=NULL)
-           {
+            {
                 /* A.) check for descender definition */
                 if (strncmp(line,"Descender",9)==0)
-               {
+                {
                     if ((sscanf(line,"%s%d",descString,&lastDescender)!=2) ||
-                       (strcmp(descString,"Descender")!=0)) 
-                   {
-                       wxLogDebug( "AFM-file '%s': line '%s' has error (bad descender)\n", afmName,line );
+                            (strcmp(descString,"Descender")!=0))
+                    {
+                        wxLogDebug( "AFM-file '%s': line '%s' has error (bad descender)\n", afmName,line );
                     }
                 }
                 /* JC 1.) check for UnderlinePosition */
                 else if(strncmp(line,"UnderlinePosition",17)==0)
-               {
+                {
                     if ((sscanf(line,"%s%lf",upString,&UnderlinePosition)!=2) ||
-                       (strcmp(upString,"UnderlinePosition")!=0)) 
-                   {
-                       wxLogDebug( "AFM-file '%s': line '%s' has error (bad UnderlinePosition)\n", afmName, line );
+                            (strcmp(upString,"UnderlinePosition")!=0))
+                    {
+                        wxLogDebug( "AFM-file '%s': line '%s' has error (bad UnderlinePosition)\n", afmName, line );
                     }
                 }
-               /* JC 2.) check for UnderlineThickness */
+                /* JC 2.) check for UnderlineThickness */
                 else if(strncmp(line,"UnderlineThickness",18)==0)
-               {
+                {
                     if ((sscanf(line,"%s%lf",utString,&UnderlineThickness)!=2) ||
-                       (strcmp(utString,"UnderlineThickness")!=0)) 
-                   {
-                       wxLogDebug( "AFM-file '%s': line '%s' has error (bad UnderlineThickness)\n", afmName, line );
+                            (strcmp(utString,"UnderlineThickness")!=0))
+                    {
+                        wxLogDebug( "AFM-file '%s': line '%s' has error (bad UnderlineThickness)\n", afmName, line );
                     }
                 }
-               /* JC 3.) check for EncodingScheme */
+                /* JC 3.) check for EncodingScheme */
                 else if(strncmp(line,"EncodingScheme",14)==0)
-               {
+                {
                     if ((sscanf(line,"%s%s",utString,encString)!=2) ||
-                       (strcmp(utString,"EncodingScheme")!=0)) 
-                   {
-                       wxLogDebug("AFM-file '%s': line '%s' has error (bad EncodingScheme)\n", afmName, line );
+                            (strcmp(utString,"EncodingScheme")!=0))
+                    {
+                        wxLogDebug("AFM-file '%s': line '%s' has error (bad EncodingScheme)\n", afmName, line );
                     }
                     else if (strncmp(encString, "AdobeStandardEncoding", 21))
                     {
-                       wxLogDebug( "AFM-file '%s': line '%s' has error (unsupported EncodingScheme %s)\n",
-                                   afmName,line, encString);
+                        wxLogDebug( "AFM-file '%s': line '%s' has error (unsupported EncodingScheme %s)\n",
+                                afmName,line, encString);
                     }
                 }
                 /* B.) check for char-width */
                 else if(strncmp(line,"C ",2)==0)
-               {
+                {
                     if (sscanf(line,"%s%d%s%s%d",cString,&ascii,semiString,WXString,&cWidth)!=5)
-                   {
+                    {
                         wxLogDebug("AFM-file '%s': line '%s' has an error (bad character width)\n",afmName,line);
                     }
                     if(strcmp(cString,"C")!=0 || strcmp(semiString,";")!=0 || strcmp(WXString,"WX")!=0)
-                   {
+                    {
                         wxLogDebug("AFM-file '%s': line '%s' has a format error\n",afmName,line);
                     }
                     /* printf("            char '%c'=%d has width '%d'\n",ascii,ascii,cWidth); */
                     if (ascii>=0 && ascii<256)
-                   {
+                    {
                         lastWidths[ascii] = cWidth; /* store width */
                     }
-                   else
-                   {
-                       /* MATTHEW: this happens a lot; don't print an error */
+                    else
+                    {
+                        /* MATTHEW: this happens a lot; don't print an error */
                         /* wxLogDebug("AFM-file '%s': ASCII value %d out of range\n",afmName,ascii); */
                     }
                 }
@@ -1729,9 +1729,9 @@ void wxPostScriptDC::GetTextExtent( const wxString& string, long *x, long *y,
             fclose(afmFile);
         }
         /* hack to compute correct values for german 'Umlaute'
-        /  the correct way would be to map the character names
-        /  like 'adieresis' to corresp. positions of ISOEnc and read
-        /  these values from AFM files, too. Maybe later ... */
+           /  the correct way would be to map the character names
+           /  like 'adieresis' to corresp. positions of ISOEnc and read
+           /  these values from AFM files, too. Maybe later ... */
         lastWidths[196] = lastWidths['A'];  // Ã„
         lastWidths[228] = lastWidths['a'];  // Ã¤
         lastWidths[214] = lastWidths['O'];  // Ã–
@@ -1746,8 +1746,8 @@ void wxPostScriptDC::GetTextExtent( const wxString& string, long *x, long *y,
     m_underlineThickness = m_underlineThickness * fontToUse->GetPointSize() / 1000.0f * m_scaleFactor;
 
     /* 3. now the font metrics are read in, calc size this
-    /  is done by adding the widths of the characters in the
-    /  string. they are given in 1/1000 of the size! */
+       /  is done by adding the widths of the characters in the
+       /  string. they are given in 1/1000 of the size! */
 
     long widthSum=0;
     long height=Size; /* by default */
@@ -1755,16 +1755,16 @@ void wxPostScriptDC::GetTextExtent( const wxString& string, long *x, long *y,
     for(p=(unsigned char *)(const char *)string; *p; p++)
     {
         if(lastWidths[*p]== INT_MIN)
-       {
+        {
             wxLogDebug("GetTextExtent: undefined width for character '%c' (%d)\n", *p,*p);
             widthSum += (long)(lastWidths[' ']/1000.0F * Size); /* assume space */
         }
-       else
-       {
+        else
+        {
             widthSum += (long)((lastWidths[*p]/1000.0F)*Size);
         }
     }
-    
+
     /* add descender to height (it is usually a negative value) */
     if (lastDescender!=INT_MIN)
     {
@@ -1779,12 +1779,12 @@ void wxPostScriptDC::GetTextExtent( const wxString& string, long *x, long *y,
     if (descent)
     {
         if(lastDescender!=INT_MIN)
-       {
+        {
             *descent = (long)(((-lastDescender)/1000.0F) * Size); /* MATTHEW: forgot scale */
         }
-       else
-       {
-           *descent = 0;
+        else
+        {
+            *descent = 0;
         }
     }
 
@@ -1797,13 +1797,13 @@ void wxPostScriptDC::GetTextExtent( const wxString& string, long *x, long *y,
 void wxPostScriptDC::GetSizeMM(long *width, long *height) const
 {
     const char *paperType = wxThePrintSetupData->GetPaperName();
-  
+
     if (!paperType) paperType = _("A4 210 x 297 mm");
 
     wxPrintPaperType *paper = wxThePrintPaperDatabase->FindPaperType(paperType);
-    
+
     if (!paper) paper = wxThePrintPaperDatabase->FindPaperType(_("A4 210 x 297 mm"));
-    
+
     if (paper)
     {
         if (width) *width = paper->widthMM;
@@ -1869,7 +1869,7 @@ wxPostScriptPrintDialog::wxPostScriptPrintDialog (wxWindow *parent, const wxStri
    print_modes[2] = _("Preview Only");
 
 
-  
+
    wxButton *okBut = new wxButton (this, wxID_OK, _("OK"), wxPoint(5, 5));
    (void) new wxButton (this, wxID_CANCEL, _("Cancel"), wxPoint(40, 5));
    okBut->SetDefault();
@@ -1901,12 +1901,12 @@ wxPostScriptPrintDialog::wxPostScriptPrintDialog (wxWindow *parent, const wxStri
    wxGetResource ("wxWindows", "PSView", &wxThePrintSetupData->previewCommand);
 
    features = (wxThePrintSetupData->GetPrintPreviewCommand() &&
-               *wxThePrintSetupData->GetPrintPreviewCommand()) ? 3 : 2; 
-  
+               *wxThePrintSetupData->GetPrintPreviewCommand()) ? 3 : 2;
+
    wxRadioBox *radio1 = new wxRadioBox(this, wxID_PRINTER_MODES, _("PostScript:"),
                                        wxPoint(150, yPos),
                                        wxSize(-1,-1), features,
-                                       print_modes, features, wxRA_SPECIFY_ROWS); 
+                                       print_modes, features, wxRA_SPECIFY_ROWS);
 
 #ifdef __WXMSW__
    radio1->Enable(0, FALSE);
@@ -1937,7 +1937,7 @@ wxPostScriptPrintDialog::wxPostScriptPrintDialog (wxWindow *parent, const wxStri
    (void) new wxStaticText(this, -1, _("Y Translation"), wxPoint(220, yPos));
    sprintf (buf, "%.2ld", wx_printer_translate_y);
    /* wxTextCtrl *text4 = */ (void) new wxTextCtrl(this, wxID_PRINTER_Y_TRANS, buf, wxPoint(320, yPos), wxSize(100, -1));
-  
+
    Fit ();
 
    delete[] orientation;
index 96d7af417a3904bcd5958de6dc7be953ec9a08f8..e0b042cff0ef36a9977c9057c50845392de733fd 100644 (file)
@@ -1,99 +1,74 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        thread.cpp
-// Purpose:     wxThread Implementation for Posix threads
+// Name:        threadpsx.cpp
+// Purpose:     wxThread (Posix) Implementation
 // Author:      Original from Wolfram Gloger/Guilhem Lavaux
-// Modified by: Robert Roebling
+// Modified by:
 // Created:     04/22/98
 // RCS-ID:      $Id$
-// Copyright:   (c) Wolfram Gloger (1996, 1997); Guilhem Lavaux (1998)
+// Copyright:   (c) Wolfram Gloger (1996, 1997)
+//                  Guilhem Lavaux (1998)
+//                  Robert Roebling (1999)
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 #ifdef __GNUG__
-#pragma implementation "thread.h"
+    #pragma implementation "thread.h"
 #endif
 
-#include "wx/defs.h"
-
-#if wxUSE_THREADS
-
-#include "wx/module.h"
-#include "wx/thread.h"
-#include "wx/utils.h"
-#include "wx/log.h"
-
 #include <stdio.h>
 #include <unistd.h>
 #include <pthread.h>
 #include <errno.h>
 
-#include <stdio.h>
-#include <unistd.h>
-
-// for select()
-#include <sys/time.h>
-#include <sys/types.h>
-#ifdef __sgi
-#include <bstring.h>
+#ifdef __linux__
+    #include <sched.h>
 #endif
 
-//--------------------------------------------------------------------
-// constants
-//--------------------------------------------------------------------
+#include "wx/thread.h"
+#include "wx/module.h"
+#include "wx/utils.h"
+#include "wx/log.h"
+#include "wx/intl.h"
+#include "wx/dynarray.h"
 
-enum thread_state 
+enum thread_state
 {
-  STATE_IDLE = 0,
-  STATE_RUNNING,
-  STATE_PAUSING,
-  STATE_PAUSED,
-  STATE_CANCELED,
-  STATE_EXITED
+    STATE_NEW,          // didn't start execution yet (=> RUNNING)
+    STATE_RUNNING,
+    STATE_PAUSED,
+    STATE_CANCELED,
+    STATE_EXITED
 };
 
-//--------------------------------------------------------------------
-// global data
-//--------------------------------------------------------------------
-
-static pthread_t p_mainid;
-
-wxMutex *wxMainMutex = (wxMutex*) NULL; /* controls access to all GUI functions */
+WX_DEFINE_ARRAY(wxThread *, wxArrayThread);
 
-/* TODO for Xt */
+// -----------------------------------------------------------------------------
+// global data
+// -----------------------------------------------------------------------------
 
-static int p_thrd_pipe[2] = { -1, -1 };
+// we keep the list of all threads created by the application to be able to
+// terminate them on exit if there are some left - otherwise the process would
+// be left in memory
+static wxArrayThread gs_allThreads;
 
-//-------------------------------------------------------------------------
-// global functions
-//-------------------------------------------------------------------------
+// the id of the main thread
+static pthread_t gs_tidMain;
 
-static void wxThreadGuiInit()
-{
-/* TODO for Xt */
-}
+// the key for the pointer to the associated wxThread object
+static pthread_key_t gs_keySelf;
 
-static void wxThreadGuiExit()
-{
-/* TODO for Xt */
-}
+// this mutex must be acquired before any call to a GUI function
+static wxMutex *gs_mutexGui;
 
-void wxMutexGuiEnter()
-{
-  if (wxMainMutex)
-    wxMainMutex->Lock();
-}
-
-void wxMutexGuiLeave()
-{
-  if (wxMainMutex)
-    wxMainMutex->Unlock();
-}
+//--------------------------------------------------------------------
+// common GUI thread code
+//--------------------------------------------------------------------
 
 //--------------------------------------------------------------------
 // wxMutex (Posix implementation)
 //--------------------------------------------------------------------
 
-class wxMutexInternal 
+class wxMutexInternal
 {
 public:
   pthread_mutex_t p_mutex;
@@ -102,55 +77,67 @@ public:
 wxMutex::wxMutex()
 {
     p_internal = new wxMutexInternal;
-    pthread_mutex_init(&(p_internal->p_mutex), NULL);
+    pthread_mutex_init( &(p_internal->p_mutex), (const pthread_mutexattr_t*) NULL );
     m_locked = 0;
 }
 
 wxMutex::~wxMutex()
 {
     if (m_locked > 0)
-        wxLogDebug( "wxMutex warning: freeing a locked mutex (%d locks)\n", m_locked );
+        wxLogDebug("Freeing a locked mutex (%d locks)", m_locked);
 
-    pthread_mutex_destroy(&(p_internal->p_mutex));
+    pthread_mutex_destroy( &(p_internal->p_mutex) );
     delete p_internal;
 }
 
 wxMutexError wxMutex::Lock()
 {
-    int err;
-
-    err = pthread_mutex_lock(&(p_internal->p_mutex));
+    int err = pthread_mutex_lock( &(p_internal->p_mutex) );
     if (err == EDEADLK)
+    {
+        wxLogDebug("Locking this mutex would lead to deadlock!");
+
         return wxMUTEX_DEAD_LOCK;
-       
+    }
+
     m_locked++;
+
     return wxMUTEX_NO_ERROR;
 }
 
 wxMutexError wxMutex::TryLock()
 {
-    int err;
-
     if (m_locked)
+    {
         return wxMUTEX_BUSY;
-       
-    err = pthread_mutex_trylock(&(p_internal->p_mutex));
-    switch (err) 
+    }
+
+    int err = pthread_mutex_trylock( &(p_internal->p_mutex) );
+    switch (err)
     {
         case EBUSY: return wxMUTEX_BUSY;
     }
+
     m_locked++;
+
     return wxMUTEX_NO_ERROR;
 }
 
 wxMutexError wxMutex::Unlock()
 {
     if (m_locked > 0)
+    {
         m_locked--;
+    }
     else
+    {
+        wxLogDebug("Unlocking not locked mutex.");
+
         return wxMUTEX_UNLOCKED;
-       
-    pthread_mutex_unlock(&(p_internal->p_mutex));
+    }
+
+    pthread_mutex_unlock( &(p_internal->p_mutex) );
+
     return wxMUTEX_NO_ERROR;
 }
 
@@ -158,7 +145,7 @@ wxMutexError wxMutex::Unlock()
 // wxCondition (Posix implementation)
 //--------------------------------------------------------------------
 
-class wxConditionInternal 
+class wxConditionInternal
 {
 public:
   pthread_cond_t p_condition;
@@ -167,251 +154,533 @@ public:
 wxCondition::wxCondition()
 {
     p_internal = new wxConditionInternal;
-    pthread_cond_init(&(p_internal->p_condition), NULL);
+    pthread_cond_init( &(p_internal->p_condition), (const pthread_condattr_t *) NULL );
 }
 
 wxCondition::~wxCondition()
 {
-    pthread_cond_destroy(&(p_internal->p_condition));
+    pthread_cond_destroy( &(p_internal->p_condition) );
+
     delete p_internal;
 }
 
 void wxCondition::Wait(wxMutex& mutex)
 {
-    pthread_cond_wait(&(p_internal->p_condition), &(mutex.p_internal->p_mutex));
+    pthread_cond_wait( &(p_internal->p_condition), &(mutex.p_internal->p_mutex) );
 }
 
 bool wxCondition::Wait(wxMutex& mutex, unsigned long sec, unsigned long nsec)
 {
     struct timespec tspec;
 
-    tspec.tv_sec = time(NULL)+sec;
+    tspec.tv_sec = time(0L)+sec;
     tspec.tv_nsec = nsec;
     return (pthread_cond_timedwait(&(p_internal->p_condition), &(mutex.p_internal->p_mutex), &tspec) != ETIMEDOUT);
 }
 
 void wxCondition::Signal()
 {
-    pthread_cond_signal(&(p_internal->p_condition));
+    pthread_cond_signal( &(p_internal->p_condition) );
 }
 
 void wxCondition::Broadcast()
 {
-    pthread_cond_broadcast(&(p_internal->p_condition));
+    pthread_cond_broadcast( &(p_internal->p_condition) );
 }
 
 //--------------------------------------------------------------------
 // wxThread (Posix implementation)
 //--------------------------------------------------------------------
 
-class wxThreadInternal 
+class wxThreadInternal
 {
 public:
-  wxThreadInternal() { state = STATE_IDLE; }
-  ~wxThreadInternal() {}
-  static void *PthreadStart(void *ptr);
-  pthread_t thread_id;
-  int state;
-  int prio;
-  int defer_destroy;
+    wxThreadInternal();
+    ~wxThreadInternal();
+
+    // thread entry function
+    static void *PthreadStart(void *ptr);
+
+    // thread actions
+        // start the thread
+    wxThreadError Run();
+        // ask the thread to terminate
+    void Cancel();
+        // wake up threads waiting for our termination
+    void SignalExit();
+        // go to sleep until Resume() is called
+    void Pause();
+        // resume the thread
+    void Resume();
+
+    // accessors
+        // priority
+    int GetPriority() const { return m_prio; }
+    void SetPriority(int prio) { m_prio = prio; }
+        // state
+    thread_state GetState() const { return m_state; }
+    void SetState(thread_state state) { m_state = state; }
+        // id
+    pthread_t GetId() const { return thread_id; }
+        // "cancelled" flag
+    bool WasCancelled() const { return m_cancelled; }
+
+//private: -- should be!
+    pthread_t thread_id;
+
+private:
+    thread_state m_state;    // see thread_state enum
+    int          m_prio;     // in wxWindows units: from 0 to 100
+
+    // set when the thread should terminate
+    bool m_cancelled;
+
+    // this (mutex, cond) pair is used to synchronize the main thread and this
+    // thread in several situations:
+    //  1. The thread function blocks until condition is signaled by Run() when
+    //     it's initially created - this allows create thread in "suspended"
+    //     state
+    //  2. The Delete() function blocks until the condition is signaled when the
+    //     thread exits.
+    wxMutex     m_mutex;
+    wxCondition m_cond;
+
+    // another (mutex, cond) pair for Pause()/Resume() usage
+    //
+    // VZ: it's possible that we might reuse the mutex and condition from above
+    //     for this too, but as I'm not at all sure that it won't create subtle
+    //     problems with race conditions between, say, Pause() and Delete() I
+    //     prefer this may be a bit less efficient but much safer solution
+    wxMutex     m_mutexSuspend;
+    wxCondition m_condSuspend;
 };
 
 void *wxThreadInternal::PthreadStart(void *ptr)
 {
     wxThread *thread = (wxThread *)ptr;
+    wxThreadInternal *pthread = thread->p_internal;
 
-    // Call the main entry
-    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+    if ( pthread_setspecific(gs_keySelf, thread) != 0 )
+    {
+        wxLogError(_("Can not start thread: error writing TLS."));
+
+        return (void *)-1;
+    }
+
+    // wait for the condition to be signaled from Run()
+    // mutex state: currently locked by the thread which created us
+    pthread->m_cond.Wait(pthread->m_mutex);
+
+    // mutex state: locked again on exit of Wait()
+
+    // call the main entry
     void* status = thread->Entry();
 
+    // terminate the thread
     thread->Exit(status);
 
+    wxFAIL_MSG("wxThread::Exit() can't return.");
+
     return NULL;
 }
 
-wxThreadError wxThread::Create()
+wxThreadInternal::wxThreadInternal()
 {
-    pthread_attr_t a;
-    int min_prio, max_prio, p;
-    struct sched_param sp;
+    m_state = STATE_NEW;
+    m_cancelled = FALSE;
 
-    if (p_internal->state != STATE_IDLE)
-        return wxTHREAD_RUNNING;
+    // this mutex is locked during almost all thread lifetime - it will only be
+    // unlocked in the very end
+    m_mutex.Lock();
 
-    // Change thread priority
-    pthread_attr_init(&a);
-    pthread_attr_getschedpolicy(&a, &p);
+    // this mutex is used in Pause()/Resume() and is also locked all the time
+    // unless the thread is paused
+    m_mutexSuspend.Lock();
+}
 
-    min_prio = sched_get_priority_min(p);
-    max_prio = sched_get_priority_max(p);
+wxThreadInternal::~wxThreadInternal()
+{
+    m_mutexSuspend.Unlock();
 
-    pthread_attr_getschedparam(&a, &sp);
-    sp.sched_priority = min_prio +
-               (p_internal->prio*(max_prio-min_prio))/100;
-    pthread_attr_setschedparam(&a, &sp);
+    // note that m_mutex will be unlocked by the thread which waits for our
+    // termination
+}
 
-    // this is the point of no return
-    p_internal->state = STATE_RUNNING;
-    if (pthread_create(&p_internal->thread_id, &a,
-                     wxThreadInternal::PthreadStart, (void *)this) != 0) 
-    {
-        p_internal->state = STATE_IDLE;
-        pthread_attr_destroy(&a);
-        return wxTHREAD_NO_RESOURCE;
-    }
-    pthread_attr_destroy(&a);
+wxThreadError wxThreadInternal::Run()
+{
+    wxCHECK_MSG( GetState() == STATE_NEW, wxTHREAD_RUNNING,
+                 "thread may only be started once after successful Create()" );
+
+    // the mutex was locked on Create(), so we will be able to lock it again
+    // only when the thread really starts executing and enters the wait -
+    // otherwise we might signal the condition before anybody is waiting for it
+    wxMutexLocker lock(m_mutex);
+    m_cond.Signal();
+
+    m_state = STATE_RUNNING;
 
     return wxTHREAD_NO_ERROR;
+
+    // now the mutex is unlocked back - but just to allow Wait() function to
+    // terminate by relocking it, so the net result is that the worker thread
+    // starts executing and the mutex is still locked
+}
+
+void wxThreadInternal::Cancel()
+{
+    // if the thread we're waiting for is waiting for the GUI mutex, we will
+    // deadlock so make sure we release it temporarily
+    if ( wxThread::IsMain() )
+        wxMutexGuiLeave();
+
+    // nobody ever writes this variable so it's safe to not use any
+    // synchronization here
+    m_cancelled = TRUE;
+
+    // entering Wait() releases the mutex thus allowing SignalExit() to acquire
+    // it and to signal us its termination
+    m_cond.Wait(m_mutex);
+
+    // mutex is still in the locked state - relocked on exit from Wait(), so
+    // unlock it - we don't need it any more, the thread has already terminated
+    m_mutex.Unlock();
+
+    // reacquire GUI mutex
+    if ( wxThread::IsMain() )
+        wxMutexGuiEnter();
 }
 
-void wxThread::SetPriority(int prio)
+void wxThreadInternal::SignalExit()
 {
-    if (p_internal->state == STATE_RUNNING)
-        return;
+    // as mutex is currently locked, this will block until some other thread
+    // (normally the same which created this one) unlocks it by entering Wait()
+    m_mutex.Lock();
 
-    if (prio > 100) prio = 100;
-       
-    if (prio < 0) prio = 0;
-    
-    p_internal->prio = prio;
+    // wake up all the threads waiting for our termination
+    m_cond.Broadcast();
+
+    // after this call mutex will be finally unlocked
+    m_mutex.Unlock();
 }
 
-int wxThread::GetPriority() const
+void wxThreadInternal::Pause()
 {
-    return p_internal->prio;
+    wxCHECK_RET( m_state == STATE_PAUSED,
+                 "thread must first be paused with wxThread::Pause()." );
+
+    // wait until the condition is signaled from Resume()
+    m_condSuspend.Wait(m_mutexSuspend);
 }
 
-void wxThread::DeferDestroy(bool on)
+void wxThreadInternal::Resume()
 {
-    if (on)
-        pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
-    else
-        pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+    wxCHECK_RET( m_state == STATE_PAUSED,
+                 "can't resume thread which is not suspended." );
+
+    // we will be able to lock this mutex only when Pause() starts waiting
+    wxMutexLocker lock(m_mutexSuspend);
+    m_condSuspend.Signal();
+
+    SetState(STATE_RUNNING);
+}
+
+// -----------------------------------------------------------------------------
+// static functions
+// -----------------------------------------------------------------------------
+
+wxThread *wxThread::This()
+{
+    return (wxThread *)pthread_getspecific(gs_keySelf);
+}
+
+bool wxThread::IsMain()
+{
+    return (bool)pthread_equal(pthread_self(), gs_tidMain);
+}
+
+void wxThread::Yield()
+{
+    sched_yield();
+}
+
+void wxThread::Sleep(unsigned long milliseconds)
+{
+    wxUsleep(milliseconds);
+}
+
+// -----------------------------------------------------------------------------
+// creating thread
+// -----------------------------------------------------------------------------
+
+wxThread::wxThread()
+{
+    // add this thread to the global list of all threads
+    gs_allThreads.Add(this);
+
+    p_internal = new wxThreadInternal();
 }
 
-wxThreadError wxThread::Destroy()
+wxThreadError wxThread::Create()
 {
-    int res = 0;
+    if (p_internal->GetState() != STATE_NEW)
+        return wxTHREAD_RUNNING;
+
+    // set up the thread attribute: right now, we only set thread priority
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
 
-    if (p_internal->state == STATE_RUNNING) 
+    int prio;
+    if ( pthread_attr_getschedpolicy(&attr, &prio) != 0 )
+    {
+        wxLogError(_("Can not retrieve thread scheduling policy."));
+    }
+
+    int min_prio = sched_get_priority_min(prio),
+        max_prio = sched_get_priority_max(prio);
+
+    if ( min_prio == -1 || max_prio == -1 )
+    {
+        wxLogError(_("Can not get priority range for scheduling policy %d."),
+                   prio);
+    }
+    else
     {
-        res = pthread_cancel(p_internal->thread_id);
-        if (res == 0)
-           p_internal->state = STATE_CANCELED;
+        struct sched_param sp;
+        pthread_attr_getschedparam(&attr, &sp);
+        sp.sched_priority = min_prio +
+                           (p_internal->GetPriority()*(max_prio-min_prio))/100;
+        pthread_attr_setschedparam(&attr, &sp);
+    }
+
+    // create the new OS thread object
+    int rc = pthread_create(&p_internal->thread_id, &attr,
+                            wxThreadInternal::PthreadStart,
+                            (void *)this);
+    pthread_attr_destroy(&attr);
+
+    if ( rc != 0 )
+    {
+        p_internal->SetState(STATE_EXITED);
+        return wxTHREAD_NO_RESOURCE;
     }
 
     return wxTHREAD_NO_ERROR;
 }
 
+wxThreadError wxThread::Run()
+{
+    return p_internal->Run();
+}
+
+// -----------------------------------------------------------------------------
+// misc accessors
+// -----------------------------------------------------------------------------
+
+void wxThread::SetPriority(unsigned int prio)
+{
+    wxCHECK_RET( (WXTHREAD_MIN_PRIORITY <= prio) &&
+                 (prio <= WXTHREAD_MAX_PRIORITY), "invalid thread priority" );
+
+    wxCriticalSectionLocker lock(m_critsect);
+
+    switch ( p_internal->GetState() )
+    {
+        case STATE_NEW:
+            // thread not yet started, priority will be set when it is
+            p_internal->SetPriority(prio);
+            break;
+
+        case STATE_RUNNING:
+        case STATE_PAUSED:
+            {
+                struct sched_param sparam;
+                sparam.sched_priority = prio;
+
+                if ( pthread_setschedparam(p_internal->GetId(),
+                                           SCHED_OTHER, &sparam) != 0 )
+                {
+                    wxLogError(_("Failed to set thread priority %d."), prio);
+                }
+            }
+            break;
+
+        case STATE_EXITED:
+        default:
+            wxFAIL_MSG("impossible to set thread priority in this state");
+    }
+}
+
+unsigned int wxThread::GetPriority() const
+{
+    wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect);
+
+    return p_internal->GetPriority();
+}
+
+unsigned long wxThread::GetID() const
+{
+    return (unsigned long)p_internal->thread_id;
+}
+
+// -----------------------------------------------------------------------------
+// pause/resume
+// -----------------------------------------------------------------------------
+
 wxThreadError wxThread::Pause()
 {
-    if (p_internal->state != STATE_RUNNING)
+    wxCriticalSectionLocker lock(m_critsect);
+
+    if ( p_internal->GetState() != STATE_RUNNING )
+    {
+        wxLogDebug("Can't pause thread which is not running.");
+
         return wxTHREAD_NOT_RUNNING;
+    }
 
-    if (!p_internal->defer_destroy)
-        return wxTHREAD_MISC_ERROR;
+    p_internal->SetState(STATE_PAUSED);
 
-    p_internal->state = STATE_PAUSING;
     return wxTHREAD_NO_ERROR;
 }
 
 wxThreadError wxThread::Resume()
 {
-    if (p_internal->state == STATE_PAUSING || p_internal->state == STATE_PAUSED)
-      p_internal->state = STATE_RUNNING;
+    wxCriticalSectionLocker lock(m_critsect);
 
-    return wxTHREAD_NO_ERROR;
+    if ( p_internal->GetState() == STATE_PAUSED )
+    {
+        p_internal->Resume();
+
+        return wxTHREAD_NO_ERROR;
+    }
+    else
+    {
+        wxLogDebug("Attempt to resume a thread which is not paused.");
+
+        return wxTHREAD_MISC_ERROR;
+    }
 }
 
-void *wxThread::Join()
+// -----------------------------------------------------------------------------
+// exiting thread
+// -----------------------------------------------------------------------------
+
+wxThread::ExitCode wxThread::Delete()
 {
-    void* status = 0;
+    m_critsect.Enter();
+    thread_state state = p_internal->GetState();
+    m_critsect.Leave();
 
-    if (p_internal->state != STATE_IDLE) 
+    switch ( state )
     {
-        bool do_unlock = wxThread::IsMain();
+        case STATE_NEW:
+        case STATE_EXITED:
+            // nothing to do
+            break;
 
-        while (p_internal->state == STATE_RUNNING)
-            wxYield();
+        case STATE_PAUSED:
+            // resume the thread first
+            Resume();
 
-        if (do_unlock) wxMainMutex->Unlock();
-      
-        pthread_join(p_internal->thread_id, &status);
-      
-        if (do_unlock) wxMainMutex->Lock();
+            // fall through
 
-        p_internal->state = STATE_IDLE;
+        default:
+            // set the flag telling to the thread to stop and wait
+            p_internal->Cancel();
     }
-    
-    return status;
+
+    return NULL;
 }
 
-unsigned long wxThread::GetID() const
+wxThreadError wxThread::Kill()
 {
-    return p_internal->thread_id;
+    switch ( p_internal->GetState() )
+    {
+        case STATE_NEW:
+        case STATE_EXITED:
+            return wxTHREAD_NOT_RUNNING;
+
+        default:
+            if ( pthread_cancel(p_internal->GetId()) != 0 )
+            {
+                wxLogError(_("Failed to terminate a thread."));
+
+                return wxTHREAD_MISC_ERROR;
+            }
+
+            return wxTHREAD_NO_ERROR;
+    }
 }
 
 void wxThread::Exit(void *status)
 {
-    wxThread* ptr = this;
+    // first call user-level clean up code
+    OnExit();
+
+    // next wake up the threads waiting for us (OTOH, this function won't return
+    // until someone waited for us!)
+    p_internal->SignalExit();
 
-/*    THREAD_SEND_EXIT_MSG(ptr);  TODO for Xt */
-    
-    p_internal->state = STATE_EXITED;
+    p_internal->SetState(STATE_EXITED);
+
+    // delete both C++ thread object and terminate the OS thread object
+    delete this;
     pthread_exit(status);
 }
 
-void wxThread::TestDestroy()
+// also test whether we were paused
+bool wxThread::TestDestroy()
 {
-    if (p_internal->state == STATE_PAUSING) 
+    wxCriticalSectionLocker lock((wxCriticalSection&)m_critsect);
+
+    if ( p_internal->GetState() == STATE_PAUSED )
     {
-        p_internal->state = STATE_PAUSED;
-        while (p_internal->state == STATE_PAUSED) 
-       {
-            pthread_testcancel();
-            usleep(1);
-        }
+        // leave the crit section or the other threads will stop too if they try
+        // to call any of (seemingly harmless) IsXXX() functions while we sleep
+        m_critsect.Leave();
+
+        p_internal->Pause();
+
+        // enter it back before it's finally left in lock object dtor
+        m_critsect.Enter();
     }
-    pthread_testcancel();
+
+    return p_internal->WasCancelled();
 }
 
-bool wxThread::IsMain()
+wxThread::~wxThread()
 {
-    return (bool)pthread_equal(pthread_self(), p_mainid);
+    // remove this thread from the global array
+    gs_allThreads.Remove(this);
 }
 
+// -----------------------------------------------------------------------------
+// state tests
+// -----------------------------------------------------------------------------
+
 bool wxThread::IsRunning() const
 {
-    return (p_internal->state == STATE_RUNNING);
-}
+    wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect);
 
-bool wxThread::IsAlive() const
-{
-    return (p_internal->state == STATE_RUNNING) ||
-           (p_internal->state == STATE_PAUSING) ||
-           (p_internal->state == STATE_PAUSED);
+    return p_internal->GetState() == STATE_RUNNING;
 }
 
-wxThread::wxThread()
+bool wxThread::IsAlive() const
 {
-    p_internal = new wxThreadInternal();
-}
+    wxCriticalSectionLocker lock((wxCriticalSection&)m_critsect);
 
-wxThread::~wxThread()
-{
-    Destroy();
-    Join();
-    delete p_internal;
-}
+    switch ( p_internal->GetState() )
+    {
+        case STATE_RUNNING:
+        case STATE_PAUSED:
+            return TRUE;
 
-// The default callback just joins the thread and throws away the result.
-void wxThread::OnExit()
-{
-    Join();
+        default:
+            return FALSE;
+    }
 }
 
 //--------------------------------------------------------------------
-// wxThreadModule 
+// wxThreadModule
 //--------------------------------------------------------------------
 
 class wxThreadModule : public wxModule
@@ -426,22 +695,53 @@ private:
 
 IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
 
-bool wxThreadModule::OnInit() 
+bool wxThreadModule::OnInit()
 {
-    wxMainMutex = new wxMutex();
-    wxThreadGuiInit();
-    p_mainid = pthread_self();
-    wxMainMutex->Lock();
+    if ( pthread_key_create(&gs_keySelf, NULL /* dtor function */) != 0 )
+    {
+        wxLogError(_("Thread module initialization failed: "
+                     "failed to create pthread key."));
+
+        return FALSE;
+    }
+
+    gs_mutexGui = new wxMutex();
+    //wxThreadGuiInit();
+    gs_tidMain = pthread_self();
+    gs_mutexGui->Lock();
 
     return TRUE;
 }
 
 void wxThreadModule::OnExit()
 {
-    wxMainMutex->Unlock();
-    wxThreadGuiExit();
-    delete wxMainMutex;
-};
+    wxASSERT_MSG( wxThread::IsMain(), "only main thread can be here" );
 
-#endif
-  // wxUSE_THREADS
+    // terminate any threads left
+    size_t count = gs_allThreads.GetCount();
+    if ( count != 0u )
+        wxLogDebug("Some threads were not terminated by the application.");
+
+    for ( size_t n = 0u; n < count; n++ )
+    {
+        gs_allThreads[n]->Delete();
+    }
+
+    // destroy GUI mutex
+    gs_mutexGui->Unlock();
+    //wxThreadGuiExit();
+    delete gs_mutexGui;
+
+    // and free TLD slot
+    (void)pthread_key_delete(gs_keySelf);
+}
+
+void wxMutexGuiEnter()
+{
+  gs_mutexGui->Lock();
+}
+
+void wxMutexGuiLeave()
+{
+  gs_mutexGui->Unlock();
+}
index 3c65b50a732cbc5ba34f234a1401519d1156e122..8603963d6f7a1db433234e4e8fb1116456144479 100644 (file)
@@ -86,6 +86,30 @@ extern "C"
 }
 #endif
 
+void wxUsleep(unsigned long milliseconds)
+{
+#if defined(HAVE_NANOSLEEP)
+    timespec tmReq;
+    tmReq.tv_sec = milliseconds / 1000;
+    tmReq.tv_nsec = (milliseconds % 1000) * 1000 * 1000;
+
+    // we're not interested in remaining time nor in return value
+    (void)nanosleep(&tmReq, (timespec *)NULL);
+#elif defined(HAVE_USLEEP)
+    // uncomment this if you feel brave or if you are sure that your version
+    // of Solaris has a safe usleep() function but please notice that usleep()
+    // is known to lead to crashes in MT programs in Solaris 2.[67] and is not
+    // documented as MT-Safe
+    #if defined(__SUN__) && defined(wxUSE_THREADS)
+        #error "usleep() cannot be used in MT programs under Solaris."
+    #endif // Sun
+
+    usleep(milliseconds * 1000); // usleep(3) wants microseconds
+#else // !sleep function
+    #error "usleep() or nanosleep() function required for wxUsleep"
+#endif // sleep function
+}
+
 void xt_notify_end_process(XtPointer client, int *fid,
                            XtInputId *id)
 {