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