+char *strdup(const char *s)
+{
+ return strcpy( (char*) malloc( strlen( s ) + 1 ) , s ) ;
+}
+
+int isascii( int c )
+{
+ return ( c >= 0 && c < 128 ) ;
+}
+#endif // __MWERKS__
+
+// ----------------------------------------------------------------------------
+// wxSafeYield and supporting functions
+// ----------------------------------------------------------------------------
+
+void wxEnableTopLevelWindows(bool enable)
+{
+ wxWindowList::Node *node;
+ for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
+ node->GetData()->Enable(enable);
+}
+
+wxWindowDisabler::wxWindowDisabler(wxWindow *winToSkip)
+{
+ // remember the top level windows which were already disabled, so that we
+ // don't reenable them later
+ m_winDisabled = NULL;
+
+ wxWindowList::Node *node;
+ for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
+ {
+ wxWindow *winTop = node->GetData();
+ if ( winTop == winToSkip )
+ continue;
+
+ if ( winTop->IsEnabled() )
+ {
+ winTop->Disable();
+ }
+ else
+ {
+ if ( !m_winDisabled )
+ {
+ m_winDisabled = new wxWindowList;
+ }
+
+ m_winDisabled->Append(winTop);
+ }
+ }
+}
+
+wxWindowDisabler::~wxWindowDisabler()
+{
+ wxWindowList::Node *node;
+ for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
+ {
+ wxWindow *winTop = node->GetData();
+ if ( !m_winDisabled || !m_winDisabled->Find(winTop) )
+ {
+ winTop->Enable();
+ }
+ //else: had been already disabled, don't reenable
+ }
+
+ delete m_winDisabled;
+}
+
+// Yield to other apps/messages and disable user input to all windows except
+// the given one
+bool wxSafeYield(wxWindow *win)
+{
+ wxWindowDisabler wd(win);
+
+ bool rc = wxYield();
+
+ return rc;
+}
+
+// ----------------------------------------------------------------------------
+// misc functions
+// ----------------------------------------------------------------------------
+
+// Don't synthesize KeyUp events holding down a key and producing KeyDown
+// events with autorepeat. On by default and always on in wxMSW. wxGTK version
+// in utilsgtk.cpp.
+#ifndef __WXGTK__
+bool wxSetDetectableAutoRepeat( bool WXUNUSED(flag) )
+{
+ return TRUE; // detectable auto-repeat is the only mode MSW supports
+}
+#endif // !wxGTK
+
+#endif // wxUSE_GUI
+
+const wxChar *wxGetInstallPrefix()
+{
+ wxString prefix;
+
+ if ( wxGetEnv(wxT("WX_PREFIX"), &prefix) )
+ return prefix.c_str();
+
+#ifdef wxINSTALL_PREFIX
+ return wxT(wxINSTALL_PREFIX);
+#else
+ return wxT("");
+#endif
+}
+
+wxString wxGetDataDir()
+{
+ wxString format = wxGetInstallPrefix();
+ format << wxFILE_SEP_PATH
+ << wxT("share") << wxFILE_SEP_PATH
+ << wxT("wx") << wxFILE_SEP_PATH
+ << wxT("%i.%i");
+ wxString dir;
+ dir.Printf(format.c_str(), wxMAJOR_VERSION, wxMINOR_VERSION);
+ return dir;
+}
+
+
+// ----------------------------------------------------------------------------
+// network and user id functions
+// ----------------------------------------------------------------------------
+
+// Get Full RFC822 style email address
+bool wxGetEmailAddress(wxChar *address, int maxSize)
+{
+ wxString email = wxGetEmailAddress();
+ if ( !email )
+ return FALSE;
+
+ wxStrncpy(address, email, maxSize - 1);
+ address[maxSize - 1] = wxT('\0');
+
+ return TRUE;
+}
+
+wxString wxGetEmailAddress()
+{
+ wxString email;
+
+ wxString host = wxGetFullHostName();
+ if ( !!host )
+ {
+ wxString user = wxGetUserId();
+ if ( !!user )
+ {
+ email << user << wxT('@') << host;
+ }
+ }
+
+ return email;
+}
+
+wxString wxGetUserId()
+{
+ static const int maxLoginLen = 256; // FIXME arbitrary number
+
+ wxString buf;
+ bool ok = wxGetUserId(buf.GetWriteBuf(maxLoginLen), maxLoginLen);
+ buf.UngetWriteBuf();
+
+ if ( !ok )
+ buf.Empty();
+
+ return buf;
+}
+
+wxString wxGetUserName()