Remove all lines containing cvs/svn "$Id$" keyword.
[wxWidgets.git] / src / x11 / colour.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/x11/colour.cpp
3 // Purpose: wxColour class
4 // Author: Julian Smart, Robert Roebling
5 // Modified by:
6 // Created: 17/09/98
7 // Copyright: (c) Julian Smart, Robert Roebling
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
13
14 #include "wx/colour.h"
15
16 #ifndef WX_PRECOMP
17 #include "wx/app.h"
18 #include "wx/gdicmn.h"
19 #endif
20
21 #include "wx/x11/private.h"
22
23 //-----------------------------------------------------------------------------
24 // wxColour
25 //-----------------------------------------------------------------------------
26
27 class wxColourRefData : public wxGDIRefData
28 {
29 public:
30 wxColourRefData()
31 {
32 m_color.red = 0;
33 m_color.green = 0;
34 m_color.blue = 0;
35 m_color.pixel = 0;
36 m_colormap = NULL;
37 m_hasPixel = false;
38 }
39
40 wxColourRefData(const wxColourRefData& data)
41 {
42 m_color = data.m_color;
43 m_colormap = data.m_colormap;
44 m_hasPixel = data.m_hasPixel;
45 }
46
47 virtual ~wxColourRefData()
48 {
49 FreeColour();
50 }
51
52 bool operator==(const wxColourRefData& data) const
53 {
54 return (m_colormap == data.m_colormap &&
55 m_hasPixel == data.m_hasPixel &&
56 m_color.red == data.m_color.red &&
57 m_color.green == data.m_color.green &&
58 m_color.blue == data.m_color.blue &&
59 m_color.pixel == data.m_color.pixel);
60 }
61
62 void FreeColour();
63 void AllocColour( WXColormap cmap );
64
65 XColor m_color;
66 WXColormap m_colormap;
67 bool m_hasPixel;
68
69 friend class wxColour;
70
71 // reference counter for systems with <= 8-Bit display
72 static unsigned short colMapAllocCounter[ 256 ];
73 };
74
75 unsigned short wxColourRefData::colMapAllocCounter[ 256 ] =
76 {
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, 0, 0, 0, 0,
89 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
90 };
91
92 void wxColourRefData::FreeColour()
93 {
94 if (!m_colormap)
95 return;
96 #if !wxUSE_NANOX
97 if ( wxTheApp &&
98 (wxTheApp->m_visualInfo->m_visualType == GrayScale ||
99 wxTheApp->m_visualInfo->m_visualType == PseudoColor) )
100 {
101 int idx = m_color.pixel;
102 colMapAllocCounter[ idx ] = colMapAllocCounter[ idx ] - 1;
103
104 if (colMapAllocCounter[ idx ] == 0)
105 {
106 unsigned long pixel = m_color.pixel;
107 XFreeColors( wxGlobalDisplay(), (Colormap) m_colormap, &pixel, 1, 0 );
108 }
109 }
110 #endif
111 }
112
113 void wxColourRefData::AllocColour( WXColormap cmap )
114 {
115 if (m_hasPixel && (m_colormap == cmap))
116 return;
117
118 FreeColour();
119
120 #if !wxUSE_NANOX
121 if ((wxTheApp->m_visualInfo->m_visualType == GrayScale) ||
122 (wxTheApp->m_visualInfo->m_visualType == PseudoColor))
123 {
124 m_hasPixel = XAllocColor( wxGlobalDisplay(), (Colormap) cmap, &m_color );
125 int idx = m_color.pixel;
126 colMapAllocCounter[ idx ] = colMapAllocCounter[ idx ] + 1;
127 }
128 else
129 #endif
130 {
131 m_hasPixel = XAllocColor( wxGlobalDisplay(), (Colormap) cmap, &m_color );
132 }
133
134 m_colormap = cmap;
135 }
136
137 //-----------------------------------------------------------------------------
138
139 #define M_COLDATA ((wxColourRefData *)m_refData)
140
141 #define SHIFT (8*(sizeof(short int)-sizeof(char)))
142
143 wxColour::~wxColour()
144 {
145 }
146
147 bool wxColour::operator == ( const wxColour& col ) const
148 {
149 if (m_refData == col.m_refData) return true;
150
151 if (!m_refData || !col.m_refData) return false;
152
153 XColor *own = &(((wxColourRefData*)m_refData)->m_color);
154 XColor *other = &(((wxColourRefData*)col.m_refData)->m_color);
155
156 return (own->red == other->red)
157 && (own->green == other->green)
158 && (own->blue == other->blue) ;
159
160 }
161
162 wxGDIRefData *wxColour::CreateGDIRefData() const
163 {
164 return new wxColourRefData;
165 }
166
167 wxGDIRefData *wxColour::CloneGDIRefData(const wxGDIRefData *data) const
168 {
169 return new wxColourRefData(*(wxColourRefData *)data);
170 }
171
172 void wxColour::InitRGBA(unsigned char red, unsigned char green, unsigned char blue,
173 unsigned char WXUNUSED(alpha))
174 {
175 AllocExclusive();
176
177 #if wxUSE_NANOX
178 M_COLDATA->m_color.red = ((unsigned short)red) ;
179 M_COLDATA->m_color.green = ((unsigned short)green) ;
180 M_COLDATA->m_color.blue = ((unsigned short)blue) ;
181 #else
182 M_COLDATA->m_color.red = ((unsigned short)red) << SHIFT;
183 M_COLDATA->m_color.green = ((unsigned short)green) << SHIFT;
184 M_COLDATA->m_color.blue = ((unsigned short)blue) << SHIFT;
185 #endif
186 M_COLDATA->m_color.pixel = 0;
187 }
188
189 unsigned char wxColour::Red() const
190 {
191 wxCHECK_MSG( IsOk(), 0, wxT("invalid colour") );
192
193 #if wxUSE_NANOX
194 return (unsigned char) M_COLDATA->m_color.red ;
195 #else
196 return (unsigned char)(M_COLDATA->m_color.red >> SHIFT);
197 #endif
198 }
199
200 unsigned char wxColour::Green() const
201 {
202 wxCHECK_MSG( IsOk(), 0, wxT("invalid colour") );
203
204 #if wxUSE_NANOX
205 return (unsigned char) M_COLDATA->m_color.green ;
206 #else
207 return (unsigned char)(M_COLDATA->m_color.green >> SHIFT);
208 #endif
209 }
210
211 unsigned char wxColour::Blue() const
212 {
213 wxCHECK_MSG( IsOk(), 0, wxT("invalid colour") );
214
215 #if wxUSE_NANOX
216 return (unsigned char) M_COLDATA->m_color.blue ;
217 #else
218 return (unsigned char)(M_COLDATA->m_color.blue >> SHIFT);
219 #endif
220 }
221
222 void wxColour::CalcPixel( WXColormap cmap )
223 {
224 wxCHECK_RET( IsOk(), wxT("invalid colour") );
225
226 wxCHECK_RET( cmap, wxT("invalid colormap") );
227
228 M_COLDATA->AllocColour( cmap );
229 }
230
231 unsigned long wxColour::GetPixel() const
232 {
233 wxCHECK_MSG( IsOk(), 0, wxT("invalid colour") );
234
235 return M_COLDATA->m_color.pixel;
236 }
237
238 WXColor *wxColour::GetColor() const
239 {
240 wxCHECK_MSG( IsOk(), NULL, wxT("invalid colour") );
241
242 return (WXColor*) &M_COLDATA->m_color;
243 }
244
245 bool wxColour::FromString(const wxString& name)
246 {
247 Display *dpy = wxGlobalDisplay();
248 WXColormap colormap = wxTheApp->GetMainColormap( dpy );
249 XColor xcol;
250 if ( XParseColor( dpy, (Colormap)colormap, name.mbc_str(), &xcol ) )
251 {
252 UnRef();
253
254 m_refData = new wxColourRefData;
255 M_COLDATA->m_colormap = colormap;
256 M_COLDATA->m_color = xcol;
257 return true;
258 }
259
260 return wxColourBase::FromString(name);
261 }