1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/os2/dcclient.cpp 
   3 // Purpose:     wxClientDC class 
   4 // Author:      David Webster 
   8 // Copyright:   (c) David Webster 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // =========================================================================== 
  14 // =========================================================================== 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 // For compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  23 #include "wx/dcclient.h" 
  26     #include "wx/string.h" 
  29     #include "wx/window.h" 
  32 #include "wx/os2/private.h" 
  34 // ---------------------------------------------------------------------------- 
  36 // ---------------------------------------------------------------------------- 
  38 struct WXDLLEXPORT wxPaintDCInfo
 
  40     wxPaintDCInfo( wxWindow
* pWin
 
  44         m_hWnd 
= pWin
->GetHWND(); 
  45         m_hDC 
= pDC
->GetHDC(); 
  49     WXHWND                          m_hWnd
;   // window for this DC 
  50     WXHDC                           m_hDC
;    // the DC handle 
  51     size_t                          m_nCount
; // usage count 
  52 }; // end of wxPaintDCInfot 
  54 #include "wx/arrimpl.cpp" 
  56 WX_DEFINE_OBJARRAY(wxArrayDCInfo
); 
  58 // ---------------------------------------------------------------------------- 
  60 // ---------------------------------------------------------------------------- 
  62     IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
) 
  63     IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
) 
  64     IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxWindowDC
) 
  66 // ---------------------------------------------------------------------------- 
  68 // ---------------------------------------------------------------------------- 
  70 static RECT        g_paintStruct
; 
  73     // a global variable which we check to verify that wxPaintDC are only 
  74     // created in resopnse to WM_PAINT message - doing this from elsewhere is a 
  75     // common programming error among wxWidgets programmers and might lead to 
  76     // very subtle and difficult to debug refresh/repaint bugs. 
  80 // =========================================================================== 
  82 // =========================================================================== 
  84 // ---------------------------------------------------------------------------- 
  86 // ---------------------------------------------------------------------------- 
  88 wxWindowDC::wxWindowDC() 
  91     m_PageSize
