]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/os2/dcclient.cpp
no changes
[wxWidgets.git] / src / os2 / dcclient.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: dcclient.cpp
3// Purpose: wxClientDC class
4// Author: David Webster
5// Modified by:
6// Created: 09/21/99
7// RCS-ID: $Id$
8// Copyright: (c) David Webster
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ===========================================================================
13// declarations
14// ===========================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#include "wx/string.h"
24#include "wx/log.h"
25#include "wx/window.h"
26#include "wx/app.h"
27
28#include "wx/os2/private.h"
29
30#include "wx/dcclient.h"
31
32// ----------------------------------------------------------------------------
33// array/list types
34// ----------------------------------------------------------------------------
35
36struct WXDLLEXPORT wxPaintDCInfo
37{
38 wxPaintDCInfo( wxWindow* pWin
39 ,wxDC* pDC
40 )
41 {
42 m_hWnd = pWin->GetHWND();
43 m_hDC = pDC->GetHDC();
44 m_nCount = 1;
45 }
46
47 WXHWND m_hWnd; // window for this DC
48 WXHDC m_hDC; // the DC handle
49 size_t m_nCount; // usage count
50}; // end of wxPaintDCInfot
51
52#include "wx/arrimpl.cpp"
53
54WX_DEFINE_OBJARRAY(wxArrayDCInfo);
55
56// ----------------------------------------------------------------------------
57// macros
58// ----------------------------------------------------------------------------
59
60 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC)
61 IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxWindowDC)
62 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxWindowDC)
63
64// ----------------------------------------------------------------------------
65// global variables
66// ----------------------------------------------------------------------------
67
68static RECT g_paintStruct;
69
70#ifdef __WXDEBUG__
71 // a global variable which we check to verify that wxPaintDC are only
72 // created in resopnse to WM_PAINT message - doing this from elsewhere is a
73 // common programming error among wxWindows programmers and might lead to
74 // very subtle and difficult to debug refresh/repaint bugs.
75 int g_isPainting = 0;
76#endif // __WXDEBUG__
77
78// ===========================================================================
79// implementation
80// ===========================================================================
81
82// ----------------------------------------------------------------------------
83// wxWindowDC
84// ----------------------------------------------------------------------------
85
86wxWindowDC::wxWindowDC()
87{
88 m_pCanvas = NULL;
89}
90
91wxWindowDC::wxWindowDC(
92 wxWindow* pTheCanvas
93)
94{
95 ERRORID vError;
96 wxString sError;
97
98 m_pCanvas = pTheCanvas;
99 m_hDC = (WXHDC) ::WinOpenWindowDC(GetWinHwnd(pTheCanvas) );
100
101 //
102 // default under PM is that Window and Client DC's are the same
103 // so we offer a separate Presentation Space to use for the
104 // entire window. Otherwise, calling BeginPaint will just create
105 // chached-micro client presentation space
106 //
107 m_hPS = ::GpiCreatePS( vHabmain
108 ,m_hDC
109 ,&m_PageSize
110 ,PU_PELS | GPIF_LONG | GPIA_ASSOC
111 );
112 ::GpiAssociate(m_hPS, NULLHANDLE);
113 ::GpiAssociate(m_hPS, m_hDC);
114
115 //
116 // Set the wxWindows color table
117 //
118 if (!::GpiCreateLogColorTable( m_hPS
119 ,0L
120 ,LCOLF_CONSECRGB
121 ,0L
122 ,(LONG)wxTheColourDatabase->m_nSize
123 ,(PLONG)wxTheColourDatabase->m_palTable
124 ))
125 {
126 vError = ::WinGetLastError(vHabmain);
127 sError = wxPMErrorToStr(vError);
128 wxLogError("Unable to set current color table. Error: %s\n", sError);
129 }
130 ::GpiCreateLogColorTable( m_hPS
131 ,0L
132 ,LCOLF_RGB
133 ,0L
134 ,0L
135 ,NULL
136 );
137 ::WinQueryWindowRect( GetWinHwnd(m_pCanvas)
138 ,&m_vRclPaint
139 );
140 InitDC();
141} // end of wxWindowDC::wxWindowDC
142
143void wxWindowDC::InitDC()
144{
145 wxColour vColor;
146
147 vColor.InitFromName("BLACK");
148 m_pen.SetColour(vColor);
149 vColor.Set("WHITE");
150 m_brush.SetColour(vColor);
151 //
152 // The background mode is only used for text background and is set in
153 // DrawText() to OPAQUE as required, otherwise always TRANSPARENT,
154 //
155 ::GpiSetBackMix(GetHPS(), BM_LEAVEALONE);
156
157 //
158 // Default bg colour is pne of the window
159 //
160 SetBackground(wxBrush(m_pCanvas->GetBackgroundColour(), wxSOLID));
161} // end of wxWindowDC::InitDC
162
163// ----------------------------------------------------------------------------
164// wxClientDC
165// ----------------------------------------------------------------------------
166
167wxClientDC::wxClientDC()
168{
169 m_pCanvas = NULL;
170}
171
172wxClientDC::wxClientDC(
173 wxWindow* pTheCanvas
174)
175{
176 SIZEL vSizl = { 0,0};
177 ERRORID vError;
178 wxString sError;
179
180 m_pCanvas = pTheCanvas;
181
182 //
183 // default under PM is that Window and Client DC's are the same
184 //
185 m_hDC = (WXHDC) ::WinOpenWindowDC(GetWinHwnd(pTheCanvas));
186 m_hPS = ::GpiCreatePS( wxGetInstance()
187 ,m_hDC
188 ,&vSizl
189 ,PU_PELS | GPIF_LONG | GPIA_ASSOC
190 );
191
192 // Set the wxWindows color table
193 if (!::GpiCreateLogColorTable( m_hPS
194 ,0L
195 ,LCOLF_CONSECRGB
196 ,0L
197 ,(LONG)wxTheColourDatabase->m_nSize
198 ,(PLONG)wxTheColourDatabase->m_palTable
199 ))
200 {
201 vError = ::WinGetLastError(vHabmain);
202 sError = wxPMErrorToStr(vError);
203 wxLogError("Unable to set current color table. Error: %s\n", sError);
204 }
205 ::GpiCreateLogColorTable( m_hPS
206 ,0L
207 ,LCOLF_RGB
208 ,0L
209 ,0L
210 ,NULL
211 );
212 //
213 // Set the DC/PS rectangle
214 //
215 ::WinQueryWindowRect( GetWinHwnd(m_pCanvas)
216 ,&m_vRclPaint
217 );
218 InitDC();
219} // end of wxClientDC::wxClientDC
220
221// ----------------------------------------------------------------------------
222// wxPaintDC
223// ----------------------------------------------------------------------------
224
225wxArrayDCInfo wxPaintDC::ms_cache;
226
227wxPaintDC::wxPaintDC()
228{
229 m_pCanvas = NULL;
230 m_hDC = 0;
231}
232
233wxPaintDC::wxPaintDC(
234 wxWindow* pCanvas
235)
236{
237 wxCHECK_RET(pCanvas, wxT("NULL canvas in wxPaintDC ctor"));
238
239#ifdef __WXDEBUG__
240 if (g_isPainting <= 0)
241 {
242 wxFAIL_MSG( wxT("wxPaintDC may be created only in EVT_PAINT handler!") );
243 return;
244 }
245#endif // __WXDEBUG__
246
247 m_pCanvas = pCanvas;
248
249 //
250 // Do we have a DC for this window in the cache?
251 //
252 wxPaintDCInfo* pInfo = FindInCache();
253
254 if (pInfo)
255 {
256 m_hDC = pInfo->m_hDC;
257 pInfo->m_nCount++;
258 }
259 else // not in cache, create a new one
260 {
261 HPS hPS;
262
263 hPS = ::WinBeginPaint( GetWinHwnd(m_pCanvas)
264 ,NULLHANDLE
265 ,&g_paintStruct
266 );
267 if(hPS)
268 {
269 m_hOldPS = m_hPS;
270 m_hPS = hPS;
271 ::GpiCreateLogColorTable( m_hPS
272 ,0L
273 ,LCOLF_CONSECRGB
274 ,0L
275 ,(LONG)wxTheColourDatabase->m_nSize
276 ,(PLONG)wxTheColourDatabase->m_palTable
277 );
278 ::GpiCreateLogColorTable( m_hPS
279 ,0L
280 ,LCOLF_RGB
281 ,0L
282 ,0L
283 ,NULL
284 );
285
286 ::WinFillRect(hPS, &g_paintStruct, m_pCanvas->GetBackgroundColour().GetPixel());
287 ::WinQueryWindowRect( GetWinHwnd(m_pCanvas)
288 ,&m_vRclPaint
289 );
290 }
291
292 m_bIsPaintTime = TRUE;
293 m_hDC = (WXHDC) -1; // to satisfy those anonizmous efforts
294 ms_cache.Add(new wxPaintDCInfo(m_pCanvas, this));
295 }
296 InitDC();
297} // end of wxPaintDC::wxPaintDC
298
299wxPaintDC::~wxPaintDC()
300{
301 if ( m_hDC )
302 {
303 SelectOldObjects(m_hDC);
304
305 size_t nIndex;
306 wxPaintDCInfo* pInfo = FindInCache(&nIndex);
307
308 wxCHECK_RET( pInfo, wxT("existing DC should have a cache entry") );
309
310 if ( !--pInfo->m_nCount )
311 {
312 ::WinEndPaint(m_hPS);
313 m_hPS = m_hOldPS;
314 m_bIsPaintTime = FALSE;
315 ms_cache.Remove(nIndex);
316 }
317 //else: cached DC entry is still in use
318
319 // prevent the base class dtor from ReleaseDC()ing it again
320 m_hDC = 0;
321 }
322}
323
324wxPaintDCInfo* wxPaintDC::FindInCache(
325 size_t* pIndex
326) const
327{
328 wxPaintDCInfo* pInfo = NULL;
329 size_t nCache = ms_cache.GetCount();
330
331 for (size_t n = 0; n < nCache; n++)
332 {
333 pInfo = &ms_cache[n];
334 if (pInfo->m_hWnd == m_pCanvas->GetHWND())
335 {
336 if (pIndex)
337 *pIndex = n;
338 break;
339 }
340 }
341 return pInfo;
342} // end of wxPaintDC::FindInCache
343
344// find the entry for this DC in the cache (keyed by the window)
345WXHDC wxPaintDC::FindDCInCache(
346 wxWindow* pWin
347)
348{
349 wxPaintDCInfo* pInfo = NULL;
350 size_t nCache = ms_cache.GetCount();
351
352 for (size_t n = 0; n < nCache; n++)
353 {
354 pInfo = &ms_cache[n];
355 if (pInfo->m_hWnd == pWin->GetHWND())
356 {
357 return pInfo->m_hDC;
358 }
359 }
360 return 0;
361} // end of wxPaintDC::FindInCache
362