X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e99762c031bf2c71af7f856c1d713bce0422acaa..ae177b45b258b4985ee8c9ce7848bcb4f1266f80:/src/os2/dcclient.cpp diff --git a/src/os2/dcclient.cpp b/src/os2/dcclient.cpp index a5cc0f7fee..d02dd2bdcf 100644 --- a/src/os2/dcclient.cpp +++ b/src/os2/dcclient.cpp @@ -23,6 +23,7 @@ #include "wx/string.h" #include "wx/log.h" #include "wx/window.h" +#include "wx/app.h" #include "wx/os2/private.h" @@ -69,7 +70,7 @@ static RECT g_paintStruct; #ifdef __WXDEBUG__ // a global variable which we check to verify that wxPaintDC are only // created in resopnse to WM_PAINT message - doing this from elsewhere is a - // common programming error among wxWindows programmers and might lead to + // common programming error among wxWidgets programmers and might lead to // very subtle and difficult to debug refresh/repaint bugs. int g_isPainting = 0; #endif // __WXDEBUG__ @@ -85,6 +86,8 @@ static RECT g_paintStruct; wxWindowDC::wxWindowDC() { m_pCanvas = NULL; + m_PageSize.cx = m_PageSize.cy = 0; + } wxWindowDC::wxWindowDC( @@ -93,24 +96,37 @@ wxWindowDC::wxWindowDC( { ERRORID vError; wxString sError; + int nWidth, nHeight; m_pCanvas = pTheCanvas; + DoGetSize(&nWidth, &nHeight); + m_PageSize.cx = nWidth; + m_PageSize.cy = nHeight; m_hDC = (WXHDC) ::WinOpenWindowDC(GetWinHwnd(pTheCanvas) ); - m_nDCCount++; + // // default under PM is that Window and Client DC's are the same // so we offer a separate Presentation Space to use for the // entire window. Otherwise, calling BeginPaint will just create // chached-micro client presentation space // - m_hPS = GpiCreatePS( m_hab - ,m_hDC - ,&m_PageSize - ,PU_PELS | GPIF_LONG | GPIA_ASSOC - ); + m_hPS = ::GpiCreatePS( vHabmain + ,m_hDC + ,&m_PageSize + ,PU_PELS | GPIF_LONG | GPIA_ASSOC + ); + if (!m_hPS) + { + vError = ::WinGetLastError(vHabmain); + sError = wxPMErrorToStr(vError); + wxLogError("Unable to create presentation space. Error: %s\n", sError.c_str()); + } ::GpiAssociate(m_hPS, NULLHANDLE); ::GpiAssociate(m_hPS, m_hDC); - // Set the wxWindows color table + + // + // Set the wxWidgets color table + // if (!::GpiCreateLogColorTable( m_hPS ,0L ,LCOLF_CONSECRGB @@ -121,32 +137,65 @@ wxWindowDC::wxWindowDC( { vError = ::WinGetLastError(vHabmain); sError = wxPMErrorToStr(vError); - wxLogError("Unable to set current color table. Error: %s\n", sError); + wxLogError("Unable to set current color table. Error: %s\n", sError.c_str()); } - SetBackground(wxBrush(m_pCanvas->GetBackgroundColour(), wxSOLID)); -} + ::GpiCreateLogColorTable( m_hPS + ,0L + ,LCOLF_RGB + ,0L + ,0L + ,NULL + ); + ::WinQueryWindowRect( GetWinHwnd(m_pCanvas) + ,&m_vRclPaint + ); + InitDC(); +} // end of wxWindowDC::wxWindowDC -wxWindowDC::~wxWindowDC() +void wxWindowDC::InitDC() { - if (m_pCanvas && m_hDC) - { - SelectOldObjects(m_hDC); - // - // In PM one does not explicitly close or release an open WindowDC - // They automatically close with the window, unless explicitly detached - // but we need to destroy our PS - // - if(m_hPS) - { - ::GpiAssociate(m_hPS, NULLHANDLE); - ::GpiDestroyPS(m_hPS); - } - m_hPS = NULLHANDLE; - m_hDC = NULLHANDLE; - } - m_nDCCount--; -} + // + // The background mode is only used for text background and is set in + // DrawText() to OPAQUE as required, otherwise always TRANSPARENT, + // + ::GpiSetBackMix(GetHPS(), BM_LEAVEALONE); + + // + // Default bg colour is pne of the window + // + SetBackground(wxBrush(m_pCanvas->GetBackgroundColour(), wxSOLID)); + + wxColour vColor( wxT("BLACK") ); + m_pen.SetColour(vColor); + + vColor.Set( wxT("WHITE") ); + m_brush.SetColour(vColor); + InitializePalette(); + wxFont* pFont = new wxFont( 12 + ,wxNORMAL + ,wxNORMAL + ,wxBOLD + ); + SetFont(*pFont); + delete pFont; + // + // OS/2 default vertical character allignment needs to match the other OS's + // + ::GpiSetTextAlignment((HPS)GetHPS(), TA_NORMAL_HORIZ, TA_BOTTOM); + +} // end of wxWindowDC::InitDC + +void wxWindowDC::DoGetSize( + int* pnWidth +, int* pnHeight +) const +{ + wxCHECK_RET( m_pCanvas, _T("wxWindowDC without a window?") ); + m_pCanvas->GetSize( pnWidth + ,pnHeight + ); +} // end of wxWindowDC::DoGetSize // ---------------------------------------------------------------------------- // wxClientDC @@ -177,7 +226,7 @@ wxClientDC::wxClientDC( ,PU_PELS | GPIF_LONG | GPIA_ASSOC ); - // Set the wxWindows color table + // Set the wxWidgets color table if (!::GpiCreateLogColorTable( m_hPS ,0L ,LCOLF_CONSECRGB @@ -188,51 +237,62 @@ wxClientDC::wxClientDC( { vError = ::WinGetLastError(vHabmain); sError = wxPMErrorToStr(vError); - wxLogError("Unable to set current color table. Error: %s\n", sError); + wxLogError("Unable to set current color table. Error: %s\n", sError.c_str()); } + ::GpiCreateLogColorTable( m_hPS + ,0L + ,LCOLF_RGB + ,0L + ,0L + ,NULL + ); // - // Default mode is BM_LEAVEALONE so we make no call Set the mix + // Set the DC/PS rectangle // - SetBackground(wxBrush( m_pCanvas->GetBackgroundColour() - ,wxSOLID - ) - ); + ::WinQueryWindowRect( GetWinHwnd(m_pCanvas) + ,&m_vRclPaint + ); + InitDC(); } // end of wxClientDC::wxClientDC -wxClientDC::~wxClientDC() +void wxClientDC::InitDC() { - if ( m_pCanvas && GetHdc() ) - { - SelectOldObjects(m_hDC); + wxWindowDC::InitDC(); - // - // We don't explicitly release Device contexts in PM and - // the cached micro PS is already gone - // - m_hDC = 0; + // in wxUniv build we must manually do some DC adjustments usually + // performed by Windows for us +#ifdef __WXUNIVERSAL__ + wxPoint ptOrigin = m_pCanvas->GetClientAreaOrigin(); + if ( ptOrigin.x || ptOrigin.y ) + { + // no need to shift DC origin if shift is null + SetDeviceOrigin(ptOrigin.x, ptOrigin.y); } + + // clip the DC to avoid overwriting the non client area + SetClippingRegion(wxPoint(0, 0), m_pCanvas->GetClientSize()); +#endif // __WXUNIVERSAL__ +} // end of wxClientDC::InitDC + +wxClientDC::~wxClientDC() +{ } // end of wxClientDC::~wxClientDC +void wxClientDC::DoGetSize( + int* pnWidth +, int* pnHeight +) const +{ + wxCHECK_RET( m_pCanvas, _T("wxWindowDC without a window?") ); + m_pCanvas->GetClientSize( pnWidth + ,pnHeight + ); +} // end of wxClientDC::DoGetSize + // ---------------------------------------------------------------------------- // wxPaintDC // ---------------------------------------------------------------------------- -// VZ: initial implementation (by JACS) only remembered the last wxPaintDC -// created and tried to reuse - this was supposed to take care of a -// situation when a derived class OnPaint() calls base class OnPaint() -// because in this case ::BeginPaint() shouldn't be called second time. -// -// I'm not sure how useful this is, however we must remember the HWND -// associated with the last HDC as well - otherwise we may (and will!) try -// to reuse the HDC for another HWND which is a nice recipe for disaster. -// -// So we store a list of windows for which we already have the DC and not -// just one single hDC. This seems to work, but I'm really not sure about -// the usefullness of the whole idea - IMHO it's much better to not call -// base class OnPaint() at all, or, if we really want to allow it, add a -// "wxPaintDC *" parameter to wxPaintEvent which should be used if it's -// !NULL instead of creating a new DC. - wxArrayDCInfo wxPaintDC::ms_cache; wxPaintDC::wxPaintDC() @@ -246,7 +306,6 @@ wxPaintDC::wxPaintDC( ) { wxCHECK_RET(pCanvas, wxT("NULL canvas in wxPaintDC ctor")); - RECTL vRect; #ifdef __WXDEBUG__ if (g_isPainting <= 0) @@ -270,46 +329,16 @@ wxPaintDC::wxPaintDC( } else // not in cache, create a new one { - SIZEL vSizl = { 0,0}; HPS hPS; - HRGN hRgn; - - memset(&g_paintStruct, '\0', sizeof(RECTL)); - if (!::WinQueryUpdateRect(GetWinHwnd(m_pCanvas), &g_paintStruct)) - { - wxLogLastError("CreateRectRgn"); -// return; - } - m_hDC = (WXHDC) ::WinOpenWindowDC(GetWinHwnd(m_pCanvas)); - m_hPS = ::GpiCreatePS( wxGetInstance() - ,m_hDC - ,&vSizl - ,PU_PELS | GPIF_LONG | GPIA_ASSOC - ); - - // Set the wxWindows color table - ::GpiCreateLogColorTable( m_hPS - ,0L - ,LCOLF_CONSECRGB - ,0L - ,(LONG)wxTheColourDatabase->m_nSize - ,(PLONG)wxTheColourDatabase->m_palTable - ); - ::GpiCreateLogColorTable( m_hPS - ,0L - ,LCOLF_RGB - ,0L - ,0L - ,NULL - ); -#if 0 + m_hDC = ::WinOpenWindowDC(GetWinHwnd(m_pCanvas)); hPS = ::WinBeginPaint( GetWinHwnd(m_pCanvas) ,NULLHANDLE ,&g_paintStruct ); if(hPS) { + ::GpiAssociate(hPS, m_hDC); m_hOldPS = m_hPS; m_hPS = hPS; ::GpiCreateLogColorTable( m_hPS @@ -326,16 +355,18 @@ wxPaintDC::wxPaintDC( ,0L ,NULL ); + + ::WinFillRect(hPS, &g_paintStruct, m_pCanvas->GetBackgroundColour().GetPixel()); + ::WinQueryWindowRect( GetWinHwnd(m_pCanvas) + ,&m_vRclPaint + ); } -#endif m_bIsPaintTime = TRUE; - m_hDC = (WXHDC) -1; // to satisfy those anonizmous efforts - m_vRclPaint = g_paintStruct; ms_cache.Add(new wxPaintDCInfo(m_pCanvas, this)); } - SetBackground(wxBrush(m_pCanvas->GetBackgroundColour(), wxSOLID)); -} + InitDC(); +} // end of wxPaintDC::wxPaintDC wxPaintDC::~wxPaintDC() { @@ -353,7 +384,7 @@ wxPaintDC::~wxPaintDC() ::WinEndPaint(m_hPS); m_hPS = m_hOldPS; m_bIsPaintTime = FALSE; - ms_cache.Remove(nIndex); + ms_cache.RemoveAt(nIndex); } //else: cached DC entry is still in use @@ -382,3 +413,22 @@ wxPaintDCInfo* wxPaintDC::FindInCache( return pInfo; } // end of wxPaintDC::FindInCache +// find the entry for this DC in the cache (keyed by the window) +WXHDC wxPaintDC::FindDCInCache( + wxWindow* pWin +) +{ + wxPaintDCInfo* pInfo = NULL; + size_t nCache = ms_cache.GetCount(); + + for (size_t n = 0; n < nCache; n++) + { + pInfo = &ms_cache[n]; + if (pInfo->m_hWnd == pWin->GetHWND()) + { + return pInfo->m_hDC; + } + } + return 0; +} // end of wxPaintDC::FindInCache +