]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/colour.cpp
Fix memory leak when a spacer is added, and crash when a window is added before wxSiz...
[wxWidgets.git] / src / gtk1 / colour.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: colour.cpp
3// Purpose:
4// Author: Robert Roebling
dbf858b5
RR
5// Id: $Id$
6// Copyright: (c) 1998 Robert Roebling
65571936 7// Licence: wxWindows licence
c801d85f
KB
8/////////////////////////////////////////////////////////////////////////////
9
10
14f355c2 11#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
c801d85f
KB
12#pragma implementation "colour.h"
13#endif
14
14f355c2
VS
15// For compilers that support precompilation, includes "wx.h".
16#include "wx/wxprec.h"
17
ed39ff57 18#include "wx/colour.h"
e1bf3ad3 19#include "wx/gdicmn.h"
2b5f62a0 20#include "wx/gtk/private.h"
c801d85f 21
071a2d78 22#include <gdk/gdk.h>
307fc8d5 23#include <gdk/gdkx.h>
071a2d78 24#include <gdk/gdkprivate.h>
c801d85f
KB
25
26//-----------------------------------------------------------------------------
27// wxColour
28//-----------------------------------------------------------------------------
29
30class wxColourRefData: public wxObjectRefData
31{
47c93b63 32public:
c89f5c02
RR
33 wxColourRefData()
34 {
35 m_color.red = 0;
36 m_color.green = 0;
37 m_color.blue = 0;
38 m_color.pixel = 0;
39 m_colormap = (GdkColormap *) NULL;
aad6765c 40 m_hasPixel = false;
c89f5c02 41 }
4e6b8309 42
dbb846c6 43 wxColourRefData(const wxColourRefData& data)
d84afea9 44 : wxObjectRefData()
dbb846c6
VZ
45 {
46 m_color = data.m_color;
47 m_colormap = data.m_colormap;
48 m_hasPixel = data.m_hasPixel;
49 }
50
c89f5c02
RR
51 ~wxColourRefData()
52 {
53 FreeColour();
54 }
15248e43 55
c89f5c02
RR
56 bool operator == (const wxColourRefData& data) const
57 {
58 return (m_colormap == data.m_colormap &&
59 m_hasPixel == data.m_hasPixel &&
60 m_color.red == data.m_color.red &&
61 m_color.green == data.m_color.green &&
62 m_color.blue == data.m_color.blue &&
63 m_color.pixel == data.m_color.pixel);
64 }
4e6b8309 65
68dda785 66 void FreeColour();
d13fd3e4 67 void AllocColour( GdkColormap* cmap );
8bbe427f 68
c801d85f
KB
69 GdkColor m_color;
70 GdkColormap *m_colormap;
71 bool m_hasPixel;
8bbe427f 72
f6bcfd97 73 friend class wxColour;
d13fd3e4
VZ
74
75 // reference counter for systems with <= 8-Bit display
76 static gushort colMapAllocCounter[ 256 ];
77};
78
4e6b8309
VZ
79gushort wxColourRefData::colMapAllocCounter[ 256 ] =
80{
d13fd3e4
VZ
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, 0, 0, 0, 0,
90 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
91 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
92 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
93 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
c801d85f
KB
94};
95
68dda785 96void wxColourRefData::FreeColour()
c801d85f 97{
47c93b63
RR
98 if (m_colormap)
99 {
100#ifdef __WXGTK20__
101 if ((m_colormap->visual->type == GDK_VISUAL_GRAYSCALE) ||
102 (m_colormap->visual->type == GDK_VISUAL_PSEUDO_COLOR))
103#else
104 GdkColormapPrivate *private_colormap = (GdkColormapPrivate*) m_colormap;
105 if ((private_colormap->visual->type == GDK_VISUAL_GRAYSCALE) ||
106 (private_colormap->visual->type == GDK_VISUAL_PSEUDO_COLOR))
107#endif
108 {
d13fd3e4
VZ
109 int idx = m_color.pixel;
110 colMapAllocCounter[ idx ] = colMapAllocCounter[ idx ] - 1;
4e6b8309 111
d13fd3e4 112 if (colMapAllocCounter[ idx ] == 0)
47c93b63
RR
113 gdk_colormap_free_colors( m_colormap, &m_color, 1 );
114 }
115 }
ff7b1510 116}
c801d85f 117
d13fd3e4
VZ
118void wxColourRefData::AllocColour( GdkColormap *cmap )
119{
120 if (m_hasPixel && (m_colormap == cmap))
121 return;
122
123 FreeColour();
4e6b8309 124
d13fd3e4 125#ifdef __WXGTK20__
31c8af3a
VZ
126 if ( (cmap->visual->type == GDK_VISUAL_GRAYSCALE) ||
127 (cmap->visual->type == GDK_VISUAL_PSEUDO_COLOR) )
d13fd3e4
VZ
128#else
129 GdkColormapPrivate *private_colormap = (GdkColormapPrivate*) cmap;
130 if ((private_colormap->visual->type == GDK_VISUAL_GRAYSCALE) ||
131 (private_colormap->visual->type == GDK_VISUAL_PSEUDO_COLOR))
132#endif
133 {
134 m_hasPixel = gdk_colormap_alloc_color( cmap, &m_color, FALSE, TRUE );
135 int idx = m_color.pixel;
136 colMapAllocCounter[ idx ] = colMapAllocCounter[ idx ] + 1;
137 }
138 else
139 {
140 m_hasPixel = gdk_color_alloc( cmap, &m_color );
141 }
142 m_colormap = cmap;
143}
144
c801d85f
KB
145//-----------------------------------------------------------------------------
146
147#define M_COLDATA ((wxColourRefData *)m_refData)
148
3b9faf4c
VS
149// GDK's values are in 0..65535 range, our are in 0..255
150#define SHIFT 8
c801d85f
KB
151
152IMPLEMENT_DYNAMIC_CLASS(wxColour,wxGDIObject)
153
4b5f3fe6 154wxColour::wxColour( unsigned char red, unsigned char green, unsigned char blue )
c801d85f 155{
1ecc4d80
RR
156 m_refData = new wxColourRefData();
157 M_COLDATA->m_color.red = ((unsigned short)red) << SHIFT;
158 M_COLDATA->m_color.green = ((unsigned short)green) << SHIFT;
159 M_COLDATA->m_color.blue = ((unsigned short)blue) << SHIFT;
160 M_COLDATA->m_color.pixel = 0;
ff7b1510 161}
8bbe427f 162
4e6b8309
VZ
163/* static */
164wxColour wxColour::CreateByName(const wxString& name)
165{
166 wxColour col;
167
168 GdkColor colGDK;
169 if ( gdk_color_parse( wxGTK_CONV( name ), &colGDK ) )
170 {
171 wxColourRefData *refData = new wxColourRefData;
172 refData->m_color = colGDK;
173 col.m_refData = refData;
174 }
175
176 return col;
177}
222ed1d6
MB
178
179
68dda785 180void wxColour::InitFromName( const wxString &colourName )
c801d85f 181{
4e6b8309
VZ
182 // check the cache first
183 wxColour col;
184 if ( wxTheColourDatabase )
c801d85f 185 {
4e6b8309 186 col = wxTheColourDatabase->Find(colourName);
1ecc4d80 187 }
15248e43 188
4e6b8309
VZ
189 if ( !col.Ok() )
190 {
191 col = CreateByName(colourName);
192 }
15248e43 193
4e6b8309
VZ
194 if ( col.Ok() )
195 {
196 *this = col;
197 }
198 else
199 {
200 wxFAIL_MSG( wxT("wxColour: couldn't find colour") );
ff7b1510 201 }
ff7b1510 202}
c801d85f 203
68dda785 204wxColour::~wxColour()
c801d85f 205{
ff7b1510 206}
c801d85f 207
33b64e6f 208bool wxColour::operator == ( const wxColour& col ) const
8bbe427f 209{
4e6b8309 210 if (m_refData == col.m_refData)
aad6765c 211 return true;
15248e43 212
4e6b8309 213 if (!m_refData || !col.m_refData)
aad6765c 214 return false;
15248e43 215
2b62ab35
RR
216 GdkColor *own = &(((wxColourRefData*)m_refData)->m_color);
217 GdkColor *other = &(((wxColourRefData*)col.m_refData)->m_color);
4e6b8309
VZ
218 return own->red == other->red &&
219 own->blue == other->blue &&
220 own->green == other->green;
ff7b1510 221}
c801d85f 222
c89f5c02
RR
223wxObjectRefData *wxColour::CreateRefData() const
224{
225 return new wxColourRefData;
226}
227
228wxObjectRefData *wxColour::CloneRefData(const wxObjectRefData *data) const
8bbe427f 229{
c89f5c02 230 return new wxColourRefData(*(wxColourRefData *)data);
ff7b1510 231}
c801d85f 232
4b5f3fe6 233void wxColour::Set( unsigned char red, unsigned char green, unsigned char blue )
c801d85f 234{
c89f5c02 235 AllocExclusive();
4e6b8309 236
1ecc4d80
RR
237 M_COLDATA->m_color.red = ((unsigned short)red) << SHIFT;
238 M_COLDATA->m_color.green = ((unsigned short)green) << SHIFT;
239 M_COLDATA->m_color.blue = ((unsigned short)blue) << SHIFT;
240 M_COLDATA->m_color.pixel = 0;
4e6b8309 241
2b5f62a0 242 M_COLDATA->m_colormap = (GdkColormap*) NULL;
aad6765c 243 M_COLDATA->m_hasPixel = false;
ff7b1510 244}
c801d85f 245
68dda785 246unsigned char wxColour::Red() const
c801d85f 247{
223d09f6 248 wxCHECK_MSG( Ok(), 0, wxT("invalid colour") );
8bbe427f 249
1ecc4d80 250 return (unsigned char)(M_COLDATA->m_color.red >> SHIFT);
ff7b1510 251}
c801d85f 252
68dda785 253unsigned char wxColour::Green() const
c801d85f 254{
223d09f6 255 wxCHECK_MSG( Ok(), 0, wxT("invalid colour") );
8bbe427f 256
1ecc4d80 257 return (unsigned char)(M_COLDATA->m_color.green >> SHIFT);
ff7b1510 258}
c801d85f 259
68dda785 260unsigned char wxColour::Blue() const
c801d85f 261{
223d09f6 262 wxCHECK_MSG( Ok(), 0, wxT("invalid colour") );
8bbe427f 263
1ecc4d80 264 return (unsigned char)(M_COLDATA->m_color.blue >> SHIFT);
ff7b1510 265}
c801d85f 266
c801d85f
KB
267void wxColour::CalcPixel( GdkColormap *cmap )
268{
1ecc4d80 269 if (!Ok()) return;
8bbe427f 270
d13fd3e4 271 M_COLDATA->AllocColour( cmap );
ff7b1510 272}
c801d85f 273
68dda785 274int wxColour::GetPixel() const
c801d85f 275{
223d09f6 276 wxCHECK_MSG( Ok(), 0, wxT("invalid colour") );
8bbe427f 277
1ecc4d80 278 return M_COLDATA->m_color.pixel;
ff7b1510 279}
c801d85f 280
68dda785 281GdkColor *wxColour::GetColor() const
c801d85f 282{
223d09f6 283 wxCHECK_MSG( Ok(), (GdkColor *) NULL, wxT("invalid colour") );
8bbe427f 284
1ecc4d80 285 return &M_COLDATA->m_color;
ff7b1510 286}
c801d85f
KB
287
288