]> git.saurik.com Git - wxWidgets.git/blame - src/x11/colour.cpp
The bug is no longer there, but leave the workaround in place for
[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
0b5c0e1a
JS
235#if wxUSE_NANOX
236 M_COLDATA->m_color.red = ((unsigned short)red) ;
237 M_COLDATA->m_color.green = ((unsigned short)green) ;
238 M_COLDATA->m_color.blue = ((unsigned short)blue) ;
239#else
3cd0b8c5
RR
240 M_COLDATA->m_color.red = ((unsigned short)red) << SHIFT;
241 M_COLDATA->m_color.green = ((unsigned short)green) << SHIFT;
242 M_COLDATA->m_color.blue = ((unsigned short)blue) << SHIFT;
0b5c0e1a 243#endif
3cd0b8c5 244 M_COLDATA->m_color.pixel = 0;
83df96d6
JS
245}
246
3cd0b8c5
RR
247unsigned char wxColour::Red() const
248{
249 wxCHECK_MSG( Ok(), 0, wxT("invalid colour") );
250
0b5c0e1a
JS
251#if wxUSE_NANOX
252 return (unsigned char) M_COLDATA->m_color.red ;
253#else
3cd0b8c5 254 return (unsigned char)(M_COLDATA->m_color.red >> SHIFT);
0b5c0e1a 255#endif
3cd0b8c5
RR
256}
257
258unsigned char wxColour::Green() const
259{
260 wxCHECK_MSG( Ok(), 0, wxT("invalid colour") );
261
0b5c0e1a
JS
262#if wxUSE_NANOX
263 return (unsigned char) M_COLDATA->m_color.green ;
264#else
3cd0b8c5 265 return (unsigned char)(M_COLDATA->m_color.green >> SHIFT);
0b5c0e1a 266#endif
3cd0b8c5
RR
267}
268
269unsigned char wxColour::Blue() const
270{
271 wxCHECK_MSG( Ok(), 0, wxT("invalid colour") );
272
0b5c0e1a
JS
273#if wxUSE_NANOX
274 return (unsigned char) M_COLDATA->m_color.blue ;
275#else
3cd0b8c5 276 return (unsigned char)(M_COLDATA->m_color.blue >> SHIFT);
0b5c0e1a 277#endif
3cd0b8c5
RR
278}
279
280void wxColour::CalcPixel( WXColormap cmap )
281{
887dd52f
RR
282 wxCHECK_RET( Ok(), wxT("invalid colour") );
283
284 wxCHECK_RET( cmap, wxT("invalid colormap") );
3cd0b8c5
RR
285
286 M_COLDATA->AllocColour( cmap );
287}
288
289unsigned long wxColour::GetPixel() const
290{
291 wxCHECK_MSG( Ok(), 0, wxT("invalid colour") );
292
293 return M_COLDATA->m_color.pixel;
294}
295
296WXColor *wxColour::GetColor() const
297{
298 wxCHECK_MSG( Ok(), (WXColor *) NULL, wxT("invalid colour") );
299
300 return (WXColor*) &M_COLDATA->m_color;
83df96d6 301}