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     wxColour 
vColor( wxT("BLACK") ); 
 172     m_pen
.SetColour(vColor
); 
 174     vColor
.Set( wxT("WHITE") ); 
 175     m_brush
.SetColour(vColor
); 
 177     wxFont
*                         pFont 
= new wxFont( 10 
 185     // OS/2 default vertical character alignment needs to match the other OS's 
 187     ::GpiSetTextAlignment((HPS
)GetHPS(), TA_NORMAL_HORIZ
, TA_BOTTOM
); 
 189 } // end of wxWindowDC::InitDC 
 191 void wxWindowDC::DoGetSize( 
 196     wxCHECK_RET( m_pCanvas
, _T("wxWindowDC without a window?") ); 
 197     m_pCanvas
->GetSize( pnWidth
 
 200 } // end of wxWindowDC::DoGetSize 
 202 // ---------------------------------------------------------------------------- 
 204 // ---------------------------------------------------------------------------- 
 206 wxClientDC::wxClientDC() 
 211 wxClientDC::wxClientDC( 
 215     SIZEL                           vSizl 
= { 0,0}; 
 219     m_pCanvas 
= pTheCanvas
; 
 222     // default under PM is that Window and Client DC's are the same 
 224     m_hDC 
= (WXHDC
) ::WinOpenWindowDC(GetWinHwnd(pTheCanvas
)); 
 225     m_hPS 
= ::GpiCreatePS( wxGetInstance() 
 228                           ,PU_PELS 
| GPIF_LONG 
| GPIA_ASSOC
 
 231     // Set the wxWidgets color table 
 232     if (!::GpiCreateLogColorTable( m_hPS
 
 236                                   ,(LONG
)wxTheColourDatabase
->m_nSize
 
 237                                   ,(PLONG
)wxTheColourDatabase
->m_palTable
 
 240         vError 
= ::WinGetLastError(vHabmain
); 
 241         sError 
= wxPMErrorToStr(vError
); 
 242         wxLogError(_T("Unable to set current color table (4). Error: %s\n"), sError
.c_str()); 
 244     ::GpiCreateLogColorTable( m_hPS
 
 252     // Set the DC/PS rectangle 
 254     ::WinQueryWindowRect( GetWinHwnd(m_pCanvas
) 
 258 } // end of wxClientDC::wxClientDC 
 260 void wxClientDC::InitDC() 
 262     wxWindowDC::InitDC(); 
 264     // in wxUniv build we must manually do some DC adjustments usually 
 265     // performed by Windows for us 
 266 #ifdef __WXUNIVERSAL__ 
 267     wxPoint ptOrigin 
= m_pCanvas
->GetClientAreaOrigin(); 
 268     if ( ptOrigin
.x 
|| ptOrigin
.y 
) 
 270         // no need to shift DC origin if shift is null 
 271         SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
); 
 274     // clip the DC to avoid overwriting the non client area 
 275     SetClippingRegion(wxPoint(0, 0), m_pCanvas
->GetClientSize()); 
 276 #endif // __WXUNIVERSAL__ 
 277 } // end of wxClientDC::InitDC 
 279 wxClientDC::~wxClientDC() 
 281 } // end of wxClientDC::~wxClientDC 
 283 void wxClientDC::DoGetSize( 
 288     wxCHECK_RET( m_pCanvas
, _T("wxWindowDC without a window?") ); 
 289     m_pCanvas
->GetClientSize( pnWidth
 
 292 } // end of wxClientDC::DoGetSize 
 294 // ---------------------------------------------------------------------------- 
 296 // ---------------------------------------------------------------------------- 
 298 wxArrayDCInfo 
wxPaintDC::ms_cache
; 
 300 wxPaintDC::wxPaintDC() 
 306 wxPaintDC::wxPaintDC( 
 310     wxCHECK_RET(pCanvas
, wxT("NULL canvas in wxPaintDC ctor")); 
 313     if (g_isPainting 
<= 0) 
 315         wxFAIL_MSG( wxT("wxPaintDC may be created only in EVT_PAINT handler!") ); 
 318 #endif // __WXDEBUG__ 
 323     // Do we have a DC for this window in the cache? 
 325     wxPaintDCInfo
*                  pInfo 
= FindInCache(); 
 329         m_hDC 
= pInfo
->m_hDC
; 
 332     else // not in cache, create a new one 
 336         m_hDC 
= ::WinOpenWindowDC(GetWinHwnd(m_pCanvas
)); 
 337         hPS 
= ::WinBeginPaint( GetWinHwnd(m_pCanvas
) 
 343             ::GpiAssociate(hPS
, m_hDC
); 
 346             ::GpiCreateLogColorTable( m_hPS
 
 350                                      ,(LONG
)wxTheColourDatabase
->m_nSize
 
 351                                      ,(PLONG
)wxTheColourDatabase
->m_palTable
 
 353             ::GpiCreateLogColorTable( m_hPS
 
 361             ::WinFillRect(hPS
, &g_paintStruct
,  m_pCanvas
->GetBackgroundColour().GetPixel()); 
 362             ::WinQueryWindowRect( GetWinHwnd(m_pCanvas
) 
 367         m_bIsPaintTime   
= true; 
 368         ms_cache
.Add(new wxPaintDCInfo(m_pCanvas
, this)); 
 371 } // end of wxPaintDC::wxPaintDC 
 373 wxPaintDC::~wxPaintDC() 
 377         SelectOldObjects(m_hDC
); 
 380         wxPaintDCInfo
*              pInfo 
= FindInCache(&nIndex
); 
 382         wxCHECK_RET( pInfo
, wxT("existing DC should have a cache entry") ); 
 384         if ( !--pInfo
->m_nCount 
) 
 386             ::WinEndPaint(m_hPS
); 
 388             m_bIsPaintTime 
= false; 
 389             ms_cache
.RemoveAt(nIndex
); 
 391         //else: cached DC entry is still in use 
 393         // prevent the base class dtor from ReleaseDC()ing it again 
 398 wxPaintDCInfo
* wxPaintDC::FindInCache( 
 402     wxPaintDCInfo
*                  pInfo 
= NULL
; 
 403     size_t                          nCache 
= ms_cache
.GetCount(); 
 405     for (size_t n 
= 0; n 
< nCache
; n
++) 
 407         pInfo 
= &ms_cache
[n
]; 
 408         if (pInfo
->m_hWnd 
== m_pCanvas
->GetHWND()) 
 416 } // end of wxPaintDC::FindInCache 
 418 // find the entry for this DC in the cache (keyed by the window) 
 419 WXHDC 
wxPaintDC::FindDCInCache( 
 423     wxPaintDCInfo
*                  pInfo 
= NULL
; 
 424     size_t                          nCache 
= ms_cache
.GetCount(); 
 426     for (size_t n 
= 0; n 
< nCache
; n
++) 
 428         pInfo 
= &ms_cache
[n
]; 
 429         if (pInfo
->m_hWnd 
== pWin
->GetHWND()) 
 435 } // end of wxPaintDC::FindInCache