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