1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Various utilities
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 // Note: this is done in utilscmn.cpp now.
14 // #pragma implementation
15 // #pragma implementation "utils.h"
18 // For compilers that support precompilation, includes "wx.h".
19 #include "wx/wxprec.h"
29 #include "wx/cursor.h"
32 #include "wx/msw/private.h"
43 #include <sys/unistd.h>
49 #define stricmp strcasecmp
52 #ifdef __BORLANDC__ // Please someone tell me which version of Borland needs
53 // this (3.1 I believe) and how to test for it.
54 // If this works for Borland 4.0 as well, then no worries.
70 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
76 // In the WIN.INI file
77 static const char WX_SECTION
[] = "wxWindows";
78 static const char eHOSTNAME
[] = "HostName";
79 static const char eUSERID
[] = "UserId";
80 static const char eUSERNAME
[] = "UserName";
82 // For the following functions we SHOULD fill in support
83 // for Windows-NT (which I don't know) as I assume it begin
84 // a POSIX Unix (so claims MS) that it has some special
85 // functions beyond those provided by WinSock
87 // Get full hostname (eg. DoDo.BSn-Germany.crg.de)
88 bool wxGetHostName(char *buf
, int maxSize
)
91 DWORD nSize
= maxSize
;
92 return (::GetComputerName(buf
, &nSize
) != 0);
95 const char *default_host
= "noname";
97 if ((sysname
= getenv("SYSTEM_NAME")) == NULL
) {
98 GetProfileString(WX_SECTION
, eHOSTNAME
, default_host
, buf
, maxSize
- 1);
100 strncpy(buf
, sysname
, maxSize
- 1);
102 return *buf
? TRUE
: FALSE
;
106 // Get user ID e.g. jacs
107 bool wxGetUserId(char *buf
, int maxSize
)
109 #if defined(__WIN32__) && !defined(__win32s__) && 0
110 // Gets the current user's full name according to the MS article PSS ID
112 // Seems to be the same as the login name for me?
113 char *UserName
= new char[256];
114 char *Domain
= new char[256];
115 DWORD maxCharacters
= 255;
116 GetUserName( UserName
, &maxCharacters
);
117 GetComputerName( Domain
, &maxCharacters
);
119 WCHAR wszUserName
[256]; // Unicode user name
120 WCHAR wszDomain
[256];
123 struct _SERVER_INFO_100
*si100
; // Server structure
124 struct _USER_INFO_2
*ui
; // User structure
126 // Convert ASCII user name and domain to Unicode.
128 MultiByteToWideChar( CP_ACP
, 0, UserName
,
129 strlen(UserName
)+1, wszUserName
, sizeof(wszUserName
) );
130 MultiByteToWideChar( CP_ACP
, 0, Domain
,
131 strlen(Domain
)+1, wszDomain
, sizeof(wszDomain
) );
133 // Get the computer name of a DC for the specified domain.
134 // >If you get a link error on this, include netapi32.lib<
136 NetGetDCName( NULL
, wszDomain
, &ComputerName
);
138 // Look up the user on the DC.
140 if(NetUserGetInfo( (LPWSTR
) ComputerName
,
141 (LPWSTR
) &wszUserName
, 2, (LPBYTE
*) &ui
))
143 printf( "Error getting user information.\n" );
147 // Convert the Unicode full name to ASCII.
149 WideCharToMultiByte( CP_ACP
, 0, ui
->usri2_full_name
,
150 -1, buf
, 256, NULL
, NULL
);
154 DWORD nSize = maxSize;
155 return ::GetUserName(buf, &nSize);
159 const char *default_id
= "anonymous";
161 // Can't assume we have NIS (PC-NFS) or some other ID daemon
163 if ( (user
= getenv("USER")) == NULL
&&
164 (user
= getenv("LOGNAME")) == NULL
) {
165 // Use wxWindows configuration data (comming soon)
166 GetProfileString(WX_SECTION
, eUSERID
, default_id
, buf
, maxSize
- 1);
168 strncpy(buf
, user
, maxSize
- 1);
169 return *buf
? TRUE
: FALSE
;
173 // Get user name e.g. Julian Smart
174 bool wxGetUserName(char *buf
, int maxSize
)
176 const char *default_name
= "Unknown User";
177 #if defined(__WIN32__)
179 DWORD nSize = maxSize;
180 In VC++ 4.0, results in unresolved symbol __imp__GetUserNameA
181 if (GetUserName(buf, &nSize))
185 // Could use NIS, MS-Mail or other site specific programs
186 // Use wxWindows configuration data
187 GetProfileString(WX_SECTION
, eUSERNAME
, default_name
, buf
, maxSize
- 1);
188 return *buf
? TRUE
: FALSE
;
191 #if !defined(__WATCOMC__) && !defined(__GNUWIN32__) && USE_PENWINDOWS
192 extern HANDLE g_hPenWin
; // PenWindows Running?
195 // PenWindows Does have a user concept!
196 // Get the current owner of the recognizer
197 GetPrivateProfileString("Current", "User", default_name
, wxBuffer
, maxSize
- 1, "PENWIN.INI");
198 strncpy(buf
, wxBuffer
, maxSize
- 1);
203 // Could use NIS, MS-Mail or other site specific programs
204 // Use wxWindows configuration data
205 GetProfileString(WX_SECTION
, eUSERNAME
, default_name
, buf
, maxSize
- 1);
207 return *buf
? TRUE
: FALSE
;
211 int wxKill(long pid
, int sig
)
217 // Execute a program in an Interactive Shell
220 wxShell(const wxString
& command
)
223 if ((shell
= getenv("COMSPEC")) == NULL
)
224 shell
= "\\COMMAND.COM";
228 sprintf(tmp
, "%s /c %s", shell
, WXSTRINGCAST command
);
232 return (wxExecute((char *)tmp
, FALSE
) != 0);
235 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
236 long wxGetFreeMemory(void)
238 #if defined(__WIN32__) && !defined(__BORLANDC__)
239 MEMORYSTATUS memStatus
;
240 memStatus
.dwLength
= sizeof(MEMORYSTATUS
);
241 GlobalMemoryStatus(&memStatus
);
242 return memStatus
.dwAvailPhys
;
244 return (long)GetFreeSpace(0);
248 // Sleep for nSecs seconds. Attempt a Windows implementation using timers.
249 static bool inTimer
= FALSE
;
250 class wxSleepTimer
: public wxTimer
253 inline void Notify(void)
260 static wxTimer
*wxTheSleepTimer
= NULL
;
262 void wxSleep(int nSecs
)
264 #if 0 // WIN32 hangs app
270 wxTheSleepTimer
= new wxSleepTimer
;
272 wxTheSleepTimer
->Start(nSecs
*1000);
275 if (wxTheApp
->Pending())
276 wxTheApp
->Dispatch();
278 delete wxTheSleepTimer
;
279 wxTheSleepTimer
= NULL
;
283 // Consume all events until no more left
284 void wxFlushEvents(void)
289 // Output a debug mess., in a system dependent fashion.
290 void wxDebugMsg(const char *fmt
...)
293 static char buffer
[512];
295 if (!wxTheApp
->GetWantDebugOutput())
300 wvsprintf(buffer
,fmt
,ap
) ;
301 OutputDebugString((LPCSTR
)buffer
) ;
306 // Non-fatal error: pop up message box and (possibly) continue
307 void wxError(const wxString
& msg
, const wxString
& title
)
309 sprintf(wxBuffer
, "%s\nContinue?", WXSTRINGCAST msg
);
310 if (MessageBox(NULL
, (LPCSTR
)wxBuffer
, (LPCSTR
)WXSTRINGCAST title
,
311 MB_ICONSTOP
| MB_YESNO
) == IDNO
)
315 // Fatal error: pop up message box and abort
316 void wxFatalError(const wxString
& msg
, const wxString
& title
)
318 sprintf(wxBuffer
, "%s: %s", WXSTRINGCAST title
, WXSTRINGCAST msg
);
319 FatalAppExit(0, (LPCSTR
)wxBuffer
);
326 Beep(1000,1000) ; // 1kHz during 1 sec.
332 // Chris Breeze 27/5/98: revised WIN32 code to
333 // detect WindowsNT correctly
334 int wxGetOsVersion(int *majorVsn
, int *minorVsn
)
336 extern char *wxOsVersion
;
337 if (majorVsn
) *majorVsn
= 0;
338 if (minorVsn
) *minorVsn
= 0;
342 memset(&info
, 0, sizeof(OSVERSIONINFO
));
343 info
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
344 if (GetVersionEx(&info
))
346 if (majorVsn
) *majorVsn
= info
.dwMajorVersion
;
347 if (minorVsn
) *minorVsn
= info
.dwMinorVersion
;
348 switch (info
.dwPlatformId
)
350 case VER_PLATFORM_WIN32s
:
353 case VER_PLATFORM_WIN32_WINDOWS
:
356 case VER_PLATFORM_WIN32_NT
:
361 return wxWINDOWS
; // error if we get here, return generic value
365 # ifdef __WINDOWS_386__
368 # if !defined(__WATCOMC__) && !defined(GNUWIN32) && USE_PENWINDOWS
369 extern HANDLE g_hPenWin
;
370 retValue
= g_hPenWin
? wxPENWINDOWS
: wxWINDOWS
;
373 // @@@@ To be completed. I don't have the manual here...
374 if (majorVsn
) *majorVsn
= 3 ;
375 if (minorVsn
) *minorVsn
= 1 ;
380 // Reading and writing resources (eg WIN.INI, .Xdefaults)
382 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, const wxString
& value
, const wxString
& file
)
385 return (WritePrivateProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)value
, (LPCSTR
)WXSTRINGCAST file
) != 0);
387 return (WriteProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)WXSTRINGCAST value
) != 0);
390 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, float value
, const wxString
& file
)
393 sprintf(buf
, "%.4f", value
);
394 return wxWriteResource(section
, entry
, buf
, file
);
397 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, long value
, const wxString
& file
)
400 sprintf(buf
, "%ld", value
);
401 return wxWriteResource(section
, entry
, buf
, file
);
404 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, int value
, const wxString
& file
)
407 sprintf(buf
, "%d", value
);
408 return wxWriteResource(section
, entry
, buf
, file
);
411 bool wxGetResource(const wxString
& section
, const wxString
& entry
, char **value
, const wxString
& file
)
413 static const char defunkt
[] = "$$default";
416 int n
= GetPrivateProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)defunkt
,
417 (LPSTR
)wxBuffer
, 1000, (LPCSTR
)WXSTRINGCAST file
);
418 if (n
== 0 || strcmp(wxBuffer
, defunkt
) == 0)
423 int n
= GetProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)defunkt
,
424 (LPSTR
)wxBuffer
, 1000);
425 if (n
== 0 || strcmp(wxBuffer
, defunkt
) == 0)
428 if (*value
) delete[] (*value
);
429 *value
= copystring(wxBuffer
);
433 bool wxGetResource(const wxString
& section
, const wxString
& entry
, float *value
, const wxString
& file
)
436 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
439 *value
= (float)strtod(s
, NULL
);
446 bool wxGetResource(const wxString
& section
, const wxString
& entry
, long *value
, const wxString
& file
)
449 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
452 *value
= strtol(s
, NULL
, 10);
459 bool wxGetResource(const wxString
& section
, const wxString
& entry
, int *value
, const wxString
& file
)
462 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
465 *value
= (int)strtol(s
, NULL
, 10);
471 #endif // USE_RESOURCES
474 static HCURSOR wxBusyCursorOld
= 0;
475 static int wxBusyCursorCount
= 0;
477 // Set the cursor to the busy cursor for all windows
478 void wxBeginBusyCursor(wxCursor
*cursor
)
480 wxBusyCursorCount
++;
481 if (wxBusyCursorCount
== 1)
483 wxBusyCursorOld
= ::SetCursor((HCURSOR
) cursor
->GetHCURSOR());
487 (void)::SetCursor((HCURSOR
) cursor
->GetHCURSOR());
491 // Restore cursor to normal
492 void wxEndBusyCursor(void)
494 if (wxBusyCursorCount
== 0)
497 wxBusyCursorCount
--;
498 if (wxBusyCursorCount
== 0)
500 ::SetCursor(wxBusyCursorOld
);
505 // TRUE if we're between the above two calls
508 return (wxBusyCursorCount
> 0);
512 char *wxGetUserHome (const wxString
& user
)
515 wxString
user1(user
);
519 if (wxGetUserId(tmp
, sizeof(tmp
)/sizeof(char))) {
520 // Guests belong in the temp dir
521 if (stricmp(tmp
, "annonymous") == 0) {
522 if ((home
= getenv("TMP")) != NULL
||
523 (home
= getenv("TMPDIR")) != NULL
||
524 (home
= getenv("TEMP")) != NULL
)
525 return *home
? home
: "\\";
527 if (stricmp(tmp
, WXSTRINGCAST user1
) == 0)
532 if ((home
= getenv("HOME")) != NULL
)
534 strcpy(wxBuffer
, home
);
535 Unix2DosFilename(wxBuffer
);
538 return NULL
; // No home known!
541 // Check whether this window wants to process messages, e.g. Stop button
542 // in long calculations.
543 bool wxCheckForInterrupt(wxWindow
*wnd
)
547 HWND win
= (HWND
) wnd
->GetHWND();
548 while(PeekMessage(&msg
,win
,0,0,PM_REMOVE
)){
549 TranslateMessage(&msg
);
550 DispatchMessage(&msg
);
552 return TRUE
;//*** temporary?
555 wxError("wnd==NULL !!!");
556 return FALSE
;//*** temporary?
560 // MSW only: get user-defined resource from the .res file.
561 // Returns NULL or newly-allocated memory, so use delete[] to clean up.
564 char *wxLoadUserResource(const wxString
& resourceName
, const wxString
& resourceType
)
568 HRSRC hResource
= ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
571 HRSRC hResource
= ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
573 HRSRC hResource
= ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
579 HGLOBAL hData
= ::LoadResource(wxGetInstance(), hResource
);
582 char *theText
= (char *)LockResource(hData
);
586 s
= copystring(theText
);
590 UnlockResource(hData
);
594 // GlobalFree(hData);
600 void wxGetMousePosition( int* x
, int* y
)
603 GetCursorPos( & pt
);
608 // Return TRUE if we have a colour display
609 bool wxColourDisplay(void)
611 HDC dc
= ::GetDC(NULL
);
613 int noCols
= GetDeviceCaps(dc
, NUMCOLORS
);
614 if ((noCols
== -1) || (noCols
> 2))
622 // Returns depth of screen
623 int wxDisplayDepth(void)
625 HDC dc
= ::GetDC(NULL
);
626 int planes
= GetDeviceCaps(dc
, PLANES
);
627 int bitsPerPixel
= GetDeviceCaps(dc
, BITSPIXEL
);
628 int depth
= planes
*bitsPerPixel
;
633 // Get size of display
634 void wxDisplaySize(int *width
, int *height
)
636 HDC dc
= ::GetDC(NULL
);
637 *width
= GetDeviceCaps(dc
, HORZRES
); *height
= GetDeviceCaps(dc
, VERTRES
);