]> git.saurik.com Git - wxWidgets.git/blame - src/x11/colour.cpp
Crash fix under VC++
[wxWidgets.git] / src / x11 / colour.cpp
CommitLineData
83df96d6
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: colour.cpp
3// Purpose: wxColour class
3cd0b8c5 4// Author: Julian Smart, Robert Roebling
83df96d6
JS
5// Modified by:
6// Created: 17/09/98
7// RCS-ID: $Id$
3cd0b8c5 8// Copyright: (c) Julian Smart, Robert Roebling
65571936 9// Licence: wxWindows licence
83df96d6
JS
10/////////////////////////////////////////////////////////////////////////////
11
83df96d6 12
14f355c2 13#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
83df96d6
JS
14#pragma implementation "colour.h"
15#endif
16
17#include "wx/gdicmn.h"
887dd52f 18#include "wx/app.h"
83df96d6 19
7266b672 20#include "wx/x11/private.h"
83df96d6 21
3cd0b8c5
RR
22//-----------------------------------------------------------------------------
23// wxColour
24//-----------------------------------------------------------------------------
83df96d6 25
3cd0b8c5 26class wxColourRefData: public wxObjectRefData
83df96d6 27{
3cd0b8c5
RR
28public:
29 wxColourRefData()
30 {
31 m_color.red = 0;
32 m_color.green = 0;
33 m_color.blue = 0;
34 m_color.pixel = 0;
35 m_colormap = (WXColormap *) NULL;
aad6765c 36 m_hasPixel = false;
3cd0b8c5 37 }
d5cf34f4
JS
38 wxColourRefData(const wxColourRefData& data):
39 wxObjectRefData()
40 {
41 m_color = data.m_color;
42 m_colormap = data.m_colormap;
43 m_hasPixel = data.m_hasPixel;
44 }
aad6765c 45
3cd0b8c5
RR
46 ~wxColourRefData()
47 {
48 FreeColour();
49 }
83df96d6 50
3cd0b8c5
RR
51 bool operator == (const wxColourRefData& data) const
52 {
53 return (m_colormap == data.m_colormap &&
54 m_hasPixel == data.m_hasPixel &&
55 m_color.red == data.m_color.red &&
56 m_color.green == data.m_color.green &&
57 m_color.blue == data.m_color.blue &&
58 m_color.pixel == data.m_color.pixel);
59 }
aad6765c 60
3cd0b8c5
RR
61 void FreeColour();
62 void AllocColour( WXColormap cmap );
63
64 XColor m_color;
65 WXColormap m_colormap;
66 bool m_hasPixel;
67
68 friend class wxColour;
69
70 // reference counter for systems with <= 8-Bit display
71 static unsigned short colMapAllocCounter[ 256 ];
72};
73
aad6765c
JS
74unsigned short wxColourRefData::colMapAllocCounter[ 256 ] =
75{
3cd0b8c5
RR
76 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
77 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
78 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
79 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
80 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
81 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
82 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
83 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
84 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
85 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
86 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
87 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
88 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
89};
90
91void wxColourRefData::FreeColour()
83df96d6 92{
dc4025af
RR
93 if (!m_colormap)
94 return;
aad6765c 95#if !wxUSE_NANOX
ac7f6cf0
VZ
96 if ( wxTheApp &&
97 (wxTheApp->m_visualInfo->m_visualType == GrayScale ||
98 wxTheApp->m_visualInfo->m_visualType == PseudoColor) )
3cd0b8c5 99 {
dc4025af
RR
100 int idx = m_color.pixel;
101 colMapAllocCounter[ idx ] = colMapAllocCounter[ idx ] - 1;
aad6765c 102
dc4025af
RR
103 if (colMapAllocCounter[ idx ] == 0)
104 {
105 unsigned long pixel = m_color.pixel;
106 XFreeColors( wxGlobalDisplay(), (Colormap) m_colormap, &pixel, 1, 0 );
3cd0b8c5 107 }
3cd0b8c5 108 }
8601b2e1 109#endif
83df96d6
JS
110}
111
3cd0b8c5 112void wxColourRefData::AllocColour( WXColormap cmap )
83df96d6 113{
3cd0b8c5
RR
114 if (m_hasPixel && (m_colormap == cmap))
115 return;
116
117 FreeColour();
118
8601b2e1 119#if !wxUSE_NANOX
9ce8d6a2
MB
120 if ((wxTheApp->m_visualInfo->m_visualType == GrayScale) ||
121 (wxTheApp->m_visualInfo->m_visualType == PseudoColor))
3cd0b8c5 122 {
dc4025af 123 m_hasPixel = XAllocColor( wxGlobalDisplay(), (Colormap) cmap, &m_color );
3cd0b8c5
RR
124 int idx = m_color.pixel;
125 colMapAllocCounter[ idx ] = colMapAllocCounter[ idx ] + 1;
126 }
127 else
8601b2e1 128#endif
3cd0b8c5
RR
129 {
130 m_hasPixel = XAllocColor( wxGlobalDisplay(), (Colormap) cmap, &m_color );
131 }
aad6765c 132
3cd0b8c5 133 m_colormap = cmap;
83df96d6
JS
134}
135
3cd0b8c5
RR
136//-----------------------------------------------------------------------------
137
138#define M_COLDATA ((wxColourRefData *)m_refData)
139
140#define SHIFT (8*(sizeof(short int)-sizeof(char)))
141
142IMPLEMENT_DYNAMIC_CLASS(wxColour,wxGDIObject)
143
144wxColour::wxColour( unsigned char red, unsigned char green, unsigned char blue )
83df96d6 145{
3cd0b8c5 146 m_refData = new wxColourRefData();
0b5c0e1a
JS
147#if wxUSE_NANOX
148 M_COLDATA->m_color.red = ((unsigned short)red) ;
149 M_COLDATA->m_color.green = ((unsigned short)green) ;
150 M_COLDATA->m_color.blue = ((unsigned short)blue) ;
aad6765c 151#else
3cd0b8c5
RR
152 M_COLDATA->m_color.red = ((unsigned short)red) << SHIFT;
153 M_COLDATA->m_color.green = ((unsigned short)green) << SHIFT;
154 M_COLDATA->m_color.blue = ((unsigned short)blue) << SHIFT;
0b5c0e1a 155#endif
3cd0b8c5 156 M_COLDATA->m_color.pixel = 0;
83df96d6
JS
157}
158
564a150b
VZ
159/* static */
160wxColour wxColour::CreateByName(const wxString& name)
83df96d6 161{
564a150b
VZ
162 wxColour col;
163
164 Display *dpy = wxGlobalDisplay();
165 WXColormap colormap = wxTheApp->GetMainColormap( dpy );
166 XColor xcol;
167 if ( XParseColor( dpy, (Colormap)colormap, name.mb_str(), &xcol ) )
83df96d6 168 {
564a150b
VZ
169 wxColourRefData *refData = new wxColourRefData;
170 refData->m_colormap = colormap;
171 refData->m_color = xcol;
172 col.m_refData = refData;
83df96d6 173 }
564a150b
VZ
174
175 return col;
176}
177
178void wxColour::InitFromName( const wxString &colourName )
179{
180 // check the cache first
181 wxColour col;
182 if ( wxTheColourDatabase )
83df96d6 183 {
564a150b
VZ
184 col = wxTheColourDatabase->Find(colourName);
185 }
3cd0b8c5 186
564a150b
VZ
187 if ( !col.Ok() )
188 {
189 col = CreateByName(colourName);
190 }
3cd0b8c5 191
564a150b
VZ
192 if ( col.Ok() )
193 {
194 *this = col;
195 }
196 else
197 {
198 wxFAIL_MSG( wxT("wxColour: couldn't find colour") );
83df96d6
JS
199 }
200}
201
3cd0b8c5 202wxColour::~wxColour()
83df96d6
JS
203{
204}
205
3cd0b8c5 206bool wxColour::operator == ( const wxColour& col ) const
83df96d6 207{
aad6765c 208 if (m_refData == col.m_refData) return true;
3cd0b8c5 209
aad6765c 210 if (!m_refData || !col.m_refData) return false;
3cd0b8c5
RR
211
212 XColor *own = &(((wxColourRefData*)m_refData)->m_color);
213 XColor *other = &(((wxColourRefData*)col.m_refData)->m_color);
3cd0b8c5 214
aad6765c
JS
215 return (own->red == other->red)
216 && (own->green == other->green)
d35dec9b 217 && (own->blue == other->blue) ;
aad6765c 218
83df96d6
JS
219}
220
3cd0b8c5
RR
221wxObjectRefData *wxColour::CreateRefData() const
222{
223 return new wxColourRefData;
224}
83df96d6 225
3cd0b8c5
RR
226wxObjectRefData *wxColour::CloneRefData(const wxObjectRefData *data) const
227{
228 return new wxColourRefData(*(wxColourRefData *)data);
229}
83df96d6 230
3cd0b8c5 231void wxColour::Set( unsigned char red, unsigned char green, unsigned char blue )
83df96d6 232{
3cd0b8c5 233 AllocExclusive();
aad6765c 234
3cd0b8c5 235 m_refData = new wxColourRefData();
0b5c0e1a
JS
236#if wxUSE_NANOX
237 M_COLDATA->m_color.red = ((unsigned short)red) ;
238 M_COLDATA->m_color.green = ((unsigned short)green) ;
239 M_COLDATA->m_color.blue = ((unsigned short)blue) ;
240#else
3cd0b8c5
RR
241 M_COLDATA->m_color.red = ((unsigned short)red) << SHIFT;
242 M_COLDATA->m_color.green = ((unsigned short)green) << SHIFT;
243 M_COLDATA->m_color.blue = ((unsigned short)blue) << SHIFT;
0b5c0e1a 244#endif
3cd0b8c5 245 M_COLDATA->m_color.pixel = 0;
83df96d6
JS
246}
247
3cd0b8c5
RR
248unsigned char wxColour::Red() const
249{
250 wxCHECK_MSG( Ok(), 0, wxT("invalid colour") );
251
0b5c0e1a
JS
252#if wxUSE_NANOX
253 return (unsigned char) M_COLDATA->m_color.red ;
254#else
3cd0b8c5 255 return (unsigned char)(M_COLDATA->m_color.red >> SHIFT);
0b5c0e1a 256#endif
3cd0b8c5
RR
257}
258
259unsigned char wxColour::Green() const
260{
261 wxCHECK_MSG( Ok(), 0, wxT("invalid colour") );
262
0b5c0e1a
JS
263#if wxUSE_NANOX
264 return (unsigned char) M_COLDATA->m_color.green ;
265#else
3cd0b8c5 266 return (unsigned char)(M_COLDATA->m_color.green >> SHIFT);
0b5c0e1a 267#endif
3cd0b8c5
RR
268}
269
270unsigned char wxColour::Blue() const
271{
272 wxCHECK_MSG( Ok(), 0, wxT("invalid colour") );
273
0b5c0e1a
JS
274#if wxUSE_NANOX
275 return (unsigned char) M_COLDATA->m_color.blue ;
276#else
3cd0b8c5 277 return (unsigned char)(M_COLDATA->m_color.blue >> SHIFT);
0b5c0e1a 278#endif
3cd0b8c5
RR
279}
280
281void wxColour::CalcPixel( WXColormap cmap )
282{
887dd52f
RR
283 wxCHECK_RET( Ok(), wxT("invalid colour") );
284
285 wxCHECK_RET( cmap, wxT("invalid colormap") );
3cd0b8c5
RR
286
287 M_COLDATA->AllocColour( cmap );
288}
289
290unsigned long wxColour::GetPixel() const
291{
292 wxCHECK_MSG( Ok(), 0, wxT("invalid colour") );
293
294 return M_COLDATA->m_color.pixel;
295}
296
297WXColor *wxColour::GetColor() const
298{
299 wxCHECK_MSG( Ok(), (WXColor *) NULL, wxT("invalid colour") );
300
301 return (WXColor*) &M_COLDATA->m_color;
83df96d6 302}