]> git.saurik.com Git - wxWidgets.git/blame - src/common/platinfo.cpp
fixing overrelease and out-of-bounds write, fixes #13725
[wxWidgets.git] / src / common / platinfo.cpp
CommitLineData
8bb6b2c0
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/common/platinfo.cpp
3// Purpose: implements wxPlatformInfo class
4// Author: Francesco Montorsi
5// Modified by:
6// Created: 07.07.2006 (based on wxToolkitInfo)
7// RCS-ID: $Id$
8// Copyright: (c) 2006 Francesco Montorsi
526954c5 9// Licence: wxWindows licence
8bb6b2c0
VZ
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// for compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
f566c8e2
PC
27#include "wx/platinfo.h"
28
8bb6b2c0 29#ifndef WX_PRECOMP
f566c8e2 30 #include "wx/app.h"
8bb6b2c0
VZ
31 #include "wx/utils.h"
32#endif //WX_PRECOMP
33
8bb6b2c0
VZ
34#include "wx/apptrait.h"
35
449090b5
VZ
36// global object
37// VERY IMPORTANT: do not use the default constructor since it would
38// try to init the wxPlatformInfo instance using
39// gs_platInfo itself!
40static wxPlatformInfo gs_platInfo(wxPORT_UNKNOWN);
41
8bb6b2c0
VZ
42// ----------------------------------------------------------------------------
43// constants
44// ----------------------------------------------------------------------------
45
8f493187 46static const wxChar* const wxOperatingSystemIdNames[] =
8bb6b2c0 47{
9a83f860
VZ
48 wxT("Apple Mac OS"),
49 wxT("Apple Mac OS X"),
8bb6b2c0 50
9a83f860
VZ
51 wxT("Microsoft Windows 9X"),
52 wxT("Microsoft Windows NT"),
53 wxT("Microsoft Windows Micro"),
54 wxT("Microsoft Windows CE"),
8bb6b2c0 55
9a83f860
VZ
56 wxT("Linux"),
57 wxT("FreeBSD"),
58 wxT("OpenBSD"),
59 wxT("NetBSD"),
8bb6b2c0 60
9a83f860
VZ
61 wxT("SunOS"),
62 wxT("AIX"),
63 wxT("HPUX"),
8bb6b2c0 64
9a83f860
VZ
65 wxT("Other Unix"),
66 wxT("Other Unix"),
7528971e 67
9a83f860
VZ
68 wxT("DOS"),
69 wxT("OS/2"),
8bb6b2c0
VZ
70};
71
8f493187 72static const wxChar* const wxPortIdNames[] =
8bb6b2c0 73{
9a83f860
VZ
74 wxT("wxBase"),
75 wxT("wxMSW"),
76 wxT("wxMotif"),
77 wxT("wxGTK"),
0e1f8ea4 78 wxT("wxDFB"),
9a83f860
VZ
79 wxT("wxX11"),
80 wxT("wxOS2"),
81 wxT("wxMac"),
82 wxT("wxCocoa"),
83 wxT("wxWinCE"),
8bb6b2c0
VZ
84};
85
8f493187 86static const wxChar* const wxArchitectureNames[] =
8bb6b2c0 87{
9a83f860
VZ
88 wxT("32 bit"),
89 wxT("64 bit")
8bb6b2c0
VZ
90};
91
8f493187 92static const wxChar* const wxEndiannessNames[] =
8bb6b2c0 93{
9a83f860
VZ
94 wxT("Big endian"),
95 wxT("Little endian"),
96 wxT("PDP endian")
8bb6b2c0
VZ
97};
98
99// ----------------------------------------------------------------------------
100// local functions
101// ----------------------------------------------------------------------------
102
23790a2a
FM
103// returns the logarithm in base 2 of 'value'; this maps the enum values to the
104// corresponding indexes of the string arrays above
78e9b418 105static unsigned wxGetIndexFromEnumValue(int value)
8bb6b2c0 106{
9a83f860 107 wxCHECK_MSG( value, (unsigned)-1, wxT("invalid enum value") );
8bb6b2c0
VZ
108
109 int n = 0;
110 while ( !(value & 1) )
111 {
112 value >>= 1;
113 n++;
114 }
115
9a83f860 116 wxASSERT_MSG( value == 1, wxT("more than one bit set in enum value") );
8bb6b2c0
VZ
117
118 return n;
119}
120
121// ----------------------------------------------------------------------------
122// wxPlatformInfo
123// ----------------------------------------------------------------------------
124
125wxPlatformInfo::wxPlatformInfo()
126{
449090b5
VZ
127 // just copy platform info for currently running platform
128 *this = Get();
8bb6b2c0
VZ
129}
130
131wxPlatformInfo::wxPlatformInfo(wxPortId pid, int tkMajor, int tkMinor,
132 wxOperatingSystemId id, int osMajor, int osMinor,
133 wxArchitecture arch,
b98bd6af
VS
134 wxEndianness endian,
135 bool usingUniversal)
8bb6b2c0
VZ
136{
137 m_tkVersionMajor = tkMajor;
138 m_tkVersionMinor = tkMinor;
139 m_port = pid;
b98bd6af 140 m_usingUniversal = usingUniversal;
8bb6b2c0
VZ
141
142 m_os = id;
143 m_osVersionMajor = osMajor;
144 m_osVersionMinor = osMinor;
145
146 m_endian = endian;
147 m_arch = arch;
148}
149
150bool wxPlatformInfo::operator==(const wxPlatformInfo &t) const
151{
152 return m_tkVersionMajor == t.m_tkVersionMajor &&
153 m_tkVersionMinor == t.m_tkVersionMinor &&
154 m_osVersionMajor == t.m_osVersionMajor &&
155 m_osVersionMinor == t.m_osVersionMinor &&
156 m_os == t.m_os &&
23790a2a
FM
157 m_osDesc == t.m_osDesc &&
158 m_ldi == t.m_ldi &&
159 m_desktopEnv == t.m_desktopEnv &&
8bb6b2c0 160 m_port == t.m_port &&
b98bd6af 161 m_usingUniversal == t.m_usingUniversal &&
8bb6b2c0
VZ
162 m_arch == t.m_arch &&
163 m_endian == t.m_endian;
164}
165
449090b5
VZ
166void wxPlatformInfo::InitForCurrentPlatform()
167{
168 // autodetect all informations
169 const wxAppTraits * const traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
170 if ( !traits )
171 {
9a83f860 172 wxFAIL_MSG( wxT("failed to initialize wxPlatformInfo") );
449090b5
VZ
173
174 m_port = wxPORT_UNKNOWN;
175 m_usingUniversal = false;
176 m_tkVersionMajor =
177 m_tkVersionMinor = 0;
178 }
179 else
180 {
181 m_port = traits->GetToolkitVersion(&m_tkVersionMajor, &m_tkVersionMinor);
182 m_usingUniversal = traits->IsUsingUniversalWidgets();
23790a2a 183 m_desktopEnv = traits->GetDesktopEnvironment();
449090b5
VZ
184 }
185
186 m_os = wxGetOsVersion(&m_osVersionMajor, &m_osVersionMinor);
23790a2a 187 m_osDesc = wxGetOsDescription();
449090b5
VZ
188 m_endian = wxIsPlatformLittleEndian() ? wxENDIAN_LITTLE : wxENDIAN_BIG;
189 m_arch = wxIsPlatform64Bit() ? wxARCH_64 : wxARCH_32;
03647350 190
23790a2a
FM
191#ifdef __LINUX__
192 m_ldi = wxGetLinuxDistributionInfo();
193#endif
194 // else: leave m_ldi empty
449090b5
VZ
195}
196
197/* static */
198const wxPlatformInfo& wxPlatformInfo::Get()
199{
200 static bool initialized = false;
201 if ( !initialized )
202 {
203 gs_platInfo.InitForCurrentPlatform();
204 initialized = true;
205 }
206
207 return gs_platInfo;
208}
209
23790a2a
FM
210/* static */
211wxString wxPlatformInfo::GetOperatingSystemDirectory()
212{
213 return wxGetOSDirectory();
214}
215
449090b5
VZ
216
217
8bb6b2c0
VZ
218// ----------------------------------------------------------------------------
219// wxPlatformInfo - enum -> string conversions
220// ----------------------------------------------------------------------------
221
222wxString wxPlatformInfo::GetOperatingSystemFamilyName(wxOperatingSystemId os)
223{
9a83f860 224 const wxChar* string = wxT("Unknown");
8bb6b2c0 225 if ( os & wxOS_MAC )
9a83f860 226 string = wxT("Macintosh");
8bb6b2c0 227 else if ( os & wxOS_WINDOWS )
9a83f860 228 string = wxT("Windows");
8bb6b2c0 229 else if ( os & wxOS_UNIX )
9a83f860 230 string = wxT("Unix");
8bb6b2c0 231 else if ( os == wxOS_DOS )
9a83f860 232 string = wxT("DOS");
8bb6b2c0 233 else if ( os == wxOS_OS2 )
9a83f860 234 string = wxT("OS/2");
8bb6b2c0 235
8f493187 236 return string;
8bb6b2c0
VZ
237}
238
239wxString wxPlatformInfo::GetOperatingSystemIdName(wxOperatingSystemId os)
240{
78e9b418 241 const unsigned idx = wxGetIndexFromEnumValue(os);
8bb6b2c0
VZ
242
243 wxCHECK_MSG( idx < WXSIZEOF(wxOperatingSystemIdNames), wxEmptyString,
9a83f860 244 wxT("invalid OS id") );
8bb6b2c0
VZ
245
246 return wxOperatingSystemIdNames[idx];
247}
248
b98bd6af 249wxString wxPlatformInfo::GetPortIdName(wxPortId port, bool usingUniversal)
8bb6b2c0 250{
78e9b418 251 const unsigned idx = wxGetIndexFromEnumValue(port);
8bb6b2c0
VZ
252
253 wxCHECK_MSG( idx < WXSIZEOF(wxPortIdNames), wxEmptyString,
9a83f860 254 wxT("invalid port id") );
8bb6b2c0
VZ
255
256 wxString ret = wxPortIdNames[idx];
257
b98bd6af 258 if ( usingUniversal )
8bb6b2c0
VZ
259 ret += wxT("/wxUniversal");
260
261 return ret;
262}
263
b98bd6af 264wxString wxPlatformInfo::GetPortIdShortName(wxPortId port, bool usingUniversal)
8bb6b2c0 265{
78e9b418 266 const unsigned idx = wxGetIndexFromEnumValue(port);
8bb6b2c0
VZ
267
268 wxCHECK_MSG( idx < WXSIZEOF(wxPortIdNames), wxEmptyString,
9a83f860 269 wxT("invalid port id") );
8bb6b2c0
VZ
270
271 wxString ret = wxPortIdNames[idx];
272 ret = ret.Mid(2).Lower(); // remove 'wx' prefix
273
b98bd6af 274 if ( usingUniversal )
8bb6b2c0
VZ
275 ret += wxT("univ");
276
277 return ret;
278}
279
280wxString wxPlatformInfo::GetArchName(wxArchitecture arch)
281{
282 wxCOMPILE_TIME_ASSERT( WXSIZEOF(wxArchitectureNames) == wxARCH_MAX,
283 wxArchitectureNamesMismatch );
284
285 return wxArchitectureNames[arch];
286}
287
288wxString wxPlatformInfo::GetEndiannessName(wxEndianness end)
289{
290 wxCOMPILE_TIME_ASSERT( WXSIZEOF(wxEndiannessNames) == wxENDIAN_MAX,
291 wxEndiannessNamesMismatch );
292
293 return wxEndiannessNames[end];
294}
295
296
297// ----------------------------------------------------------------------------
298// wxPlatformInfo - string -> enum conversions
299// ----------------------------------------------------------------------------
300
301wxOperatingSystemId wxPlatformInfo::GetOperatingSystemId(const wxString &str)
302{
303 for ( size_t i = 0; i < WXSIZEOF(wxOperatingSystemIdNames); i++ )
304 {
8f493187 305 if ( wxString(wxOperatingSystemIdNames[i]).CmpNoCase(str) == 0 )
8bb6b2c0
VZ
306 return (wxOperatingSystemId)(1 << i);
307 }
308
309 return wxOS_UNKNOWN;
310}
311
312wxPortId wxPlatformInfo::GetPortId(const wxString &str)
313{
314 // recognize both short and long port names
315 for ( size_t i = 0; i < WXSIZEOF(wxPortIdNames); i++ )
316 {
317 wxPortId current = (wxPortId)(1 << i);
318
8f493187
PC
319 if ( wxString(wxPortIdNames[i]).CmpNoCase(str) == 0 ||
320 GetPortIdShortName(current, true).CmpNoCase(str) == 0 ||
b98bd6af 321 GetPortIdShortName(current, false).CmpNoCase(str) == 0 )
8bb6b2c0
VZ
322 return current;
323 }
324
325 return wxPORT_UNKNOWN;
326}
327
328wxArchitecture wxPlatformInfo::GetArch(const wxString &arch)
329{
330 if ( arch.Contains(wxT("32")) )
331 return wxARCH_32;
332
333 if ( arch.Contains(wxT("64")) )
334 return wxARCH_64;
335
336 return wxARCH_INVALID;
337}
338
339wxEndianness wxPlatformInfo::GetEndianness(const wxString& end)
340{
523a54d9
VZ
341 const wxString endl(end.Lower());
342 if ( endl.StartsWith(wxT("little")) )
8bb6b2c0
VZ
343 return wxENDIAN_LITTLE;
344
523a54d9 345 if ( endl.StartsWith(wxT("big")) )
8bb6b2c0
VZ
346 return wxENDIAN_BIG;
347
348 return wxENDIAN_INVALID;
349}
350