.cx 
= m_PageSize
.cy 
= 0; 
  95 wxWindowDC::wxWindowDC( 
 103     m_pCanvas 
= pTheCanvas
; 
 104     DoGetSize(&nWidth
, &nHeight
); 
 105     m_PageSize
.cx 
= nWidth
; 
 106     m_PageSize
.cy 
= nHeight
; 
 107     m_hDC 
= (WXHDC
) ::WinOpenWindowDC(GetWinHwnd(pTheCanvas
) ); 
 110     // default under PM is that Window and Client DC's are the same 
 111     // so we offer a separate Presentation Space to use for the 
 112     // entire window.  Otherwise, calling BeginPaint will just create 
 113     // chached-micro client presentation space 
 115      m_hPS 
= ::GpiCreatePS( vHabmain
 
 118                            ,PU_PELS 
| GPIF_LONG 
| GPIA_ASSOC
 
 122         vError 
= ::WinGetLastError(vHabmain
); 
 123         sError 
= wxPMErrorToStr(vError
); 
 124         wxLogError(_T("Unable to create presentation space. Error: %s\n"), sError
.c_str()); 
 126     ::GpiAssociate(m_hPS
, NULLHANDLE
); 
 127     ::GpiAssociate(m_hPS
, m_hDC
); 
 130     // Set the wxWidgets color table 
 132     if (!::GpiCreateLogColorTable( m_hPS
 
 136                                   ,(LONG
)wxTheColourDatabase
->m_nSize
 
 137                                   ,(PLONG
)wxTheColourDatabase
->m_palTable
 
 140         vError 
= ::WinGetLastError(vHabmain
); 
 141         sError 
= wxPMErrorToStr(vError
); 
 142         wxLogError(_T("Unable to set current color table (3). Error: %s\n"), sError
.c_str()); 
 144     ::GpiCreateLogColorTable( m_hPS
 
 151     ::WinQueryWindowRect( GetWinHwnd(m_pCanvas
) 
 155 } // end of wxWindowDC::wxWindowDC 
 157 void wxWindowDC::InitDC() 
 161     // The background mode is only used for text background and is set in 
 162     // DrawText() to OPAQUE as required, otherwise always TRANSPARENT, 
 164     ::GpiSetBackMix(GetHPS(), BM_LEAVEALONE
); 
 167     // Default bg colour is pne of the window 
 169     SetBackground(wxBrush(m_pCanvas
->GetBackgroundColour(), wxSOLID
)); 
 171     m_pen
.SetColour(*wxBLACK
); 
 172     m_brush
.SetColour(*wxWHITE
); 
 174     wxFont
* pFont 
= new wxFont( 10, wxMODERN
, wxNORMAL
, wxBOLD 
); 
 178     // OS/2 default vertical character alignment needs to match the other OS's 
 180     ::GpiSetTextAlignment((HPS
)GetHPS(), TA_NORMAL_HORIZ
, TA_BOTTOM
); 
 182 } // end of wxWindowDC::InitDC 
 184 void wxWindowDC::DoGetSize( 
 189     wxCHECK_RET( m_pCanvas
, _T("wxWindowDC without a window?") ); 
 190     m_pCanvas
->GetSize( pnWidth
 
 193 } // end of wxWindowDC::DoGetSize 
 195 // ---------------------------------------------------------------------------- 
 197 // ---------------------------------------------------------------------------- 
 199 wxClientDC::wxClientDC() 
 204 wxClientDC::wxClientDC( 
 208     SIZEL                           vSizl 
= { 0,0}; 
 212     m_pCanvas 
= pTheCanvas
; 
 215     // default under PM is that Window and Client DC's are the same 
 217     m_hDC 
= (WXHDC
) ::WinOpenWindowDC(GetWinHwnd(pTheCanvas
)); 
 218     m_hPS 
= ::GpiCreatePS( wxGetInstance() 
 221                           ,PU_PELS 
| GPIF_LONG 
| GPIA_ASSOC
 
 224     // Set the wxWidgets color table 
 225     if (!::GpiCreateLogColorTable( m_hPS
 
 229                                   ,(LONG
)wxTheColourDatabase
->m_nSize
 
 230                                   ,(PLONG
)wxTheColourDatabase
->m_palTable
 
 233         vError 
= ::WinGetLastError(vHabmain
); 
 234         sError 
= wxPMErrorToStr(vError
); 
 235         wxLogError(_T("Unable to set current color table (4). Error: %s\n"), sError
.c_str()); 
 237     ::GpiCreateLogColorTable( m_hPS
 
 245     // Set the DC/PS rectangle 
 247     ::WinQueryWindowRect( GetWinHwnd(m_pCanvas
) 
 251 } // end of wxClientDC::wxClientDC 
 253 void wxClientDC::InitDC() 
 255     wxWindowDC::InitDC(); 
 257     // in wxUniv build we must manually do some DC adjustments usually 
 258     // performed by Windows for us 
 259 #ifdef __WXUNIVERSAL__ 
 260     wxPoint ptOrigin 
= m_pCanvas
->GetClientAreaOrigin(); 
 261     if ( ptOrigin
.x 
|| ptOrigin
.y 
) 
 263         // no need to shift DC origin if shift is null 
 264         SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
); 
 267     // clip the DC to avoid overwriting the non client area 
 268     SetClippingRegion(wxPoint(0, 0), m_pCanvas
->GetClientSize()); 
 269 #endif // __WXUNIVERSAL__ 
 270 } // end of wxClientDC::InitDC 
 272 wxClientDC::~wxClientDC() 
 274 } // end of wxClientDC::~wxClientDC 
 276 void wxClientDC::DoGetSize( 
 281     wxCHECK_RET( m_pCanvas
, _T("wxWindowDC without a window?") ); 
 282     m_pCanvas
->GetClientSize( pnWidth
 
 285 } // end of wxClientDC::DoGetSize 
 287 // ---------------------------------------------------------------------------- 
 289 // ---------------------------------------------------------------------------- 
 291 wxArrayDCInfo 
wxPaintDC::ms_cache
; 
 293 wxPaintDC::wxPaintDC() 
 299 wxPaintDC::wxPaintDC( 
 303     wxCHECK_RET(pCanvas
, wxT("NULL canvas in wxPaintDC ctor")); 
 306     if (g_isPainting 
<= 0) 
 308         wxFAIL_MSG( wxT("wxPaintDC may be created only in EVT_PAINT handler!") ); 
 311 #endif // __WXDEBUG__ 
 316     // Do we have a DC for this window in the cache? 
 318     wxPaintDCInfo
*                  pInfo 
= FindInCache(); 
 322         m_hDC 
= pInfo
->m_hDC
; 
 325     else // not in cache, create a new one 
 329         m_hDC 
= ::WinOpenWindowDC(GetWinHwnd(m_pCanvas
)); 
 330         hPS 
= ::WinBeginPaint( GetWinHwnd(m_pCanvas
) 
 336             ::GpiAssociate(hPS
, m_hDC
); 
 339             ::GpiCreateLogColorTable( m_hPS
 
 343                                      ,(LONG
)wxTheColourDatabase
->m_nSize
 
 344                                      ,(PLONG
)wxTheColourDatabase
->m_palTable
 
 346             ::GpiCreateLogColorTable( m_hPS
 
 354             ::WinFillRect(hPS
, &g_paintStruct
,  m_pCanvas
->GetBackgroundColour().GetPixel()); 
 355             ::WinQueryWindowRect( GetWinHwnd(m_pCanvas
) 
 360         m_bIsPaintTime   
= true; 
 361         ms_cache
.Add(new wxPaintDCInfo(m_pCanvas
, this)); 
 364 } // end of wxPaintDC::wxPaintDC 
 366 wxPaintDC::~wxPaintDC() 
 370         SelectOldObjects(m_hDC
); 
 373         wxPaintDCInfo
*              pInfo 
= FindInCache(&nIndex
); 
 375         wxCHECK_RET( pInfo
, wxT("existing DC should have a cache entry") ); 
 377         if ( !--pInfo
->m_nCount 
) 
 379             ::WinEndPaint(m_hPS
); 
 381             m_bIsPaintTime 
= false; 
 382             ms_cache
.RemoveAt(nIndex
); 
 384         //else: cached DC entry is still in use 
 386         // prevent the base class dtor from ReleaseDC()ing it again 
 391 wxPaintDCInfo
* wxPaintDC::FindInCache( 
 395     wxPaintDCInfo
*                  pInfo 
= NULL
; 
 396     size_t                          nCache 
= ms_cache
.GetCount(); 
 398     for (size_t n 
= 0; n 
< nCache
; n
++) 
 400         pInfo 
= &ms_cache
[n
]; 
 401         if (pInfo
->m_hWnd 
== m_pCanvas
->GetHWND()) 
 409 } // end of wxPaintDC::FindInCache 
 411 // find the entry for this DC in the cache (keyed by the window) 
 412 WXHDC 
wxPaintDC::FindDCInCache( 
 416     wxPaintDCInfo
*                  pInfo 
= NULL
; 
 417     size_t                          nCache 
= ms_cache
.GetCount(); 
 419     for (size_t n 
= 0; n 
< nCache
; n
++) 
 421         pInfo 
= &ms_cache
[n
]; 
 422         if (pInfo
->m_hWnd 
== pWin
->GetHWND()) 
 428 } // end of wxPaintDC::FindInCache