]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/os2/brush.cpp
Correctly recognize when wglChoosePixelFormatARB() fails.
[wxWidgets.git] / src / os2 / brush.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/os2/brush.cpp
3// Purpose: wxBrush
4// Author: David Webster
5// Modified by:
6// Created: 10/13/99
7// RCS-ID: $Id$
8// Copyright: (c) David Webster
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifndef WX_PRECOMP
16 #include <stdio.h>
17 #include "wx/list.h"
18 #include "wx/utils.h"
19 #include "wx/app.h"
20 #include "wx/brush.h"
21 #include "wx/log.h"
22#endif
23
24#include "wx/os2/private.h"
25
26class WXDLLEXPORT wxBrushRefData: public wxGDIRefData
27{
28 friend class WXDLLIMPEXP_FWD_CORE wxBrush;
29public:
30 wxBrushRefData(const wxColour& colour = wxNullColour, wxBrushStyle style = wxBRUSHSTYLE_SOLID);
31 wxBrushRefData(const wxBitmap& stipple);
32 wxBrushRefData(const wxBrushRefData& rData);
33 virtual ~wxBrushRefData();
34
35 bool operator == (const wxBrushRefData& data) const
36 {
37 return (m_nStyle == data.m_nStyle &&
38 m_vStipple.IsSameAs(data.m_vStipple) &&
39 m_vColour == data.m_vColour);
40 }
41
42protected:
43 wxBrushStyle m_nStyle;
44 wxBitmap m_vStipple;
45 wxColour m_vColour;
46 WXHBRUSH m_hBrush; // in OS/2 GPI this will be the PS the pen is associated with
47 AREABUNDLE m_vBundle;
48};
49
50#define M_BRUSHDATA ((wxBrushRefData *)m_refData)
51
52// ============================================================================
53// wxBrushRefData implementation
54// ============================================================================
55
56IMPLEMENT_DYNAMIC_CLASS(wxBrush, wxGDIObject)
57
58// ----------------------------------------------------------------------------
59// wxBrushRefData ctors/dtor
60// ----------------------------------------------------------------------------
61
62wxBrushRefData::wxBrushRefData(const wxColour& colour, wxBrushStyle style)
63 : m_vColour(colour)
64{
65 m_nStyle = style;
66 m_hBrush = 0;
67 memset(&m_vBundle, '\0', sizeof(AREABUNDLE));
68} // end of wxBrushRefData::wxBrushRefData
69
70wxBrushRefData::wxBrushRefData(const wxBitmap& stipple)
71{
72 m_vStipple = stipple;
73 m_nStyle = stipple.GetMask() ? wxBRUSHSTYLE_STIPPLE_MASK_OPAQUE
74 : wxBRUSHSTYLE_STIPPLE;
75
76 m_hBrush = NULL;
77 memset(&m_vBundle, '\0', sizeof(AREABUNDLE));
78}
79
80wxBrushRefData::wxBrushRefData(const wxBrushRefData& rData)
81 : wxGDIRefData(),
82 m_vStipple(rData.m_vStipple),
83 m_vColour(rData.m_vColour)
84{
85 m_nStyle = rData.m_nStyle;
86 m_hBrush = 0;
87 memcpy(&m_vBundle, &rData.m_vBundle, sizeof(AREABUNDLE));
88} // end of wxBrushRefData::wxBrushRefData
89
90wxBrushRefData::~wxBrushRefData()
91{
92} // end of wxBrushRefData::~wxBrushRefData
93
94// ============================================================================
95// wxBrush implementation
96// ============================================================================
97
98// ----------------------------------------------------------------------------
99// wxBrush ctors/dtor
100// ----------------------------------------------------------------------------
101
102wxBrush::wxBrush()
103{
104} // end of wxBrush::wxBrush
105
106wxBrush::~wxBrush()
107{
108} // end of wxBrush::~wxBrush
109
110wxBrush::wxBrush(
111 const wxColour& rColour
112, wxBrushStyle nStyle
113)
114{
115 m_refData = new wxBrushRefData(rColour, nStyle);
116
117 RealizeResource();
118} // end of wxBrush::wxBrush
119
120#if FUTURE_WXWIN_COMPATIBILITY_3_0
121wxBrush::wxBrush(const wxColour& col, int style)
122{
123 m_refData = new wxBrushRefData(col, (wxBrushStyle)style);
124
125 RealizeResource();
126}
127#endif
128
129wxBrush::wxBrush(const wxBitmap& rStipple)
130{
131 m_refData = new wxBrushRefData(rStipple);
132
133 RealizeResource();
134} // end of wxBrush::wxBrush
135
136bool wxBrush::RealizeResource()
137{
138 bool bOk;
139 ERRORID vError;
140 wxString sError;
141
142 if (M_BRUSHDATA && M_BRUSHDATA->m_hBrush == 0L)
143 {
144 SIZEL vSize = {0, 0};
145 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
146 HDC hDC = ::DevOpenDC( vHabmain
147 ,OD_MEMORY
148 ,"*"
149 ,5L
150 ,(PDEVOPENDATA)&vDop
151 ,NULLHANDLE
152 );
153 M_BRUSHDATA->m_hBrush = (WXHPEN)::GpiCreatePS( vHabmain
154 ,hDC
155 ,&vSize
156 ,PU_PELS | GPIT_MICRO | GPIA_ASSOC
157 );
158 }
159 if (M_BRUSHDATA)
160 {
161 //
162 // Set the color table to RGB mode
163 //
164 if (!::GpiCreateLogColorTable( (HPS)M_BRUSHDATA->m_hBrush
165 ,0L
166 ,LCOLF_RGB
167 ,0L
168 ,0L
169 ,NULL
170 ))
171 {
172 vError = ::WinGetLastError(vHabmain);
173 sError = wxPMErrorToStr(vError);
174 wxLogError(wxT("Unable to set current color table to RGB mode. Error: %s\n"), sError.c_str());
175 return false;
176 }
177
178 if (M_BRUSHDATA->m_nStyle==wxTRANSPARENT)
179 {
180 return true;
181 }
182 COLORREF vPmColour = 0L;
183
184 vPmColour = M_BRUSHDATA->m_vColour.GetPixel() ;
185
186 M_BRUSHDATA->m_vBundle.usSet = LCID_DEFAULT;
187 switch (M_BRUSHDATA->m_nStyle)
188 {
189 case wxTRANSPARENT:
190 M_BRUSHDATA->m_hBrush = NULL; // Must always select a suitable background brush
191 break; // - could choose white always for a quick solution
192
193 case wxBDIAGONAL_HATCH:
194 M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_DIAG3;
195 break;
196
197 case wxCROSSDIAG_HATCH:
198 M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_DIAGHATCH;
199 break;
200
201 case wxFDIAGONAL_HATCH:
202 M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_DIAG1;
203 break;
204
205 case wxCROSS_HATCH:
206 M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_HATCH;
207 break;
208
209 case wxHORIZONTAL_HATCH:
210 M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_HORIZ;
211 break;
212
213 case wxVERTICAL_HATCH:
214 M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_VERT;
215 break;
216
217 case wxSTIPPLE:
218 if (M_BRUSHDATA->m_vStipple.Ok())
219 {
220 ::GpiSetBitmapId( M_BRUSHDATA->m_hBrush
221 ,(USHORT)M_BRUSHDATA->m_vStipple.GetHBITMAP()
222 ,(USHORT)M_BRUSHDATA->m_vStipple.GetId()
223 );
224 ::GpiSetPatternSet( M_BRUSHDATA->m_hBrush
225 ,(USHORT)M_BRUSHDATA->m_vStipple.GetId()
226 );
227 }
228 else
229 M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_SOLID;
230 break ;
231
232 case wxSOLID:
233 default:
234 M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_SOLID;
235 break;
236 }
237#ifdef WXDEBUG_CREATE
238 if (M_BRUSHDATA->m_hBrush==NULL) wxError("Cannot create brush","Internal error") ;
239#endif
240 M_BRUSHDATA->m_vBundle.lColor = vPmColour;
241 M_BRUSHDATA->m_vBundle.lBackColor = RGB_WHITE;
242 M_BRUSHDATA->m_vBundle.usMixMode = FM_OVERPAINT;
243 M_BRUSHDATA->m_vBundle.usBackMixMode = BM_OVERPAINT;
244
245 bOk = (bool)::GpiSetAttrs( M_BRUSHDATA->m_hBrush
246 ,PRIM_AREA
247 ,ABB_COLOR | ABB_BACK_COLOR | ABB_MIX_MODE | ABB_BACK_MIX_MODE |
248 ABB_SET | ABB_SYMBOL | ABB_REF_POINT
249 ,ABB_SET | ABB_SYMBOL | ABB_REF_POINT
250 ,&M_BRUSHDATA->m_vBundle
251 );
252 if (!bOk)
253 {
254 vError = ::WinGetLastError(vHabmain);
255 sError = wxPMErrorToStr(vError);
256 wxLogError(wxT("Can't set Gpi attributes for an AREABUNDLE. Error: %s\n"), sError.c_str());
257 }
258 return bOk;
259 }
260 return false;
261} // end of wxBrush::RealizeResource
262
263// ----------------------------------------------------------------------------
264// wxBrush accessors
265// ----------------------------------------------------------------------------
266
267wxColour wxBrush::GetColour() const
268{
269 wxCHECK_MSG( Ok(), wxNullColour, wxT("invalid brush") );
270
271 return M_BRUSHDATA->m_vColour;
272}
273
274wxBrushStyle wxBrush::GetStyle() const
275{
276 wxCHECK_MSG( Ok(), wxBRUSHSTYLE_INVALID, wxT("invalid brush") );
277
278 return M_BRUSHDATA->m_nStyle;
279}
280
281wxBitmap *wxBrush::GetStipple() const
282{
283 wxCHECK_MSG( Ok(), NULL, wxT("invalid brush") );
284
285 return &(M_BRUSHDATA->m_vStipple);
286}
287
288int wxBrush::GetPS() const
289{
290 wxCHECK_MSG( Ok(), 0, wxT("invalid brush") );
291
292 return M_BRUSHDATA->m_hBrush;
293}
294
295WXHANDLE wxBrush::GetResourceHandle() const
296{
297 wxCHECK_MSG( Ok(), 0, wxT("invalid brush") );
298
299 return (WXHANDLE)M_BRUSHDATA->m_hBrush;
300} // end of wxBrush::GetResourceHandle
301
302bool wxBrush::FreeResource( bool WXUNUSED(bForce) )
303{
304 if (M_BRUSHDATA && (M_BRUSHDATA->m_hBrush != 0))
305 {
306 M_BRUSHDATA->m_hBrush = 0;
307 return true;
308 }
309 else return false;
310} // end of wxBrush::FreeResource
311
312bool wxBrush::IsFree() const
313{
314 return (M_BRUSHDATA && (M_BRUSHDATA->m_hBrush == 0));
315} // end of wxBrush::IsFree
316
317// ----------------------------------------------------------------------------
318// wxBrush setters
319// ----------------------------------------------------------------------------
320
321void wxBrush::SetColour( const wxColour& rColour )
322{
323 AllocExclusive();
324 M_BRUSHDATA->m_vColour = rColour;
325 RealizeResource();
326}
327
328void wxBrush::SetColour(unsigned char cRed, unsigned char cGreen, unsigned char cBlue)
329{
330 AllocExclusive();
331 M_BRUSHDATA->m_vColour.Set( cRed, cGreen, cBlue );
332 RealizeResource();
333} // end of wxBrush::SetColour
334
335void wxBrush::SetStyle(wxBrushStyle nStyle)
336{
337 AllocExclusive();
338 M_BRUSHDATA->m_nStyle = nStyle;
339 RealizeResource();
340} // end of wxBrush::SetStyle
341
342void wxBrush::SetStipple(
343 const wxBitmap& rStipple
344)
345{
346 AllocExclusive();
347 M_BRUSHDATA->m_vStipple = rStipple;
348 RealizeResource();
349} // end of wxBrush::SetStipple
350
351void wxBrush::SetPS(
352 HPS hPS
353)
354{
355 AllocExclusive();
356 if (M_BRUSHDATA->m_hBrush)
357 ::GpiDestroyPS(M_BRUSHDATA->m_hBrush);
358 M_BRUSHDATA->m_hBrush = hPS;
359 RealizeResource();
360} // end of WxWinGdi_CPen::SetPS
361
362// ----------------------------------------------------------------------------
363// wxBrush house keeping stuff
364// ----------------------------------------------------------------------------
365
366bool wxBrush::operator == (
367 const wxBrush& brush
368) const
369{
370 if (m_refData == brush.m_refData) return true;
371
372 if (!m_refData || !brush.m_refData) return false;
373
374 return ( *(wxBrushRefData*)m_refData == *(wxBrushRefData*)brush.m_refData );
375} // end of wxBrush::operator ==
376
377wxGDIRefData *wxBrush::CreateGDIRefData() const
378{
379 return new wxBrushRefData;
380}
381
382wxGDIRefData *wxBrush::CloneGDIRefData(const wxGDIRefData *data) const
383{
384 return new wxBrushRefData(*(const wxBrushRefData *)data);
385}